classdef simulinkModelCleaner < handle
% Written by Stuart Bowman of the MITRE Corporation.
% www.mitre.org
% sbowman@mitre.org
% To Use:
%
% Instantiate this class:
% smc = simulinkModelCleaner('myModel')
%
% Have fun cleaning your simulink models!
properties (SetAccess=private,GetAccess=public)
slModelName = '';
end;
methods
function this = simulinkModelCleaner(modelName)
% Class Constructor
% Error check licenses
if ~is_simulink_loaded,
try
load_simulink;
catch me
error('Simulink isn''t available. This class cannot work without Simulink.')
end;
end;
% Error check inputs
if nargin == 0,
% error
error('You must supply the name of a simulink model file as an arguement to the contructor!')
elseif nargin == 1,
% Get model name
if ischar(modelName)
% Set the model name
if exist(modelName,'file') == 4,
% This is a model file
this.slModelName = modelName;
else
error('Simulink model %s not found! Argument must specify the name of a Simulink model that is on your path.',modelName)
end;
else
error('Improper argument type: must be of type char, but found type %s.', class(modelName))
end;
else
error('Too many arguments passed to the class constructor')
end;
end;
function replaceBlocks(this,findThisBlock,replaceWithThisBlock)
% Generic replacement method. Provide a valid string block to
% find (e.g. 'Scope') and a valid block to replace with. All
% instances found will be replaced.
this.doBlockReplacement(findThisBlock,replaceWithThisBlock);
end;
function bool = doCleanUp(this)
% Finds all Scope & Display blocks and replaces them with
% Terminator blocks.
% Make sure the system is loaded
load_system(this.slModelName);
try
% Search for all scopes and replace with a Terminator
this.doBlockReplacement('Scope','Terminator');
this.doBlockReplacement('Display','Terminator');
% Save the new configuration
save_system(this.slModelName);
% Return
bool = true;
catch me
bool = false;
warning('The block replacement did not complete! %s',me.message);
end; % try
end; % function
function bool = undoCleanUp(this)
% Finds all Terminators whose UserData parameter contains old
% information and replaces them with the built-in block that
% they used to be.
% Make sure the system is loaded
load_system(this.slModelName);
% Look for Terminator blocks
[allTerminators,cnt] = this.findBlockByType('Terminator');
if ~cnt
% No Terminators to replace. exit.
bool = true;
return;
end;
% Loop over the list of Terminators
try
for iNm = 1:length(allTerminators)
was = get_param(cell2mat(allTerminators(iNm)),'UserData'); % get UserData
if isstruct(was),
if isfield(was,'BlockName') && isfield(was,'BlockType'),
currentName = get_param(cell2mat(allTerminators(iNm)),'Name');
oldName = was.BlockName;
oldType = was.BlockType;
replace_block(this.slModelName,'Name',currentName,['built-in/' oldType],'noprompt'); % replace the block with what it originally was
set_param(cell2mat(allTerminators(iNm)),'Name',oldName); % revert to the old name
else
break
end;
end; % if isstruct...
end; % for iNm...
% Save the new configuration
save_system(this.slModelName);
% Return
bool = true;
catch me
% Error
bool = false;
warning('The undo action did not complete! %s',me.message);
end;
end; % function
function [blkList,count] = findBlockByType(this,blkType)
% Get a cell array of blocks that are of type blkType
% Make sure the system is loaded
load_system(this.slModelName);
% Find
blkList = find_system(this.slModelName,'FollowLinks','on','FindAll','off','CaseSensitive','off','LookUnderMasks','all','BlockType',blkType);
if nargout ==2, count = length(blkList); end;
end; % function
end;
methods (Access=private)
function doBlockReplacement(this,findThisBlock,replaceWithBuiltInBlock)
% Loop over the incoming blckList and replace every instance
% with the block provided by replaceWithBuiltInBlock.
[blckList,cnt] = this.findBlockByType(findThisBlock);
if cnt == 0,
return;
end;
for iNm = 1:cnt
oldName = get_param(cell2mat(blckList(iNm)),'Name'); % get the current block name
replace_block(this.slModelName,'Name',oldName,['built-in/' replaceWithBuiltInBlock],'noprompt'); % replace the block with this built-in block
was.BlockType = findThisBlock;
was.BlockName = oldName;
set_param(cell2mat(blckList(iNm)),'UserData',was); % set the new name and save the old information
end;
end;
end;
end