gusucode.com > target工具箱matlab源码程序 > target/foundation/utils/resource_config/RTWConfigurationCB.m
function varargout = RTWConfigurationCB(action,varargin) %RTWConfigurationCB Callback for the RTWConfiguration GUI % % varargout = RTWConfigurationCB( action, varargin ) % % -- Arguments --- % % action - 'preloadfcn' | % 'get_target' | % 'get_target_subsystem' | % 'get_target_from_system' | % 'reset_config_target_block' | % 'rtw_target_initfcn' | % 'openfcn' | % 'copyfcn' | % 'NameChangeFcn' | % 'presavefcn' | % 'deletefcn' | % 'closefcn' % % varargin - { block } % Copyright 2001-2011 The MathWorks, Inc. % % switch action case 'preloadfcn' % Required to load classes - no further action required case 'get_target' % -- Get the RTWConfiguration.Target object closest above % in the Simulink hierarchy --- block = varargin{1}; % get the closest target object - throws missing target error target = i_getTarget(block); varargout = { target }; case 'get_target_subsystem' % similar to get_target, but returns the % parent system of the closest target block block = varargin{1}; % throws missing target error [~, parent] = i_getTarget(block); varargout = { parent }; case 'get_target_from_system' % call i_getTargetFindSystem (unlimited search depth) % to find a Resource Config block within the given system. % This case should be called from within the hook file % it will handle the case when there are no RT driver blocks % in the system. We must enforce that a Resource Configuration % block exists in the system for RT builds % searches for the target and returns it subsystem = varargin{1}; % unlimited depth - allow default errors to be thrown target = i_getTargetFindSystem(subsystem); % done varargout = { target }; case 'reset_config_target_block' reset_config_target_block(varargin{1}); case 'rtw_target_initfcn' % Find the configuration block that MUST live inside this % subsystem. If it is not there throw an error. % Find the configuration block that MUST live inside this % subsystem. If it is not there throw an error. block = varargin{1}; config_block = find_system(block,... 'followlinks','on', ... 'lookundermasks','on', ... 'SearchDepth',1,... 'tag','RTW CONFIGURATION BLOCK'); if isempty(config_block) i_clean_parent(block); else % We wish the RC block to generate code ahead of all other % blocks in the model. By giving it the highest priority this % is achieved. set_param(config_block{1},'priority','-100000'); % Update the config object. This may not be necessary % and could incur a speed penalty i_update_config(config_block{1}); target = get_param(config_block{1},'userdata'); if ~strcmpi(target.getName, 'CCP') error(message('TargetSupportPackage:target:DeprecateMPC555Processor')); end % Place the target in the root of the model % in the TargetProperties field root = bdroot(block); % record initial dirty status of the model initialDirty = get_param(root, 'Dirty'); set_param(root,'TargetProperties',target); % TargetProperties is always derived from the Resource Config % block - maintain the initial dirty status of the model set_param(root, 'Dirty', initialDirty); % throw errors properly in a Simulink error message if ~isempty(target.errors) % see @RTWConfiguration/@Target/manageUI.m: % % error_text.setText(sprintf('ERROR : %s\n',errors{:})); TargetCommon.ProductInfo.error('resourceConfiguration', 'ResourceConfigurationError', sprintf('- %s\n\n',target.errors{:})); end end case 'openfcn' block = varargin{1}; if i_isInLibrary(block) % in library - do not allow block to open warndlg(['Please drag the resource configuration block into a model or model subsystem. ' ... 'The resource configuration block is not active in the ''' bdroot ''' drivers library'],... 'Resource Configuration : Warning'); else i_update_config(block); target = get_param(block,'userdata'); target.manageUI('create'); end; case 'copyfcn' % -- The block has been copied --- block = varargin{1}; if ~i_isInLibrary(block) block = varargin{1}; i_copy_config_target_block(block); i_update_config(block); else reset_config_target_block(block) end case 'NameChangeFcn' % -- The block has been moved --- block = varargin{1}; if ~i_isInLibrary(block) i_name_change_config_target_block(block); i_update_config(block); end case 'presavefcn' %-- Called when the model closes --- block = varargin{1}; if ~i_isInLibrary(block) i_presave_config_target_block(block); end i_call_tgt_presavefcn(block); case 'deletefcn' block = varargin{1}; % avoid error messages caused by the delete fcn % being called when libraries close if ~i_isInLibrary(block) i_delete_config_target_block(block); end; case 'closefcn' block = varargin{1}; target = get_param(block,'userdata'); if ~isempty(target) target.closeUI; end otherwise TargetCommon.ProductInfo.error('common', 'UnsupportedAction', action); end %% I_CALL_TGT_PRESAVEFCN calls a target specific PreSaveFcn function i_call_tgt_presavefcn(block) target = get_param(block,'userdata'); targetName = target.getName; callbackFcn = lower([targetName '_presavefcn']); if exist(callbackFcn, 'file') % May be a p-file feval(callbackFcn,bdroot(block)); end %% error message for missing target block function i_missingTargetError(block) TargetCommon.ProductInfo.error('resourceConfiguration', 'ResourceConfigurationBlockMissing', block, block); % returns true if block is in a Simulink library % returns false if block is not in a Simulink library function inlibrary = i_isInLibrary(block) if (strcmp(get_param(bdroot(block),'BlockDiagramType'),'library')) inlibrary = true; else inlibrary = false; end % implements the find_system for the target block, % given a possible parent subsystem % called by i_getTarget and 'get_target_from_subsystem' case % % varargin{1} - optional extra argument is find_system search depth % if this is omitted the search depth is unrestricted. % function target = i_getTargetFindSystem(parent, varargin) % check for depth argument if (nargin==2) depth = varargin{1}; % apply search depth limit config_block = find_system(parent,... 'FollowLinks','on',... 'lookundermasks','on', ... 'SearchDepth',depth,... 'tag','RTW CONFIGURATION BLOCK'); else % no limit on search depth config_block = find_system(parent,... 'FollowLinks','on',... 'lookundermasks','on', ... 'tag','RTW CONFIGURATION BLOCK'); end; % if ~isempty(config_block) if length(config_block) > 1 % error - multiple config blocks were found DAStudio.error('TargetSupportPackage:target:ResourceConfigurationMultipleBlocks'); end config_block = config_block{1}; target = get_param(config_block,'userdata'); if ~isa(target,'RTWConfiguration.Target') DAStudio.error('TargetSupportPackage:target:ResourceConfigurationCorrupted', ... config_block); end % validate the block associated with the target object % it should be referring to the current model (the one associated % with parent) configBlockModel = strtok(target.block, '/'); currentModel = strtok(parent, '/'); if ~strcmp(configBlockModel, ... currentModel) DAStudio.error('TargetSupportPackage:target:ResourceConfigurationIncorrectBlock', ... configBlockModel, ... currentModel); end else % error - no config blocks were found DAStudio.error('TargetSupportPackage:target:ResourceConfigurationNoConfigBlock'); end %% search for target block in the model function [target, parent] = i_getTarget(block) parent = get_param(block,'parent'); target = []; while ~isempty(parent) % apply search depth == 1 try target = i_getTargetFindSystem(parent,1); catch e switch(e.identifier) case 'TargetSupportPackage:target:ResourceConfigurationNoConfigBlock' % ok - move to next level otherwise rethrow(e); end end if ~isempty(target) %% found a target %% return it return; end; parent = get_param(parent,'parent'); end % did not find a target - throw error i_missingTargetError(block); function i_presave_config_target_block(block) % -- Close the model --- % % I would like to raise the config GUI here but it seems % that any java ui raised at this point cause MATLAB to % freeze. I guess it is a thread problem ???? % target = get_param(block,'userdata'); if ~isempty(target) target.validate; % Remove the inactiveList target.inactiveList.disconnect; end function i_delete_config_target_block(block) % NOTE: this callback is called on model close % so we can't clean the parent here - instead, this is done % in the rtw_target_initfcn function if the config block has been % removed. % % -- Close the GUI if it is open feval(mfilename, 'closefcn', block); function i_copy_config_target_block(block) % -- handle copying the configuration block from the library to the model -- % -- Arguments --- % % block - The block which is being copied target = get_param(block,'userdata'); if ~isempty(target) % -- Perform a deep copy of the target --- fName = tempname; save(fName,'target'); fileData = load(fName); target = fileData.target; target.block = block; set_param(block,'userdata',target); end i_init_parent_subsystem(block); function i_name_change_config_target_block(block) % -- handle copying the configuration block from the library to the model -- % -- Arguments --- % % block - The block which is being copied root = bdroot(block); switch get_param(root,'BlockDiagramType') case 'library' % -- Do nothing -- otherwise % -- Initialize the new parent subsystem --- i_init_parent_subsystem(block); end function i_clean_parent(parent) % -- Clean up the callbacks from an old parent subsystem --- if ~isempty(parent) try % clean the TargetProperties we may have added model = bdroot(parent); set_param(model,'TargetProperties',''); oldinit = get_param(parent,'initfcn'); set_param(parent,'initfcn',i_extract_old_block_fcn(oldinit)); is_block_diagram = strcmp(get_param(parent,'type'),'block_diagram'); if ~is_block_diagram % -- Remove the icon display command and preserve all others --- oldmask = get_param(parent,'MaskDisplay'); idx = findstr(oldmask, [ c_create_config_mask_display sprintf('\n')]); if ~isempty(idx) oldmask = oldmask((idx + length(c_create_config_mask_display)) : end); set_param(parent,'MaskDisplay',i_extract_old_block_fcn(oldmask)); end end % Remove model PreLoadFcn config_block = find_system(model,... 'FollowLinks','on',... 'lookundermasks','on', ... 'tag','RTW CONFIGURATION BLOCK'); if (length(config_block)==1) % last config block is about to be deleted % so remove preLoadFcn from Model preLoadFcn = get_param(model, 'PreLoadFcn'); while i_is_preloadfcn_already_set(preLoadFcn) preLoadFcn(1:length(c_create_config_model_preloadfcn)) = ''; end set_param(model, 'PreLoadFcn', preLoadFcn); end catch e %#ok<NASGU> % -- The parent may no longer exist during an ' undo - create subsystem ' end end function i_init_parent_subsystem(block) % -- Initialize the parent subsystem of a config block --- parent = get_param(block,'parent'); initfcn = get_param(parent, 'initfcn'); if ~i_is_whitespace(initfcn) % | ~i_is_whitespace(maskdisplay) % -- There is already code is the parent callbacks and % it may not be our own --- if ~i_is_initfcn_installed(initfcn) % The code in the callback is definitely not our own % so we notify the user that modification will take place hilite_system(block); blockname = strrep(block,sprintf('\n'),' '); parentname = strrep(parent,sprintf('\n'),' '); str = strvcat('The block ', ... ' ', blockname , ' ', ... [ ' that you just copied needs to modify the ' ... '"initfcn" and the "MaskDisplay" of it''s parent subsystem ' ] , ... ' ', parentname , ' ' , ' Code will be pre-pended without affecting the ', ... 'current functionality of the mask.'); %#ok<VCAT> msgbox(str, ... 'Copying Configuration Block'); end end i_init_parent_subsystem_callbacks(parent); % Set model PreLoadFcn i_init_model(parent); set_param(block,'oldParentName',parent); set_param(block,'oldBlockName',block); function ret = i_is_whitespace(str) %-- Returns 1 if the string is empty or whitespace --- % Parameters % str - The callback string to test % type - 'initfcn' | 'maskdisplay' % if isempty(str) ret = 1; return end if all(str == ' ' | str == sprintf('\n') | str == sprintf('\t')) ret = 1; return end ret = 0; return function ret = i_is_initfcn_installed(str) %-- Returns 1 if the callback str is empty or whitespace or % the callback is already installed ---------------------- % % Parameters % str - The callback string to test % if ~isempty(findstr(str, c_create_mask_start)) ret = 1; return end ret = 0; function i_init_parent_subsystem_callbacks(parent) % -- Initialize the parent subsystem of the configuration block --- % If the parent is a library link then the initialization functions % will have already been set and it should not be necessary to run % any of the below. In fact it can cause Simulink to error out if % a set_param is done on a library block old_init_fcn = get_param(parent,'initfcn'); % -- Only make the changes if they have not been done before --- if strcmp(get_param(parent,'type'),'block_diagram') if isempty(findstr(old_init_fcn, c_create_mask_start)) % There is no previous callback new_init_fcn = i_create_block_fcn(c_create_config_toplevel_initfcn, old_init_fcn); set_param(parent,'initfcn',new_init_fcn); end else if strcmp(get_param(parent,'linkstatus'),'resolved'); return end old_mask_display = get_param(parent, 'maskdisplay'); if isempty(findstr(old_init_fcn, c_create_mask_start)) new_init_fcn = i_create_block_fcn(c_create_config_subsys_initfcn, old_init_fcn); set_param(parent,'initfcn',new_init_fcn); end if isempty(findstr(old_mask_display, c_create_config_mask_display)) new_mask_display = ... [c_create_config_mask_display sprintf('\n') old_mask_display]; set_param(parent,'MaskDisplay',new_mask_display ); set_param(parent,'MaskIconOpaque','off'); end end function init_fcn = i_extract_old_block_fcn(init_fcn) % -- Remove the section of code from the initfcn that the config block requires --- idx = findstr(init_fcn, c_create_mask_end); if ~isempty(idx) % Remove the introduced code and the return character init_fcn = init_fcn((idx + length(c_create_mask_end) + 1) : end); else % Do not modify the initfcn end function init_fcn = i_create_block_fcn(rtw_code,old_code) % -- Merge the old and new init functions --- n = sprintf('\n'); init_fcn = ... [c_create_mask_start n rtw_code n c_create_mask_end n old_code ]; function i_init_model(parent) % -- Initialize the block diagram root of the configuration block --- model = bdroot(parent); preLoadFcn = get_param(model, 'PreLoadFcn'); if i_is_preloadfcn_already_set(preLoadFcn) % No action else set_param(model, 'PreLoadFcn', [c_create_config_model_preloadfcn, preLoadFcn]); end function i_update_config(block) % --- Update the configuration information. --- % Get the current configuration object. target = get_param(block,'userdata'); if isempty(target) target = RTWConfiguration.Target('new',block); set_param(block,'userdata',target); end target.block = block; target.processModel; function ret = i_is_preloadfcn_already_set(preLoadFcn) % -- Return 1 if the preloadfcn already starts with correctPreLoadFcn --- correctPreLoadFcn = c_create_config_model_preloadfcn; if strncmp(preLoadFcn, correctPreLoadFcn, length(correctPreLoadFcn)) ret = 1; else ret = 0; end function reset_config_target_block(block) % Initialize the configuration block that lives under % the 'RTW Target' subsystem set_param(block,'userdatapersistent','on'); target = RTWConfiguration.Target('new',block); set_param(block,'userdata',target); set_param(block,'openfcn','RTWConfigurationCB(''openfcn'',gcb);'); set_param(block,'copyfcn','RTWConfigurationCB(''copyfcn'',gcb);'); set_param(block,'deletefcn','RTWConfigurationCB(''deletefcn'',gcb);'); set_param(block,'presavefcn','RTWConfigurationCB(''presavefcn'',gcb);'); set_param(block,'NameChangeFcn','RTWConfigurationCB(''NameChangeFcn'',gcb);'); set_param(block,'undodeletefcn','RTWConfigurationCB(''NameChangeFcn'',gcb);'); set_param(block,'closefcn',''); % Closing the UI when the model closes fails set_param(block,'parentclosefcn',''); set_param(block,'destroyfcn',''); set_param(block,'postsavefcn',''); set_param(block,'loadfcn',''); function cb = c_create_config_mask_display % -- Create the MASK display for the subsystem containing the CONFIG block --- cb = 'image(imread(''target_affordance_icon.jpg''),''bottom-right'')'; function cb = c_create_config_subsys_initfcn % -- RTW_CONFIGURATION intfcn macro --- cb = 'RTWConfigurationCB(''rtw_target_initfcn'',gcb);'; function cb = c_create_config_toplevel_initfcn % -- RTW_CONFIGURATION InitFcn macro --- cb = 'RTWConfigurationCB(''rtw_target_initfcn'',gcs);'; function cb = c_create_config_model_preloadfcn % -- RTW_CONFIGURATION model PreLoadFcn macro --- cb = 'RTWConfigurationCB(''preloadfcn'', bdroot);'; function cb = c_create_mask_start % -- Start pattern to a code insertion --- cb = '% START RTW CONFIGURATION CODE %'; function cb = c_create_mask_end % -- END pattern to a code insertion --- cb = '% END RTW CONFIGURATION CODE %';