Skip to content
set_code.m 9.27 KiB
Newer Older
        %% set_code
        %    set the script of an embedded matlab block to an inputed
        %    string of eml code, create the inputs and outputs for the
        %    subsystem to connect to the eml block
        % inputs:
        %   block_handle:handle - handle block to update
        %   code:string - eml code
        %   function_name:string - name of the function
        % outputs:
        %   eml_handle:handle - handle of eml block, as this function may
        %   create a new block.
        function eml_handle = set_code(block_handle,code,function_name)
         % unlink the block from the library, this is necessary if
                % we
                % want to change the subsystem of the block.
                set_param(block_handle,'LinkStatus','none')


                % determine if the name already exists in the model

                if (~strcmp(get(block_handle,'Name'),function_name))
                    try
                    set_param(block_handle,'Name',function_name);
                    catch exception
                        msgbox(exception.message);
                    end
                end

                % embedded matlab code block store code in stateflow states so
                % we need to get the root hande
                S = sfroot;

                % get the path of the code block
                code_block = sprintf('%s/code',getfullname(block_handle));
                % determine if code block already exists
                code_blocks = find_system(getfullname(block_handle),'LookUnderMasks','all','BlockType','SubSystem','Name','code');

                % if the code block does not already exists we need to create a
                % new one
                if (isempty(code_blocks))
                    code_blocks = add_block('simulink/User-Defined Functions/Embedded MATLAB Function',code_block);
                end

                eml_handle = code_blocks
                % find the state of the code block and update it to the new
                % code
                myState = S.find('-isa','Stateflow.EMChart', '-and', 'Path', code_block); % find which one we want to edit

                if (~isempty(myState))
                    myState.Script =  sprintf('%s',code);
                end

                % delete any lines that are unconnected and one end or both
                % code from
                % http://www.mathworks.com/matlabcentral/fileexchange/12352-delete-unconnected-lines
                % Copyright (c) 2009, Per-Anders Ekström
                    % delete all the lines
                    lines = find_system( getfullname(block_handle), ...
                    'LookUnderMasks', 'all', ...
                    'FindAll', 'on', ...
                    'Type', 'line' ) ;


                    % for each line, call delete_recursive if handle still exist
                    for i=1:length( lines )
                        if ishandle( lines( i ) )
                            TableBlock.delete_recursive( lines( i ) )
                        end
                    end
                % end copyright

                % we need to determine which of the inports and outports we
                % need to create and delete. Whenever we delete a port anything
                % connected with this port is unconnected, other blocks, scopes
                % etc. We would like to avoid this if possible because it can
                % be quite annoying.

                % First loop through all the inport blocks, if there does not
                % exists an inport in the code block of the same name then
                % delete the inport block
                inports = find_system(getfullname(block_handle),'LookUnderMasks','all','SearchDepth',1,'FindAll','On','BlockType','Inport');
                for i=1:size(inports,1)
                    found = 0;
                    in_handles=find_system(code_block, 'SearchDepth',1,'FindAll','On','FollowLinks','On','LookUnderMasks','All','BlockType','Inport');

                    for j=1:size(in_handles,1)
                        if strcmp(get_param(inports(i),'Name'),get_param(in_handles(j),'Name'))
                            found = 1;
                        end
                    end

                    if (~found)
                        % old inport no longer exists
                        delete_block(inports(i));
                    end
                end

                % now we loop through all the inports in the code block if
                % there is an inport block of the same name then connect them,
                % else create a new inport block and connect them
                in_handles=find_system(code_block, 'SearchDepth',1,'FindAll','On','FollowLinks','On','LookUnderMasks','All','BlockType','Inport');
                for j = 1:size(in_handles,1)
                    found = 0;
                    inports = find_system(getfullname(block_handle),'LookUnderMasks','all','SearchDepth',1,'BlockType','Inport');
                    for i = 1:size(inports,1)
                        if strcmp(get_param(inports(i),'Name'),get_param(in_handles(j),'Name'))
                            found = 1;

                            % draw the line
                            new_port_num = sprintf('%s/1',get_param(in_handles(j),'Name'));
                            dest_port = sprintf('%s/%d','code',j);
                            try
                            add_line(getfullname(block_handle),new_port_num,dest_port);
                            end
                        end
                    end
                    if (~found)
                       new_port = sprintf('%s/%s',getfullname(block_handle),get_param(in_handles(j),'Name'));
                       add_block('simulink/Sources/In1',new_port)
                       new_port_num = sprintf('%s/1',get_param(in_handles(j),'Name'));
                    dest_port = sprintf('%s/%d','code',j);
                    % sometimes line will be created automatically
                    try       
                    add_line(getfullname(block_handle),new_port_num,dest_port);
                    end
                    end


                end


                % Next we do the same thing with the outputs
                outports = find_system(getfullname(block_handle),'LookUnderMasks','all','SearchDepth',1,'FindAll','On','BlockType','Outport');
                for i=1:size(outports,1)
                    found = 0;
                    out_handles=find_system(code_block, 'SearchDepth',1,'FindAll','On','FollowLinks','On','LookUnderMasks','All','BlockType','Outport');

                    for j=1:size(out_handles,1)
                        if strcmp(get_param(outports(i),'Name'),get_param(out_handles(j),'Name'))
                            found = 1;
                        end
                    end

                    if (~found)
                        % old inport no longer exists
                        delete_block(outports(i));
                    end
                end

                out_handles=find_system(code_block, 'SearchDepth',1,'FindAll','On','FollowLinks','On','LookUnderMasks','All','BlockType','Outport');
                for j = 1:size(out_handles,1)
                    found = 0;
                    outports = find_system(getfullname(block_handle),'LookUnderMasks','all','SearchDepth',1,'BlockType','Outport');
                    for i = 1:size(outports,1)
                        if strcmp(get_param(outports(i),'Name'),get_param(out_handles(j),'Name'))
                            found = 1;

                            % draw the line
                            new_port_num = sprintf('%s/1',get_param(out_handles(j),'Name'));
                            dest_port = sprintf('%s/%d','code',j);
                            try
                            add_line(getfullname(block_handle),dest_port,new_port_num);
                            end
                        end
                    end
                    if (~found)
                       new_port = sprintf('%s/%s',getfullname(block_handle),get_param(out_handles(j),'Name'));
                       add_block('simulink/Sinks/Out1',new_port)
                       new_port_num = sprintf('%s/1',get_param(out_handles(j),'Name'));
                    dest_port = sprintf('%s/%d','code',j);
                    try       
                    add_line(getfullname(block_handle),dest_port,new_port_num);
                    end
                    end
                end

                % delete any lines that are unconnected and one end or both
                % again sometimes extra lines are created
                % code from
                % http://www.mathworks.com/matlabcentral/fileexchange/12352-delete-unconnected-lines
                % Copyright (c) 2009, Per-Anders Ekström
                    % delete all the lines 
                    lines = find_system( getfullname(block_handle), ...
                        'LookUnderMasks', 'all', ...
                        'FindAll', 'on', ...
                        'Type', 'line' ) ;

                    % for each line, call delete_recursive if handle still exist
                    for i=1:length( lines )
                        if ishandle( lines( i ) )
                            TableBlock.delete_recursive( lines( i ) )
                        end
                    end   
                % end copyright
                
        end