├── whichtorun.m ├── .gitignore ├── SimAssist.fig ├── @saAction ├── undo_add_line.m ├── redo_delete_line.m ├── undo_add_block.m ├── redo_set_param.m ├── undo_set_param.m ├── redo_add_line.m ├── redo_add_block.m ├── undo_delete_line.m ├── private │ ├── gen_unique_name.m │ └── unlock_library.m ├── redo_replace_block.m ├── delete_line.m ├── undo_replace_block.m ├── Undo.m ├── redo_set_param_stateflow.m ├── undo_set_param_stateflow.m ├── Redo.m ├── add_block.m ├── CheckLink.m ├── set_param_stateflow.m ├── add_line.m ├── set_param.m ├── replace_block.m └── saAction.m ├── @saLine ├── GetMajorProperty.m ├── SetProperty.m ├── DictRename.m ├── PropagateDownstreamString.m ├── ReplaceStr.m ├── PropagateUpstreamString.m └── saLine.m ├── @saRecorder ├── Merge.m ├── plus.m ├── PushItem.m ├── StateflowSetParam.m ├── ReplaceBlock.m ├── DeleteLine.m ├── private │ ├── timerfcn.m │ ├── timerdisplay.m │ └── sa_get_bind_block.m ├── AddLine_PortToPort.m ├── SetParam.m ├── MoveBlock.m ├── Undo.m ├── Redo.m ├── AddLine_NoDstLineToPort.m ├── AddLine_PortToNoSrcLine.m ├── SetParamHighlight.m ├── saRecorder.m ├── AddLine_NoDstLineToNoSrcLine.m ├── AddLine_LineToNoSrcLine.m ├── AddLine_LineToPort.m ├── AddBlock.m ├── AutoLine.m └── AddLine.m ├── docs ├── SimAssist_CodeHelp.pdf ├── SimAssist工具介绍 - 20160124.pdf └── SimAssist Guideline 20160203.pdf ├── Dialogs └── saDlg_AddNewBlock.fig ├── @saBlockGroup ├── plus.m ├── IsMember.m ├── minus.m ├── Select.m ├── BGArrayUnion.m ├── set_param.m ├── private │ └── set_pos_align.m ├── Move.m ├── getBGPorts.m ├── SplitToIntactBGs.m ├── AlignPortsOutside.m ├── AlignPortsInside.m ├── VerticalAlign.m ├── saBlockGroup.m └── StraightenLinesInside.m ├── @saCmdParser ├── ParseSingleValue.m ├── ParseInteger.m ├── saCmdParser.m ├── ParseMultiValues.m ├── ParseNumericAndString.m ├── ParseStringAndInteger.m ├── ParseValuesAndInteger.m └── ParseSeqExpr.m ├── _BlockRegistration ├── regblock_line.m ├── regblock_annotation.m ├── regblock_abs.m ├── regblock_sigconv.m ├── regblock_gain.m ├── regblock_terminator.m ├── regblock_ratetransition.m ├── regblock_entityterminator.m ├── regblock_sqrt.m ├── regblock_ground.m ├── regblock_signalspecification.m ├── regblock_display.m ├── regblock_datatypeconversion.m ├── regblock_unitdelay.m ├── regblock_rounding.m ├── regblock_sl_canpack.m ├── regblock_sl_canunpack.m ├── regblock_enableport.m ├── regblock_math.m ├── regblock_trigonometry.m ├── regprotoblock_LGPT_datastore.m ├── regblock_toworkspace.m ├── regblock_inport.m ├── regblock_outport.m ├── regblock_mux.m ├── regblock_datastorewrite.m ├── regblock_argout.m ├── regblock_fromworkspace.m ├── regblock_argin.m ├── regprotoblock_siltest.m ├── regblock_merge.m ├── regblock_datastoreread.m ├── regblock_prelookup.m ├── regblock_minmax.m ├── regblock_deadzone.m ├── regblock_goto.m ├── regblock_datastorememory.m ├── regblock_from.m ├── regblock_saturate.m ├── regblock_product.m ├── regblock_interpnd.m ├── regblock_switch.m ├── regblock_motohawk_probe.m ├── regblock_sum.m ├── regblock_relationaloperator.m ├── regblock_constant.m ├── regblock_motohawk_calibration.m ├── regblock_busassignment.m ├── regblock_logic.m ├── regblock_triggerport.m ├── regblock_memory.m └── regblock_demux.m ├── saLoadLib.m ├── @saConsole ├── AddsaBlock.m ├── AddMacro.m ├── Dispatch.m ├── UIGetPromptList.m ├── DispatchH.m ├── AddCurrentBlockToMap.m ├── BuildMacros.m ├── saConsole.m ├── ImportBlockTypesExcel.m ├── LibScan.m └── MapTo.m ├── @saMacro ├── MatchPattern.m ├── Parse.m ├── Run.m └── saMacro.m ├── @saBlock └── GetSourcePath.m ├── @saProtoBlock ├── GetBlockSize.m ├── private │ ├── analyze_datatype.m │ └── override_option.m ├── Check.m ├── Refine.m ├── GetBroBlocks.m ├── Annotate.m ├── Minus.m ├── Clean.m ├── CreateRoutineMacro.m ├── GetMajorProperty.m ├── Plus.m ├── RollProperty.m ├── Adapt.m ├── Grounds.m ├── SetProperty.m ├── PropagateDownstreamString.m ├── DictRename.m ├── TemporaryCurrentBlockBased.m ├── Align.m ├── PropagateUpstreamString.m ├── SetDataType.m ├── AddBlockArray.m ├── Color.m ├── ReplaceStr.m ├── AutoSize.m ├── Terminates.m └── CreateBroBlock.m ├── saRemoveBranchLine.m ├── +Routines ├── simple.m ├── num_only.m ├── majorprop_value.m ├── dynamicinport.m ├── majorprop_str_num.m └── multiprop.m ├── saGetStringDialogParameter.m ├── _MacroRegistration ├── regmacro_query_author.m ├── regmacro_script_line.m ├── regmacro_script_unname.m ├── regmacro_script_dislink.m ├── regmacro_script_breaklink.m ├── regmacro_script_strrep.m ├── regmacro_script_motohawk_to_simulink.m ├── regmacro_script_simulink_to_motohawk.m ├── regmacro_opsym_ampersand.m ├── regmacro_script_datatype.m ├── regmacro_opsym_percent.m ├── regmacro_opsym_plus_minus.m ├── regmacro_script_annotation.m ├── regmacro_script_colorit.m ├── regmacro_script_majorprop.m ├── regmacro_script_sfstrrep.m ├── regmacro_script_clean.m ├── regmacro_routine_datastore.m ├── regmacro_script_autoline.m ├── regmacro_script_change_size.m ├── regmacro_temp_dsmlib.m ├── regmacro_script_line2fromgoto.m ├── regmacro_script_datacompare.m ├── regmacro_script_queryexplanation.m └── regmacro_script_ovrd.m ├── saDictRenameString.m ├── saOverrideOption.m ├── saGetMousePosition.m ├── saObject.m ├── saStandardDataTypeStr.m ├── saIsStateflow.m ├── GetAdjBlks.m ├── saRectifyPos.m ├── saLayoutAroundBlock.m ├── README.md ├── saGetBlockClosure.m ├── license.txt ├── saAnnotation.m ├── saGetBlockMapKey.m ├── releasepack.m ├── saGetLineDominantBlock.m └── info.xml /whichtorun.m: -------------------------------------------------------------------------------- 1 | SimAssist; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | releases/ 2 | *.asv 3 | /demos/ 4 | help/ 5 | -------------------------------------------------------------------------------- /SimAssist.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xingxing993/SimAssist/HEAD/SimAssist.fig -------------------------------------------------------------------------------- /@saAction/undo_add_line.m: -------------------------------------------------------------------------------- 1 | function undo_add_line(obj) 2 | delete_line(obj.Handle); 3 | end -------------------------------------------------------------------------------- /@saAction/redo_delete_line.m: -------------------------------------------------------------------------------- 1 | function redo_delete_line(obj) 2 | obj.delete_line(obj.Handle); 3 | end -------------------------------------------------------------------------------- /@saLine/GetMajorProperty.m: -------------------------------------------------------------------------------- 1 | function majprop = GetMajorProperty(obj, lnhdl) 2 | majprop = 'Name'; 3 | end -------------------------------------------------------------------------------- /@saAction/undo_add_block.m: -------------------------------------------------------------------------------- 1 | function undo_add_block(obj) 2 | try 3 | delete_block(obj.Handle); 4 | end 5 | end -------------------------------------------------------------------------------- /@saRecorder/Merge.m: -------------------------------------------------------------------------------- 1 | function Merge(obj,obj2) 2 | obj.ActionList = [obj2.ActionList; obj.ActionList]; 3 | end -------------------------------------------------------------------------------- /@saRecorder/plus.m: -------------------------------------------------------------------------------- 1 | function plus(obj,obj2) 2 | obj.ActionList = [obj2.ActionList; obj.ActionList]; 3 | end -------------------------------------------------------------------------------- /docs/SimAssist_CodeHelp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xingxing993/SimAssist/HEAD/docs/SimAssist_CodeHelp.pdf -------------------------------------------------------------------------------- /Dialogs/saDlg_AddNewBlock.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xingxing993/SimAssist/HEAD/Dialogs/saDlg_AddNewBlock.fig -------------------------------------------------------------------------------- /@saBlockGroup/plus.m: -------------------------------------------------------------------------------- 1 | function obj=plus(obj1,obj2) 2 | obj=saBlockGroup(union(obj1.BlockHandles,obj2.BlockHandles)); 3 | end -------------------------------------------------------------------------------- /@saRecorder/PushItem.m: -------------------------------------------------------------------------------- 1 | function PushItem(obj,simaction_item) 2 | obj.ActionList = [simaction_item; obj.ActionList]; 3 | end -------------------------------------------------------------------------------- /docs/SimAssist工具介绍 - 20160124.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xingxing993/SimAssist/HEAD/docs/SimAssist工具介绍 - 20160124.pdf -------------------------------------------------------------------------------- /@saBlockGroup/IsMember.m: -------------------------------------------------------------------------------- 1 | function bIn=IsMember(obj,block) 2 | bIn=ismember(get_param(block,'Handle'),obj.BlockHandles); 3 | end -------------------------------------------------------------------------------- /@saBlockGroup/minus.m: -------------------------------------------------------------------------------- 1 | function obj=minus(obj1,obj2) 2 | obj=saBlockGroup(setdiff(obj1.BlockHandles,obj2.BlockHandles)); 3 | end -------------------------------------------------------------------------------- /docs/SimAssist Guideline 20160203.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xingxing993/SimAssist/HEAD/docs/SimAssist Guideline 20160203.pdf -------------------------------------------------------------------------------- /@saAction/redo_set_param.m: -------------------------------------------------------------------------------- 1 | function redo_set_param(obj) 2 | try 3 | set_param(obj.Handle,obj.Property,obj.NewValue); 4 | end 5 | end -------------------------------------------------------------------------------- /@saAction/undo_set_param.m: -------------------------------------------------------------------------------- 1 | function undo_set_param(obj) 2 | try 3 | set_param(obj.Handle,obj.Property,obj.OldValue); 4 | end 5 | end -------------------------------------------------------------------------------- /@saBlockGroup/Select.m: -------------------------------------------------------------------------------- 1 | function Select(obj) 2 | for i=1:obj.BlockCount 3 | set_param(obj.BlockHandles(i),'Selected','on'); 4 | end 5 | end -------------------------------------------------------------------------------- /@saCmdParser/ParseSingleValue.m: -------------------------------------------------------------------------------- 1 | function [result, bclean] = ParseSingleValue(obj) 2 | 3 | result = obj.OptionStr; 4 | bclean = true; 5 | end -------------------------------------------------------------------------------- /@saLine/SetProperty.m: -------------------------------------------------------------------------------- 1 | function actrec = SetProperty(obj, lnhdl, propval, ~) 2 | actrec = saRecorder; 3 | actrec.SetParam(lnhdl, 'Name', propval); 4 | end -------------------------------------------------------------------------------- /@saRecorder/StateflowSetParam.m: -------------------------------------------------------------------------------- 1 | function StateflowSetParam(obj,varargin) 2 | sa = saAction('set_param_stateflow', varargin{:}); 3 | obj.PushItem(sa); 4 | end -------------------------------------------------------------------------------- /@saAction/redo_add_line.m: -------------------------------------------------------------------------------- 1 | function redo_add_line(obj) 2 | obj.Handle = add_line(obj.Data.System,obj.Data.Points); 3 | set_param(obj.Handle, obj.Property{:}); 4 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_line.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_line 2 | %REGBLK_LINE 3 | % Registration of line type in SimAssist 4 | 5 | sabt = saLine; 6 | 7 | 8 | end -------------------------------------------------------------------------------- /@saAction/redo_add_block.m: -------------------------------------------------------------------------------- 1 | function redo_add_block(obj) 2 | obj.Handle = add_block(obj.Data.Source, obj.Data.Destination, 'MakeNameUnique', 'on', obj.Property{:}); 3 | end -------------------------------------------------------------------------------- /@saRecorder/ReplaceBlock.m: -------------------------------------------------------------------------------- 1 | function block = ReplaceBlock(obj,varargin) 2 | sa = saAction('replace_block',varargin{1:2}); 3 | obj.PushItem(sa); 4 | block = sa.Handle; 5 | end -------------------------------------------------------------------------------- /@saBlockGroup/BGArrayUnion.m: -------------------------------------------------------------------------------- 1 | function obj=BGArrayUnion(objs) 2 | if numel(objs)>=1 3 | obj=objs(1); 4 | for i=2:numel(objs) 5 | obj=obj+objs(i); 6 | end 7 | end 8 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_annotation.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_annotation 2 | %REGBLK_LINE 3 | % Registration of line type in SimAssist 4 | 5 | sabt = saAnnotation; 6 | 7 | 8 | end -------------------------------------------------------------------------------- /saLoadLib.m: -------------------------------------------------------------------------------- 1 | function saLoadLib(libname) 2 | if ~bdIsLoaded(libname) 3 | % bkcs = gcs; 4 | load_system(libname); 5 | % load_system(bkcs); % restore current system 6 | end 7 | end -------------------------------------------------------------------------------- /@saConsole/AddsaBlock.m: -------------------------------------------------------------------------------- 1 | function AddsaBlock(obj, sabt) 2 | sabt.Console = obj; 3 | if ~any(strcmp(obj.BlockMap(:,1),sabt.MapKey)) 4 | obj.BlockMap = [obj.BlockMap; {sabt.MapKey, sabt}]; 5 | end 6 | end -------------------------------------------------------------------------------- /@saRecorder/DeleteLine.m: -------------------------------------------------------------------------------- 1 | function DeleteLine(obj,lnhdls) 2 | lnhdls = saRemoveBranchLine(lnhdls); 3 | for i=1:numel(lnhdls) 4 | sa = saAction('delete_line', lnhdls(i)); 5 | obj.PushItem(sa); 6 | end 7 | end -------------------------------------------------------------------------------- /@saBlockGroup/set_param.m: -------------------------------------------------------------------------------- 1 | function set_param(objs,varargin) 2 | for kk=1:numel(objs) 3 | obj=objs(kk); 4 | for i=1:obj.BlockCount 5 | set_param(obj.BlockHandles(i),varargin{:}); 6 | end 7 | end 8 | end -------------------------------------------------------------------------------- /@saConsole/AddMacro.m: -------------------------------------------------------------------------------- 1 | function AddMacro(obj, sam) 2 | sam.Console = obj; 3 | macros_tmp = [obj.Macros; sam]; 4 | [tmp, iprio] = sort([macros_tmp.Priority]); 5 | macros_tmp = macros_tmp(iprio); 6 | obj.Macros = macros_tmp; 7 | end -------------------------------------------------------------------------------- /@saLine/DictRename.m: -------------------------------------------------------------------------------- 1 | function actrec = DictRename(obj, blkhdl) 2 | % 3 | actrec = saRecorder; 4 | nam=get_param(blkhdl,'Name'); 5 | newnam=saDictRenameString(nam,obj.Dictionary); 6 | actrec.SetParam(blkhdl, 'Name', newnam); 7 | end -------------------------------------------------------------------------------- /@saRecorder/private/timerfcn.m: -------------------------------------------------------------------------------- 1 | function timerfcn(src,eventdata,hblk,oldcolor,oldannotation) 2 | set_param(hblk,'ForegroundColor',oldcolor); 3 | set_param(hblk,'AttributesFormatString',oldannotation); 4 | stop(src); 5 | delete(src); 6 | end -------------------------------------------------------------------------------- /@saAction/undo_delete_line.m: -------------------------------------------------------------------------------- 1 | function undo_delete_line(obj) 2 | for i=1:numel(obj.Data.DstPort) 3 | try 4 | obj.Handle = add_line(obj.Data.System,obj.Data.SrcPort,obj.Data.DstPort(i),'autorouting','on'); 5 | end 6 | end 7 | end -------------------------------------------------------------------------------- /@saBlockGroup/private/set_pos_align.m: -------------------------------------------------------------------------------- 1 | function actrec = set_pos_align(blkhdl, newpos) 2 | %SET_POS_ALIGN set position of block, and also trace downwards to see if 3 | %any branch downstream exists and align the trunk line node 4 | 5 | 6 | end 7 | 8 | -------------------------------------------------------------------------------- /@saMacro/MatchPattern.m: -------------------------------------------------------------------------------- 1 | function objs = MatchPattern(objarr, cmdstr) 2 | % Find the matching macro object(s) from objarr 3 | 4 | ptns = {objarr.Pattern}'; 5 | idxm = cellfun(@(c) ~isempty(regexp(cmdstr, c)), ptns); 6 | objs = objarr(idxm); 7 | 8 | end -------------------------------------------------------------------------------- /@saRecorder/AddLine_PortToPort.m: -------------------------------------------------------------------------------- 1 | function AddLine_PortToPort(obj, srchdl, dsthdl) 2 | % srchdl : outport handle 3 | % dsthdl : inport handle 4 | parsys = get_param(get_param(srchdl, 'Parent'),'Parent'); 5 | obj.AddLine(parsys, srchdl, dsthdl); 6 | end -------------------------------------------------------------------------------- /@saAction/private/gen_unique_name.m: -------------------------------------------------------------------------------- 1 | function validname = gen_unique_name(parsys,rawname) 2 | blks=find_system(parsys,'FollowLinks','on','LookUnderMasks','on','RegExp','on','SearchDepth',1); 3 | validname = genvarname(rawname,get_param(blks,'Name')); 4 | end -------------------------------------------------------------------------------- /@saBlock/GetSourcePath.m: -------------------------------------------------------------------------------- 1 | function path = GetSourcePath(obj) 2 | if isempty(obj.SourcePath) 3 | path = ''; 4 | elseif isempty(strfind(obj.SourcePath, '/')) 5 | path = ['built-in/',obj.SourcePath]; 6 | else 7 | path = obj.SourcePath; 8 | end 9 | end -------------------------------------------------------------------------------- /@saProtoBlock/GetBlockSize.m: -------------------------------------------------------------------------------- 1 | function blksize = GetBlockSize(obj) 2 | if isempty(obj.BlockSize) 3 | tmppos = get_param(obj.GetSourcePath, 'Position'); 4 | blksize = tmppos(3:4) - tmppos(1:2); 5 | else 6 | blksize = obj.BlockSize; 7 | end 8 | end -------------------------------------------------------------------------------- /@saProtoBlock/private/analyze_datatype.m: -------------------------------------------------------------------------------- 1 | function dt = analyze_datatype(str) 2 | dt = ''; 3 | if ismember(str, {'true','false','TRUE','FALSE'}) 4 | dt = 'boolean'; 5 | elseif ~isempty(regexp(str, '\.\d+', 'once')) 6 | % dt = 'single'; 7 | end 8 | end -------------------------------------------------------------------------------- /@saAction/private/unlock_library.m: -------------------------------------------------------------------------------- 1 | function unlock_library(objhdl) 2 | bd=bdroot(objhdl); 3 | if strcmp(get_param(bd,'Lock'),'on') 4 | set_param(bd,'Lock','off'); 5 | warndlg(['Caution! Modifying a locked library link.',char(10),'Library unlocked.']); 6 | end 7 | end -------------------------------------------------------------------------------- /@saAction/redo_replace_block.m: -------------------------------------------------------------------------------- 1 | function redo_replace_block(obj) 2 | blktyp = get_param(obj.Data.Path, 'BlockType'); 3 | blk = replace_block(obj.Data.Path, blktyp,obj.Data.NewBlockSrc, 'noprompt'); 4 | if iscell(blk) 5 | blk=blk{1}; 6 | end 7 | obj.Handle = get_param(blk, 'Handle'); 8 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_abs.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_abs 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Abs'); 6 | 7 | sabt.RoutinePattern = '^abs'; 8 | sabt.RoutineMethod = 'num_only'; 9 | 10 | 11 | sabt.BlockSize = [30, 30]; 12 | 13 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_sigconv.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_sigconv 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('SignalConversion'); 6 | sabt.RoutineMethod = 'num_only'; 7 | sabt.RoutinePattern = '^(sigconv|signalconv)'; 8 | sabt.BlockSize = [30, 30]; 9 | end -------------------------------------------------------------------------------- /@saRecorder/SetParam.m: -------------------------------------------------------------------------------- 1 | function SetParam(obj,varargin) 2 | objhdl = varargin{1}; 3 | if isstr(objhdl) 4 | objhdl = get_param(objhdl,'Handle'); 5 | end 6 | for i=2:2:numel(varargin) 7 | sa = saAction('set_param',objhdl, varargin{i}, varargin{i+1}); 8 | obj.PushItem(sa); 9 | end 10 | end -------------------------------------------------------------------------------- /saRemoveBranchLine.m: -------------------------------------------------------------------------------- 1 | function objs = saRemoveBranchLine(objs) 2 | lns = objs(strcmp(get_param(objs,'Type'),'line')); 3 | lns_rmv = []; 4 | for i=1:numel(lns) 5 | if ismember(get_param(lns(i),'LineParent'), objs) 6 | lns_rmv = [lns_rmv, lns(i)]; 7 | end 8 | end 9 | objs = setdiff(objs, lns_rmv); 10 | end -------------------------------------------------------------------------------- /@saConsole/Dispatch.m: -------------------------------------------------------------------------------- 1 | function varargout = Dispatch(obj, recvr, event, varargin) 2 | 3 | btobj = obj.MapTo(recvr); 4 | 5 | if nargin>2 && (ismethod(btobj, event) || isprop(btobj, event)) % if given function to call 6 | [varargout{1:nargout}] = btobj.(event)(varargin{:}); 7 | else 8 | varargout{1} = btobj; 9 | end 10 | end -------------------------------------------------------------------------------- /@saCmdParser/ParseInteger.m: -------------------------------------------------------------------------------- 1 | function [result, bclean] = ParseInteger(obj) 2 | result = regexp(obj.OptionStr, '\d+', 'match', 'once'); 3 | if isempty(result) 4 | result = []; 5 | else 6 | result = str2double(result); 7 | end 8 | reststr = regexprep(obj.OptionStr, '\d+', '', 'once'); 9 | bclean = isempty(strtrim(reststr)); 10 | end -------------------------------------------------------------------------------- /@saProtoBlock/Check.m: -------------------------------------------------------------------------------- 1 | function tf = Check(obj, blkhdl) 2 | tf = false; 3 | if ~isa(obj.ProtoCheckMethod, 'function_handle') 4 | return; 5 | end 6 | if isstr(blkhdl) 7 | try 8 | blkhdl = get_param(blkhdl, 'Handle'); 9 | catch 10 | return; 11 | end 12 | end 13 | tf = obj.ProtoCheckMethod(blkhdl); 14 | end -------------------------------------------------------------------------------- /@saRecorder/MoveBlock.m: -------------------------------------------------------------------------------- 1 | function MoveBlock(obj, blkhdl, vec, moveline) 2 | if nargin<4 3 | moveline = false; 4 | end 5 | % move block 6 | pos = get_param(blkhdl, 'Position'); 7 | newpos = [pos + [vec, vec]]; 8 | obj.SetParam(blkhdl, 'Position', newpos); 9 | dx = vec(1);dy = vec(2); 10 | 11 | if moveline 12 | 13 | end 14 | 15 | end -------------------------------------------------------------------------------- /+Routines/simple.m: -------------------------------------------------------------------------------- 1 | function [actrec, success] = simple(btobj, cmdstr, pattern, varargin) 2 | cmdpsr = saCmdParser(cmdstr, pattern); 3 | bclean = isempty(cmdpsr.OptionStr); 4 | if bclean 5 | actrec = btobj.GenericContextAdd(varargin{:}); 6 | success = true; 7 | else 8 | [actrec, success] = deal(saRecorder, false); 9 | end 10 | end -------------------------------------------------------------------------------- /+Routines/num_only.m: -------------------------------------------------------------------------------- 1 | function [actrec, success] = num_only(btobj, cmdstr, pattern, varargin) 2 | cmdpsr = saCmdParser(cmdstr, pattern); 3 | [num, bclean] = cmdpsr.ParseInteger; 4 | if bclean 5 | actrec = btobj.GenericContextAdd(num, varargin{:}); 6 | success = true; 7 | else 8 | [actrec, success] = deal(saRecorder, false); 9 | end 10 | end -------------------------------------------------------------------------------- /@saAction/delete_line.m: -------------------------------------------------------------------------------- 1 | function delete_line(obj,varargin) 2 | obj.Handle = varargin{1}; 3 | obj.Data.System = get_param(varargin{1}, 'Parent'); 4 | obj.Data.Points = get_param(varargin{1}, 'Points'); 5 | obj.Data.SrcPort = get_param(varargin{1}, 'SrcPortHandle'); 6 | obj.Data.DstPort = get_param(varargin{1}, 'DstPortHandle'); 7 | delete_line(obj.Handle); 8 | end -------------------------------------------------------------------------------- /@saRecorder/Undo.m: -------------------------------------------------------------------------------- 1 | function Undo(obj) 2 | for i=1:numel(obj.ActionList) 3 | echo = obj.ActionList(i).Undo; 4 | if ~isempty(echo) % update object handle 5 | bidx = [obj.ActionList.Handle]==echo.OldHandle; 6 | if any(bidx) 7 | [obj.ActionList(bidx).Handle]=deal(echo.NewHandle); 8 | end 9 | end 10 | end 11 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_gain.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_gain 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Gain'); 6 | 7 | sabt.RoutineMethod = 'majorprop_value'; 8 | sabt.RoutinePattern = '^gain'; 9 | 10 | sabt.MajorProperty = 'Gain'; 11 | 12 | sabt.BlockSize = [30, 30]; 13 | sabt.StrReplaceMethod = 1; 14 | end -------------------------------------------------------------------------------- /@saRecorder/Redo.m: -------------------------------------------------------------------------------- 1 | function Redo(obj) 2 | for i=numel(obj.ActionList):-1:1 3 | echo = obj.ActionList(i).Redo; 4 | if ~isempty(echo) % update object handle 5 | bidx = [obj.ActionList.Handle]==echo.OldHandle; 6 | if any(bidx) 7 | [obj.ActionList(bidx).Handle]=deal(echo.NewHandle); 8 | end 9 | end 10 | end 11 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_terminator.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_terminator 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Terminator'); 6 | sabt.RoutineMethod = 'num_only'; 7 | sabt.RoutinePattern = '^(terminator|term)'; 8 | 9 | sabt.PropagateUpstreamStringMethod = 'Name'; 10 | 11 | sabt.ConnectPort = [1, 0]; 12 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_ratetransition.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_ratetransition 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('RateTransition'); 6 | sabt.RoutineMethod = 'num_only'; 7 | sabt.RoutinePattern = '^(ratetrans|rate|rt)'; 8 | 9 | 10 | sabt.MajorProperty = ''; 11 | 12 | sabt.BlockSize = [30, 30]; 13 | 14 | end -------------------------------------------------------------------------------- /@saBlockGroup/Move.m: -------------------------------------------------------------------------------- 1 | function actrec=Move(obj,vect) 2 | actrec=saRecorder; 3 | if any((obj.Boundary(1:2)+vect)<0) 4 | return; 5 | end 6 | for i=1:obj.BlockCount 7 | blkvect=[vect,vect]; %L T R B 8 | oldpos=get_param(obj.BlockHandles(i),'Position'); 9 | newpos=oldpos+blkvect; 10 | actrec.SetParam(obj.BlockHandles(i),'Position',newpos); 11 | end 12 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_entityterminator.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_entityterminator 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('EntityTerminator'); 6 | sabt.RoutineMethod = 'num_only'; 7 | sabt.RoutinePattern = '^(entityterm)'; 8 | 9 | sabt.PropagateUpstreamStringMethod = 'Name'; 10 | 11 | sabt.ConnectPort = [1, 0]; 12 | end -------------------------------------------------------------------------------- /saGetStringDialogParameter.m: -------------------------------------------------------------------------------- 1 | function proplist = saGetStringDialogParameter(blkhdl) 2 | dlgparas = get_param(blkhdl, 'DialogParameters'); 3 | if isstruct(dlgparas) 4 | idx = structfun(@(fld)strcmp(fld.Type, 'string'), dlgparas); 5 | paranames = fieldnames(dlgparas); 6 | proplist = [paranames(idx); cellstr('Name')]; 7 | else 8 | proplist={}; 9 | end 10 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_sqrt.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_sqrt 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | if verLessThan('matlab', '7.14') 5 | sabt = []; 6 | return; 7 | end 8 | 9 | sabt = saBlock('Sqrt'); 10 | 11 | sabt.RoutinePattern = '^sqrt'; 12 | sabt.RoutineMethod = 'num_only'; 13 | 14 | 15 | sabt.BlockSize = [30, 30]; 16 | 17 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_ground.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_ground 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Ground'); 6 | 7 | sabt.RoutineMethod = 'num_only'; 8 | sabt.RoutinePattern = '^(gnd|ground)'; 9 | 10 | sabt.PropagateDownstreamStringMethod = 'Name'; 11 | 12 | sabt.BlockSize = [20, 20]; 13 | sabt.ConnectPort = [0, 1]; 14 | end -------------------------------------------------------------------------------- /@saMacro/Parse.m: -------------------------------------------------------------------------------- 1 | function varargout = Parse(obj, cmdstr, console) 2 | if isempty(obj.ParseMethod) 3 | varargout{1} = cmdstr; 4 | else 5 | if isa(obj.ParseMethod, 'function_handle') 6 | ni = nargin(obj.ParseMethod); 7 | args = {cmdstr, console}; 8 | [varargout{1:nargout}] = obj.ParseMethod(args{1:ni}); 9 | else 10 | varargout{1} = cmdstr; 11 | end 12 | end 13 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_query_author.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_query_author 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('query_author'); 6 | sam.Pattern = '^[Aa]uthor\?'; 7 | sam.Callback = @query_author; 8 | 9 | end 10 | 11 | function [actrec, success] =query_author(cmdstr, console) 12 | actrec=saRecorder;success = false; 13 | 14 | 15 | success = true; 16 | end -------------------------------------------------------------------------------- /saDictRenameString.m: -------------------------------------------------------------------------------- 1 | function namout=saDictRenameString(namin,dict) 2 | bestsplit=parse_string(namin,dict(:,1)); 3 | namout=''; 4 | for kk=1:numel(bestsplit.String) 5 | matchidx=strcmp(bestsplit.String{kk},dict(:,1)); 6 | if any(matchidx) 7 | matchterm=dict(matchidx,:); 8 | namout=[namout,matchterm{1,2}]; 9 | else 10 | namout=[namout,bestsplit.String{kk}]; 11 | end 12 | end 13 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_signalspecification.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_signalspecification 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('SignalSpecification'); 6 | 7 | sabt.RoutineMethod = 'num_only'; 8 | sabt.RoutinePattern = '^sigspec|signalspec'; 9 | 10 | sabt.DefaultDataType = 'Inherit: auto'; 11 | sabt.DataTypeMethod = -1; 12 | 13 | sabt.BlockSize = [70, 18]; 14 | 15 | end -------------------------------------------------------------------------------- /@saAction/undo_replace_block.m: -------------------------------------------------------------------------------- 1 | function undo_replace_block(obj) 2 | blktyp = get_param(obj.Data.Path, 'BlockType'); 3 | blk = replace_block(obj.Data.Path, blktyp,obj.Data.OldBlockSrc, 'noprompt'); 4 | if iscell(blk) 5 | blk=blk{1}; 6 | end 7 | obj.Handle = get_param(blk, 'Handle'); 8 | for i=1:size(obj.Property, 2) 9 | try 10 | set_param(obj.Data.Path, obj.Property{1,i}, obj.Property{2,i}); 11 | end 12 | end 13 | end -------------------------------------------------------------------------------- /@saLine/PropagateDownstreamString.m: -------------------------------------------------------------------------------- 1 | function actrec = PropagateDownstreamString(obj, lnhdl) 2 | actrec = saRecorder; 3 | hdstpt=get_param(lnhdl,'DstPortHandle'); 4 | if hdstpt<0 5 | return; 6 | else 7 | for i=1:numel(hdstpt) 8 | name_got=obj.Console.GetDownstreamString(hdstpt(i)); 9 | if ~isempty(name_got) 10 | actrec.SetParam(lnhdl,'Name',name_got); 11 | end 12 | end 13 | end 14 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_display.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_display 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Display'); 6 | 7 | sabt.RoutineMethod = 'num_only'; 8 | sabt.RoutinePattern = '^(display|disp)'; 9 | 10 | 11 | sabt.ConnectPort = [1, 0]; 12 | sabt.BlockSize = [90, 28]; 13 | 14 | sabt.LayoutSize.HorizontalMargin = 50; 15 | sabt.LayoutSize.VerticalMargin = 50; 16 | 17 | end -------------------------------------------------------------------------------- /@saLine/ReplaceStr.m: -------------------------------------------------------------------------------- 1 | function actrec = ReplaceStr(obj, lnhdl, oldstr, newstr) 2 | % 3 | actrec = saRecorder; 4 | nam = get_param(lnhdl, 'Name'); 5 | if isempty(nam) 6 | return; 7 | end 8 | if strcmp(oldstr, '^') % add prefix 9 | newnam = [newstr, nam]; 10 | elseif strcmp(oldstr, '$') % append suffix 11 | newnam = [nam, newstr]; 12 | else 13 | newnam = regexprep(nam, oldstr, newstr); 14 | end 15 | actrec.SetParam(lnhdl, 'Name',newnam); 16 | end -------------------------------------------------------------------------------- /@saProtoBlock/Refine.m: -------------------------------------------------------------------------------- 1 | function actrec = Refine(obj, blkhdl) 2 | 3 | actrec = saRecorder; 4 | if isempty(obj.RefineMethod) 5 | return; 6 | end 7 | 8 | refinemethod = obj.RefineMethod; 9 | if isa(refinemethod, 'function_handle') 10 | nn = nargout(refinemethod); 11 | if nn~=0 %if mandatory output exist, must be saRecorder 12 | actrec.Merge(refinemethod(blkhdl)); 13 | else 14 | refinemethod(blkhdl); 15 | end 16 | end 17 | 18 | end -------------------------------------------------------------------------------- /@saConsole/UIGetPromptList.m: -------------------------------------------------------------------------------- 1 | function liststr = UIGetPromptList(obj, partstr) 2 | if isempty(partstr) 3 | liststr_str = obj.PromptBuffer.String; 4 | else 5 | prmpts_strs = obj.PromptBuffer.String; 6 | liststr_str = prmpts_strs(strncmp(prmpts_strs, partstr, numel(partstr))); 7 | end 8 | liststr_fun = cellfun(@(funhdl)funhdl(partstr), obj.PromptBuffer.FunctionHandle, 'UniformOutput', false); % must be function handle 9 | liststr = [liststr_str, liststr_fun]'; 10 | end -------------------------------------------------------------------------------- /@saProtoBlock/GetBroBlocks.m: -------------------------------------------------------------------------------- 1 | function broblks = GetBroBlocks(obj, blkhdl, varargin) 2 | if isempty(obj.GetBroMethod) 3 | broblks = []; 4 | return; 5 | else 6 | if isequal(obj.GetBroMethod, -1) 7 | broblks = []; 8 | elseif isa(obj.GetBroMethod, 'function_handle') 9 | ni = nargin(obj.GetBroMethod); 10 | argsin = {blkhdl, obj}; 11 | broblks = obj.GetBroMethod(argsin{1:ni}); 12 | else 13 | broblks = []; 14 | end 15 | end 16 | end -------------------------------------------------------------------------------- /@saRecorder/AddLine_NoDstLineToPort.m: -------------------------------------------------------------------------------- 1 | function AddLine_NoDstLineToPort(obj, srchdl, dsthdl) 2 | % srchdl : line handle with destination disconnected 3 | % dsthdl : inport 4 | parsys = get_param(srchdl, 'Parent'); 5 | srcpos = get_param(srchdl, 'Points'); srcpos = srcpos(end,:); 6 | dstpos = get_param(dsthdl, 'Position'); 7 | lnpoints = [srcpos;... 8 | round((srcpos(1)+dstpos(1))/2), srcpos(2);... 9 | round((srcpos(1)+dstpos(1))/2), dstpos(2);... 10 | dstpos]; 11 | obj.AddLine(parsys, lnpoints); 12 | end -------------------------------------------------------------------------------- /@saRecorder/AddLine_PortToNoSrcLine.m: -------------------------------------------------------------------------------- 1 | function AddLine_PortToNoSrcLine(obj, srchdl, dsthdl) 2 | % srchdl : outport handle 3 | % dsthdl : line handle with source disconnected 4 | parsys = get_param(dsthdl, 'Parent'); 5 | srcpos = get_param(srchdl, 'Position'); 6 | dstpos = get_param(dsthdl, 'Points'); 7 | dstpos = dstpos(1,:); 8 | lnpoints = [srcpos;... 9 | round((srcpos(1)+dstpos(1))/2), srcpos(2);... 10 | round((srcpos(1)+dstpos(1))/2), dstpos(2);... 11 | dstpos]; 12 | obj.AddLine(parsys, lnpoints); 13 | end -------------------------------------------------------------------------------- /saOverrideOption.m: -------------------------------------------------------------------------------- 1 | function opt = saOverrideOption(varargin) 2 | % varargin shall be cell array of struct that holds different level of 3 | % options, the former arguments takes higher priority 4 | % this function merge and overrides option in priority 5 | opt = struct; 6 | for i=nargin:-1:1 7 | tmpopt = varargin{i}; 8 | if ~isstruct(tmpopt) 9 | continue; 10 | end 11 | flds = fieldnames(tmpopt); 12 | for k=1:numel(flds) 13 | opt.(flds{k}) = tmpopt.(flds{k}); 14 | end 15 | end 16 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_datatypeconversion.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_datatypeconversion 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('DataTypeConversion'); 6 | 7 | % routine definition 8 | sabt.RoutinePattern = '^(dt|datatype)'; 9 | sabt.RoutineMethod = 'num_only'; 10 | 11 | 12 | 13 | sabt.MajorProperty = 'OutDataTypeStr'; 14 | 15 | sabt.DefaultDataType = 'Inherit: Inherit via back propagation'; 16 | sabt.DataTypeMethod = -1; 17 | 18 | sabt.BlockSize = [70, 18]; 19 | 20 | end -------------------------------------------------------------------------------- /@saConsole/DispatchH.m: -------------------------------------------------------------------------------- 1 | function varargout = DispatchH(obj, recvr, event, varargin) 2 | 3 | btobj = obj.MapTo(recvr); 4 | 5 | if nargin>2 && (ismethod(btobj, event) || isprop(btobj, event))% if given function to call 6 | % if given handle as receiver, pass it as the first argument 7 | if isnumeric(recvr) 8 | [varargout{1:nargout}] = btobj.(event)(recvr, varargin{:}); 9 | else 10 | [varargout{1:nargout}] = btobj.(event)(varargin{:}); 11 | end 12 | else 13 | varargout{1} = btobj; 14 | end 15 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_unitdelay.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_unitdelay 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('UnitDelay'); 6 | 7 | sabt.RoutineMethod = 'majorprop_value'; 8 | sabt.RoutinePattern = '^(ud|dly|unitdelay)'; 9 | 10 | 11 | sabt.MajorProperty = 'X0'; 12 | sabt.AnnotationMethod = 'Init: %'; 13 | 14 | sabt.BlockSize = [35, 34]; 15 | sabt.DataTypeMethod = -1; 16 | 17 | sabt.DefaultParameters = {'SampleTime', '-1', 'AttributesFormatString', 'Init: %'}; 18 | 19 | end -------------------------------------------------------------------------------- /@saRecorder/SetParamHighlight.m: -------------------------------------------------------------------------------- 1 | function SetParamHighlight(obj,varargin) 2 | tmrdispparas={}; 3 | tmrdispvals={}; 4 | objhdl = varargin{1}; 5 | for i=2:2:numel(varargin) 6 | sa = saAction('set_param', objhdl,varargin{i}, varargin{i+1}); 7 | if ~isequal(sa.OldValue,sa.NewValue) 8 | tmrdispparas=[tmrdispparas;sa.Property]; 9 | tmrdispvals=[tmrdispvals;sa.NewValue]; 10 | end 11 | obj.PushItem(sa); 12 | end 13 | if ~isempty(tmrdispparas) 14 | timerdisplay(sa.Handle,tmrdispparas,tmrdispvals); 15 | end 16 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_line.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_line 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('script_autoline'); 6 | sam.Pattern = '^line'; 7 | sam.Callback = @script_line; 8 | 9 | end 10 | 11 | function [actrec, success] =script_line(cmdstr, console) 12 | actrec=saRecorder;success = false; 13 | 14 | srchdls = saFindSystem(gcs,'line_sender'); 15 | dsthdls = saFindSystem(gcs, 'line_receiver'); 16 | actrec.MultiAutoLine(srchdls, dsthdls); 17 | 18 | success = true; 19 | end -------------------------------------------------------------------------------- /@saRecorder/saRecorder.m: -------------------------------------------------------------------------------- 1 | classdef saRecorder < handle 2 | properties 3 | ActionList 4 | end 5 | methods 6 | function obj = saRecorder(varargin) 7 | obj.ActionList = []; 8 | end 9 | 10 | function tf = isempty(obj) 11 | tf = isempty(obj.ActionList); 12 | end 13 | 14 | function Dummy(obj) 15 | sa = saAction('Dummy'); 16 | obj.PushItem(sa); 17 | end 18 | end %methods 19 | end %classdef 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /@saAction/Undo.m: -------------------------------------------------------------------------------- 1 | function echo = Undo(obj) 2 | echo = []; 3 | switch obj.Type 4 | case 'set_param' 5 | obj.undo_set_param; 6 | case 'set_param_stateflow' 7 | obj.undo_set_param_stateflow; 8 | case 'add_block' 9 | obj.undo_add_block; 10 | case 'add_line' 11 | obj.undo_add_line; 12 | case 'delete_line' 13 | obj.undo_delete_line; 14 | case 'replace_block' 15 | echo.OldHandle = obj.Handle; 16 | obj.undo_replace_block; 17 | echo.NewHandle = obj.Handle; 18 | otherwise 19 | end 20 | end -------------------------------------------------------------------------------- /@saRecorder/AddLine_NoDstLineToNoSrcLine.m: -------------------------------------------------------------------------------- 1 | function AddLine_NoDstLineToNoSrcLine(obj, srchdl, dsthdl) 2 | % srchdl : line handle with destination disconnected 3 | % dsthdl : line handle with source disconnected 4 | parsys = get_param(srchdl, 'Parent'); 5 | srcpos = get_param(srchdl, 'Points'); srcpos = srcpos(end,:); 6 | dstpos = get_param(dsthdl, 'Points'); dstpos = dstpos(1,:); 7 | lnpoints = [srcpos;... 8 | round((srcpos(1)+dstpos(1))/2), srcpos(2);... 9 | round((srcpos(1)+dstpos(1))/2), dstpos(2);... 10 | dstpos]; 11 | obj.AddLine(parsys, lnpoints); 12 | end -------------------------------------------------------------------------------- /@saProtoBlock/Annotate.m: -------------------------------------------------------------------------------- 1 | function actrec = Annotate(obj, blkhdl) 2 | 3 | actrec = saRecorder; 4 | if isempty(obj.AnnotationMethod) 5 | return; 6 | end 7 | 8 | annomethod = obj.AnnotationMethod; 9 | if isa(annomethod, 'function_handle') 10 | nn = nargout(annomethod); 11 | if nn~=0 %if mandatory output exist, must be saRecorder 12 | actrec.Merge(annomethod(blkhdl)); 13 | else 14 | annomethod(blkhdl); 15 | end 16 | elseif isstr(annomethod) 17 | actrec.SetParam(blkhdl,'AttributesFormatString',annomethod); 18 | else 19 | end 20 | 21 | 22 | end -------------------------------------------------------------------------------- /@saCmdParser/saCmdParser.m: -------------------------------------------------------------------------------- 1 | classdef saCmdParser 2 | properties 3 | RawStr 4 | Pattern 5 | PatternStr 6 | OptionStr 7 | end 8 | methods 9 | function obj = saCmdParser(cmdstr, pattern) 10 | if nargin<2 11 | pattern = ''; 12 | end 13 | obj.RawStr = cmdstr; 14 | obj.Pattern = pattern; 15 | obj.PatternStr = regexp(cmdstr, pattern, 'once','match'); 16 | obj.OptionStr = strtrim(regexprep(cmdstr, pattern, ' ', 'once')); 17 | end 18 | end 19 | end -------------------------------------------------------------------------------- /@saProtoBlock/Minus.m: -------------------------------------------------------------------------------- 1 | function actrec = Minus(obj, blkhdl, operand) 2 | actrec = saRecorder; 3 | if isempty(obj.MinusMethod) 4 | return; 5 | else 6 | if isequal(obj.MinusMethod, -1) 7 | elseif isa(obj.MinusMethod, 'function_handle') 8 | nn = nargout(obj.MinusMethod); 9 | if nn~=0 %if mandatory output exist, must be saRecorder 10 | actrec.Merge(obj.MinusMethod(blkhdl, operand)); 11 | else 12 | obj.MinusMethod(blkhdl, operand); 13 | end 14 | else 15 | end 16 | actrec + obj.AutoSize(blkhdl); 17 | end 18 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_unname.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_unname 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('script_unname'); 6 | sam.Pattern = '^unname'; 7 | sam.Callback = @script_unname; 8 | 9 | end 10 | 11 | function [actrec, success] =script_unname(cmdstr, console) 12 | %%THE SECOND PARAMETER IS NOT MANDATORY WHEN PROVIDING THIS CALLBACK 13 | %%INTERFACE 14 | actrec=saRecorder;success = false; 15 | lns=saFindSystem(gcs, 'line'); 16 | for i=1:numel(lns) 17 | actrec.SetParam(lns(i),'Name',''); 18 | end 19 | success = true; 20 | end -------------------------------------------------------------------------------- /saGetMousePosition.m: -------------------------------------------------------------------------------- 1 | function pos = saGetMousePosition 2 | mousePosition = get(0,'PointerLocation'); 3 | locationBase = get_param(gcs,'Location'); % Screen Left-Top [0 0], and always gets valid value on different screens 4 | scrollOffset = get_param(gcs,'ScrollbarOffset'); 5 | screenSize = get(0,'ScreenSize'); 6 | zoomFactor = str2double(get_param(gcs, 'ZoomFactor'))/100; 7 | % Calculate new position 8 | p_X = ceil((mousePosition(1) - locationBase(1) + scrollOffset(1))/zoomFactor); 9 | p_Y = ceil((screenSize(4) - mousePosition(2) - locationBase(2) + scrollOffset(2))/zoomFactor); 10 | pos = [p_X, p_Y]; 11 | end -------------------------------------------------------------------------------- /saObject.m: -------------------------------------------------------------------------------- 1 | classdef saObject < dynamicprops %handle 2 | %SA_SLOBJECT Summary of this class goes here 3 | % Detailed explanation goes here 4 | 5 | properties 6 | Console % Console object 7 | MapKey % Unique key in the collected map 8 | 9 | ObjectType 10 | end 11 | 12 | methods 13 | function obj = saObject(varargin) 14 | obj.ObjectType = varargin{1}; 15 | end 16 | 17 | function tf = isa(obj, type) 18 | tf = strcmpi(obj.ObjectType, type); 19 | end 20 | end 21 | 22 | end 23 | 24 | -------------------------------------------------------------------------------- /@saAction/redo_set_param_stateflow.m: -------------------------------------------------------------------------------- 1 | function redo_set_param_stateflow(obj) 2 | rt=sfroot; 3 | if isnumeric(obj.Handle) 4 | object=get_param(obj.Handle,'Object'); 5 | if strcmpi(get_param(obj.Handle,'BlockType'),'Inport') 6 | sfdata=rt.find('Scope','Input','Path',object.Path,'Port',str2num(object.Port)); 7 | elseif strcmpi(get_param(obj.Handle,'BlockType'),'Outport') 8 | sfdata=rt.find('Scope','Output','Path',object.Path,'Port',str2num(object.Port)); 9 | end 10 | sfdata.(obj.Property)=obj.NewValue; 11 | else 12 | object = obj.Handle; 13 | object.(obj.Property) = obj.NewValue; 14 | end 15 | end -------------------------------------------------------------------------------- /@saAction/undo_set_param_stateflow.m: -------------------------------------------------------------------------------- 1 | function undo_set_param_stateflow(obj) 2 | rt=sfroot; 3 | if isnumeric(obj.Handle) 4 | object=get_param(obj.Handle,'Object'); 5 | if strcmpi(get_param(obj.Handle,'BlockType'),'Inport') 6 | sfdata=rt.find('Scope','Input','Path',object.Path,'Port',str2num(object.Port)); 7 | elseif strcmpi(get_param(obj.Handle,'BlockType'),'Outport') 8 | sfdata=rt.find('Scope','Output','Path',object.Path,'Port',str2num(object.Port)); 9 | end 10 | sfdata.(obj.Property)=obj.OldValue; 11 | else 12 | object = obj.Handle; 13 | object.(obj.Property) = obj.OldValue; 14 | end 15 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_dislink.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_dislink 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('setter_dislink'); 6 | sam.Pattern = '^(dislink)'; 7 | sam.Callback = @setter_dislink; 8 | 9 | end 10 | 11 | function [actrec, success] =setter_dislink(cmdstr, console) 12 | actrec=saRecorder;success = false; 13 | objs1=saFindSystem(gcs, 'block',[],'BlockType','SubSystem'); 14 | objs2=saFindSystem(gcs, 'block',[],'BlockType','S-Function'); 15 | objs=[objs1;objs2]; 16 | for i=1:numel(objs) 17 | set_param(objs(i),'LinkStatus','inactive'); 18 | end 19 | success = true; 20 | end -------------------------------------------------------------------------------- /@saCmdParser/ParseMultiValues.m: -------------------------------------------------------------------------------- 1 | function [vals, bclean] = ParseMultiValues(obj, nmax) 2 | % float numbers will also be considered as string, e.g., 1e-3, 12.345, etc. 3 | if nargin<2 4 | nmax = inf; 5 | end 6 | if isempty(obj.OptionStr) 7 | result = {}; 8 | else 9 | result = regexp(obj.OptionStr, '(?1 && numel(vals)>nmax 19 | bclean = false; 20 | else 21 | bclean = true; 22 | end 23 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_breaklink.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_breaklink 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('setter_breaklink'); 6 | sam.Pattern = '^(brk|break)'; 7 | sam.Callback = @setter_breaklink; 8 | 9 | end 10 | 11 | function [actrec, success] =setter_breaklink(cmdstr, console) 12 | actrec=saRecorder;success = false; 13 | objs1=saFindSystem(gcs, 'block',[],'BlockType','SubSystem'); 14 | objs2=saFindSystem(gcs, 'block',[],'BlockType','S-Function'); 15 | objs=[objs1;objs2]; 16 | for i=1:numel(objs) 17 | set_param(objs(i),'LinkStatus','none'); 18 | end 19 | success = true; 20 | end -------------------------------------------------------------------------------- /@saAction/Redo.m: -------------------------------------------------------------------------------- 1 | function echo = Redo(obj) 2 | echo=[]; % feedback 3 | switch obj.Type 4 | case 'set_param' 5 | obj.redo_set_param; 6 | case 'set_param_stateflow' 7 | obj.redo_set_param_stateflow; 8 | case 'add_block' 9 | echo.OldHandle = obj.Handle; 10 | obj.redo_add_block; 11 | echo.NewHandle = obj.Handle; 12 | case 'add_line' 13 | obj.redo_add_line; 14 | case 'delete_line' 15 | obj.redo_delete_line; 16 | case 'replace_block' 17 | echo.OldHandle = obj.Handle; 18 | obj.redo_replace_block; 19 | echo.NewHandle = obj.Handle; 20 | otherwise 21 | end 22 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_rounding.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_rounding 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Rounding'); 6 | 7 | sabt.RoutinePattern = '^(floor|round|ceil|fix)'; 8 | sabt.RoutineMethod = @routine_rounding; 9 | 10 | sabt.MajorProperty = 'Operator'; 11 | sabt.RollPropertyMethod = -1; 12 | end 13 | 14 | function [actrec, success] = routine_rounding(cmdstr, console) 15 | btobj = console.MapTo('Rounding'); 16 | %parse input command 17 | cmdpsr = saCmdParser(cmdstr, btobj.RoutinePattern); 18 | [actrec, success] = Routines.num_only(btobj, cmdpsr.OptionStr, '', 'Operator', cmdpsr.PatternStr); 19 | end -------------------------------------------------------------------------------- /saStandardDataTypeStr.m: -------------------------------------------------------------------------------- 1 | function dt = saStandardDataTypeStr(rawdt) 2 | switch rawdt 3 | case {'single', 'sgl'} 4 | dt = 'single'; 5 | case {'double', 'dbl'} 6 | dt = 'double'; 7 | case {'boolean', 'bool'} 8 | dt = 'boolean'; 9 | case {'uint8', 'u8'} 10 | dt = 'uint8'; 11 | case {'uint16', 'u16'} 12 | dt = 'uint16'; 13 | case {'uint32', 'u32'} 14 | dt = 'uint32'; 15 | case {'int8', 'i8'} 16 | dt = 'int8'; 17 | case {'int16', 'i16'} 18 | dt = 'int16'; 19 | case {'int32', 'i32'} 20 | dt = 'int32'; 21 | otherwise 22 | dt=''; 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /saIsStateflow.m: -------------------------------------------------------------------------------- 1 | function [tf, sftyp] = saIsStateflow(hdl) 2 | if ischar(hdl) 3 | hdl = get_param(hdl, 'Handle'); 4 | end 5 | if isprop(hdl, 'SFBlockType') 6 | sfbtyp = get_param(hdl, 'SFBlockType'); 7 | if ~strcmpi(sfbtyp, 'NONE') 8 | switch sfbtyp 9 | case 'Chart' 10 | tf = true; sftyp = 'Stateflow'; 11 | case {'Truth Table', 'State Transition Table'} 12 | tf = true; sftyp = sfbtyp; 13 | otherwise 14 | tf = false; sftyp = ''; 15 | end 16 | else 17 | tf = false; sftyp = ''; 18 | end 19 | else 20 | tf = false; sftyp = ''; 21 | end 22 | end -------------------------------------------------------------------------------- /@saCmdParser/ParseNumericAndString.m: -------------------------------------------------------------------------------- 1 | function [result, bclean] = ParseNumericAndString(obj) 2 | 3 | numpattern = '([-+]?\d+[.]?\d*([eE][-+]?\d+)?)'; 4 | numstr = regexp(obj.OptionStr, numpattern, 'match', 'once'); 5 | if ~isempty(numstr) 6 | result.Numeric = str2double(numstr); 7 | result.NumericStr = numstr; 8 | else 9 | result.Numeric = []; 10 | result.NumericStr = ''; 11 | end 12 | reststr = strtrim(regexprep(obj.OptionStr, numpattern, ' ', 'once')); 13 | 14 | valpattern = '\w+'; 15 | result.String = regexp(reststr, valpattern, 'match', 'once'); 16 | reststr = strtrim(regexprep(reststr, valpattern, '', 'once')); 17 | bclean = isempty(reststr); 18 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_sl_canpack.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_sl_canpack 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('canmsglib/CAN Pack'); 6 | 7 | sabt.InportStringMethod = @inport_string_canpack; 8 | 9 | end 10 | 11 | 12 | function thestr = inport_string_canpack(pthdl) 13 | ptnum = get_param(pthdl, 'PortNumber'); 14 | parblk = get_param(pthdl, 'Parent'); 15 | mskwsvars = get_param(parblk,'MaskWSVariables'); 16 | portvar = mskwsvars(strcmp({mskwsvars.Name}, 'port')).Value; %find the "port" variable used to draw the outport name 17 | %the first one is for inport, 2:end for outport 18 | thestr = portvar(ptnum).label; 19 | end -------------------------------------------------------------------------------- /@saProtoBlock/Clean.m: -------------------------------------------------------------------------------- 1 | function actrec = Clean(obj, blkhdl, varargin) 2 | actrec = saRecorder; 3 | if isempty(obj.CleanMethod) 4 | return; 5 | else 6 | cleanmethod = obj.CleanMethod; 7 | % customized clean process 8 | if isequal(cleanmethod, -1) 9 | elseif isa(cleanmethod, 'function_handle') 10 | nn = nargout(cleanmethod); 11 | ni = nargin(cleanmethod); 12 | argsin = {blkhdl, obj.Console, varargin{:}}; 13 | if nn~=0 %if mandatory output exist, must be saRecorder 14 | actrec.Merge(cleanmethod(argsin{1:ni})); 15 | else 16 | cleanmethod(argsin{1:ni}); 17 | end 18 | else 19 | end 20 | end 21 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_sl_canunpack.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_sl_canunpack 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('canmsglib/CAN Unpack'); 6 | 7 | sabt.OutportStringMethod = @outport_string_canunpack; 8 | 9 | end 10 | 11 | 12 | function thestr = outport_string_canunpack(pthdl) 13 | ptnum = get_param(pthdl, 'PortNumber'); 14 | parblk = get_param(pthdl, 'Parent'); 15 | mskwsvars = get_param(parblk,'MaskWSVariables'); 16 | portvar = mskwsvars(strcmp({mskwsvars.Name}, 'port')).Value; %find the "port" variable used to draw the outport name 17 | %the first one is for inport, 2:end for outport 18 | thestr = portvar(1+ptnum).label; 19 | end -------------------------------------------------------------------------------- /@saAction/add_block.m: -------------------------------------------------------------------------------- 1 | function add_block(obj,varargin) 2 | obj.Data.Source = varargin{1}; 3 | prop = varargin(3:end); 4 | % if 'Name' in property list, merge into destination parameter 5 | loc = []; 6 | for i=1:numel(prop) 7 | if isstr(prop{i}) && strcmp(prop{i}, 'Name') 8 | loc = i; 9 | break; 10 | end 11 | end 12 | 13 | if ~isempty(loc) 14 | obj.Data.Destination = regexprep(varargin{2}, '[^/]+$', prop{loc+1}); 15 | prop([loc, loc+1])=[]; 16 | else 17 | obj.Data.Destination = varargin{2}; 18 | end 19 | % action 20 | obj.Handle = add_block(obj.Data.Source, obj.Data.Destination, 'MakeNameUnique', 'on', prop{:}); 21 | obj.Property = [prop(1:2:end);prop(2:2:end)]; 22 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_strrep.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_strrep 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('setter_strrep'); 6 | sam.Pattern = '^.+=>.*'; 7 | sam.Callback = @setter_strrep; 8 | sam.Priority = 2; 9 | 10 | end 11 | 12 | 13 | function [actrec, success] =setter_strrep(cmdstr, console) 14 | actrec=saRecorder;success = false; 15 | regtmp = regexp(cmdstr, '^(.+)=>(.*)','once','tokens'); 16 | [oldstr, newstr] = regtmp{:}; 17 | objhdls = saFindSystem(gcs); 18 | for i=1:numel(objhdls) 19 | saobj = console.MapTo(objhdls(i)); 20 | actrec.Merge(saobj.ReplaceStr(objhdls(i), oldstr, newstr)); 21 | end 22 | success = true; 23 | end -------------------------------------------------------------------------------- /GetAdjBlks.m: -------------------------------------------------------------------------------- 1 | function adjblks=GetAdjBlks(tgtblk) 2 | if tgtblk<0 3 | adjblks=struct('SrcBlockHandles',[],'DstBlockHandles',[]); 4 | return; 5 | end 6 | ln=get_param(tgtblk,'LineHandles'); 7 | adjblks=struct(); 8 | srcblks=[];dstblks=[]; 9 | for i=1:numel(ln.Inport) 10 | if ln.Inport(i)>0 11 | srcblk=get_param(ln.Inport(i),'SrcBlockHandle'); 12 | srcblks=[srcblks;srcblk]; 13 | end 14 | end 15 | for i=1:numel(ln.Outport) 16 | if ln.Outport(i)>0 17 | dstblk=get_param(ln.Outport(i),'DstBlockHandle'); 18 | dstblks=[dstblks;dstblk]; 19 | end 20 | end 21 | adjblks.SrcBlockHandles=unique(srcblks(srcblks>0)); 22 | adjblks.DstBlockHandles=unique(dstblks(dstblks>0)); -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_motohawk_to_simulink.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_motohawk_to_simulink 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('script_motohawk_to_simulink'); 6 | sam.Pattern = '^m2s'; 7 | sam.Callback = @script_motohawk_to_simulink; 8 | 9 | end 10 | 11 | function [actrec, success] =script_motohawk_to_simulink(cmdstr, console) 12 | actrec=saRecorder;success = false; 13 | objhdls=saFindSystem(gcs, 'block'); 14 | opt = regexprep(cmdstr, '^m2s\s*', ''); 15 | if ~isempty(objhdls) 16 | actrec.Merge(m2s_wrapper(gcs,opt,false,'Selected','on')); 17 | else 18 | actrec.Merge(m2s_wrapper(gcs,opt,false)); 19 | end 20 | success = true; 21 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_simulink_to_motohawk.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_simulink_to_motohawk 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('script_simulink_to_motohawk'); 6 | sam.Pattern = '^s2m'; 7 | sam.Callback = @script_simulink_to_motohawk; 8 | 9 | end 10 | 11 | function [actrec, success] =script_simulink_to_motohawk(cmdstr, console) 12 | actrec=saRecorder;success = false; 13 | objhdls = saFindSystem(gcs, 'block'); 14 | opt = regexprep(cmdstr, '^s2m\s*', ''); 15 | if ~isempty(objhdls) 16 | actrec.Merge(s2m_wrapper(gcs,opt,false,'Selected','on')); 17 | else 18 | actrec.Merge(s2m_wrapper(gcs,opt,false)); 19 | end 20 | success = true; 21 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_enableport.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_enableport 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('EnablePort'); 6 | 7 | sabt.RoutineMethod = 'majorprop_value'; 8 | sabt.RoutinePattern = '^(en|enable)'; 9 | sabt.RoutinePriority = 40; 10 | 11 | sabt.PropagateUpstreamStringMethod = @enpropupstream; 12 | 13 | sabt.MajorProperty = 'Name'; 14 | 15 | sabt.BlockSize = [20, 20]; 16 | end 17 | 18 | function actrec = enpropupstream(blkhdl, dummy, console) 19 | actrec = saRecorder; 20 | parsys = get_param(blkhdl, 'Parent'); 21 | pts = get_param(parsys,'PortHandles'); 22 | thestr = console.GetUpstreamString(pts.Enable); 23 | actrec.SetParam(blkhdl, 'Name', thestr); 24 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_math.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_math 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Math'); 6 | 7 | sabt.RoutineMethod = @routine_math; 8 | sabt.RoutinePattern = '^(exp|log10|log|square|reciprocal|pow|rem|mod)'; 9 | sabt.RoutinePriority = 51; 10 | 11 | sabt.BlockSize = [25, 25]; 12 | 13 | sabt.MajorProperty = 'Operator'; 14 | sabt.RollPropertyMethod = -1; 15 | end 16 | 17 | function [actrec, success] = routine_math(cmdstr, console) 18 | btobj = console.MapTo('Math'); 19 | %parse input command 20 | cmdpsr = saCmdParser(cmdstr, btobj.RoutinePattern); 21 | [actrec, success] = Routines.num_only(btobj, cmdpsr.OptionStr, '', 'Operator', cmdpsr.PatternStr); 22 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_trigonometry.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_trigonometry 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Trigonometry'); 6 | 7 | sabt.RoutineMethod = @routine_trigonometry; 8 | sabt.RoutinePattern = '^(sinh|cosh|tanh|asinh|acosh|atanh|sincos|sin|cos|tan|asin|acos|atan)'; 9 | 10 | 11 | sabt.MajorProperty = 'Operator'; 12 | sabt.RollPropertyMethod = -1; 13 | end 14 | 15 | function [actrec, success] = routine_trigonometry(cmdstr, console) 16 | btobj = console.MapTo('Trigonometry'); 17 | %parse input command 18 | cmdpsr = saCmdParser(cmdstr, btobj.RoutinePattern); 19 | [actrec, success] = Routines.num_only(btobj, cmdpsr.OptionStr, '', 'Operator', cmdpsr.PatternStr); 20 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_opsym_ampersand.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_opsym_ampersand 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('opsym_ampersand'); 6 | sam.Pattern = '&'; 7 | sam.Callback = @opsym_ampersand; 8 | sam.Priority = 1; % & operator shall first be tested 9 | end 10 | 11 | function [actrec, success] = opsym_ampersand(cmdstr, console) 12 | % test & joint of multiple commands 13 | actrec = saRecorder; success = false; 14 | multicmdstrs = strtrim(regexp(cmdstr, '&', 'split')); 15 | if numel(multicmdstrs)>1 16 | for i=1:numel(multicmdstrs) 17 | actrec + console.RunCommand(strtrim(multicmdstrs{i})); 18 | end 19 | end 20 | if ~isempty(actrec) 21 | success = true; 22 | end 23 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_datatype.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_datatype 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('setter_datatype'); 6 | sam.Pattern = '^(single|sgl|double|dbl|boolean|bool|uint8|u8|uint16|u16|uint32|u32|int8|i8|int16|i16|int32|i32)'; 7 | sam.Callback = @setter_datatype; 8 | end 9 | 10 | function [actrec, success] =setter_datatype(cmdstr, console) 11 | actrec=saRecorder;success = false; 12 | dt = strtrim(cmdstr); 13 | dt = saStandardDataTypeStr(dt); 14 | if ~isempty(dt) 15 | tgtobjs = saFindSystem(gcs, 'block'); 16 | for i=1:numel(tgtobjs) 17 | actrec + console.MapTo(tgtobjs(i)).SetDataType(tgtobjs(i), dt); 18 | end 19 | end 20 | success = true; 21 | end -------------------------------------------------------------------------------- /_BlockRegistration/regprotoblock_LGPT_datastore.m: -------------------------------------------------------------------------------- 1 | function sabt = regprotoblock_LGPT_datastore 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saProtoBlock('LGPT_datastore'); 6 | sabt.ProtoCheckMethod = @check_proto; 7 | sabt.ProtoProperty = {'MajorProperty', 'InportStringMethod', 'OutportStringMethod'}; 8 | 9 | 10 | sabt.MajorProperty = 'DataStoreName'; 11 | 12 | sabt.InportStringMethod = 'DataStoreName'; 13 | sabt.OutportStringMethod = 'DataStoreName'; 14 | 15 | end 16 | 17 | function tf = check_proto(blkhdl) 18 | msktyp = get_param(blkhdl, 'MaskType'); 19 | if ismember(msktyp, {'LGPT_DataReadWrite', 'LGPT_ReadArrayElement', 'LGPT_WriteArrayElement'}) 20 | tf = true; 21 | else 22 | tf = false; 23 | end 24 | end -------------------------------------------------------------------------------- /@saMacro/Run.m: -------------------------------------------------------------------------------- 1 | function [actrec, success] = Run(objarr, cmdstr) 2 | % Try run each macro script until successed 3 | % Note that in macro definition, number of input and output arguments among 4 | % the related functions (GetOptionMethod, ParseOptionMethod, Callback) must 5 | % coordinate 6 | if nargin<2 7 | cmdstr = ''; 8 | end 9 | console = objarr(1).Console; 10 | for i=1:numel(objarr) 11 | theobj = objarr(i); 12 | ni = nargin(theobj.Callback); 13 | if ni>2 14 | [args{1:ni-2}] = theobj.Parse(cmdstr, console); 15 | else 16 | args={}; 17 | end 18 | arglist = {cmdstr, console, args{:}}; 19 | [actrec, success] = theobj.Callback(arglist{1:ni}); 20 | if success 21 | break; 22 | end 23 | end 24 | 25 | end -------------------------------------------------------------------------------- /+Routines/majorprop_value.m: -------------------------------------------------------------------------------- 1 | function [actrec, success] = majorprop_value(btobj, cmdstr, pattern, varargin) 2 | cmdpsr = saCmdParser(cmdstr, pattern); 3 | [result, bclean] = cmdpsr.ParseMultiValues; 4 | if bclean 5 | if ~isempty(result) 6 | option.PropagateString = false; 7 | if numel(result)==1 8 | pvpair = {varargin{:}, btobj.MajorProperty, result{1}}; 9 | else 10 | pvpair = {varargin{:}, btobj.MajorProperty, result}; 11 | end 12 | else 13 | option = struct; 14 | pvpair = varargin; 15 | end 16 | num = numel(result); 17 | actrec = btobj.GenericContextAdd(num, option, pvpair{:}); 18 | success = true; 19 | else 20 | [actrec, success] = deal(saRecorder, false); 21 | end 22 | end -------------------------------------------------------------------------------- /saRectifyPos.m: -------------------------------------------------------------------------------- 1 | function [newpos, rectd] = saRectifyPos(pos) 2 | % pos can be block size (4x1) or port position (2x1) 3 | newpos = pos; 4 | rectd = false; 5 | if numel(pos)>2 6 | if pos(3)2 19 | newpos(3) = pos(3)-pos(1); 20 | end 21 | rectd = true; 22 | end 23 | if pos(2)<0 24 | pos(2)=0; 25 | if numel(pos)>2 26 | newpos(4) = pos(4)-pos(2); 27 | end 28 | rectd = true; 29 | end 30 | end 31 | end -------------------------------------------------------------------------------- /@saRecorder/private/timerdisplay.m: -------------------------------------------------------------------------------- 1 | function timerdisplay(hblk,properties,newvals) 2 | try 3 | oldcolor=get_param(hblk,'ForegroundColor'); 4 | catch 5 | return; 6 | end 7 | oldannotation=get_param(hblk,'AttributesFormatString'); 8 | set_param(hblk,'ForegroundColor','green'); 9 | if isstr(properties) 10 | properties={properties}; 11 | newvals={newvals}; 12 | end 13 | dispstr=''; 14 | for i=1:numel(properties) 15 | if ~isstr(newvals{i}) 16 | newvals{i}=num2str(newvals{i}); 17 | end 18 | dispstr=sprintf('%s%s: %s\n',dispstr,properties{i},newvals{i}); 19 | end 20 | set_param(hblk,'AttributesFormatString',dispstr); 21 | tmr=timer('ExecutionMode','singleShot','StartDelay',0.5,'TimerFcn',{@timerfcn,hblk,oldcolor,oldannotation}); 22 | start(tmr); 23 | end -------------------------------------------------------------------------------- /@saBlockGroup/getBGPorts.m: -------------------------------------------------------------------------------- 1 | function ports=getBGPorts(obj) 2 | blks=obj.BlockHandles; 3 | Inports=[]; 4 | Outports=[]; 5 | for i=1:numel(blks) 6 | lns=get_param(blks(i),'LineHandles'); 7 | pts=get_param(blks(i),'PortHandles'); 8 | for j=1:numel(lns.Inport) 9 | if lns.Inport(j)>0 10 | if ~ismember(get_param(lns.Inport(j),'SrcBlockHandle'),blks) 11 | Inports=[Inports;pts.Inport(j)]; 12 | end 13 | end 14 | end 15 | for j=1:numel(lns.Outport) 16 | if lns.Outport(j)>0 17 | if ~ismember(get_param(lns.Outport(j),'DstBlockHandle'),blks) 18 | Outports=[Outports;pts.Outport(j)]; 19 | end 20 | end 21 | end 22 | end 23 | ports.Inports=Inports; 24 | ports.Outports=Outports; 25 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_toworkspace.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_toworkspace 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('ToWorkspace'); 6 | sabt.MajorProperty = 'VariableName'; 7 | sabt.DictRenameMethod = 1; % use major property 8 | sabt.BlockSize = [70, 20]; 9 | 10 | sabt.RoutineMethod = 'majorprop_str_num'; 11 | sabt.RoutinePattern = '^(tows|toworkspace)'; 12 | sabt.RoutinePriority = 15; 13 | 14 | sabt.PropagateUpstreamStringMethod = 'VariableName'; 15 | sabt.InportStringMethod = 'VariableName'; 16 | sabt.RefineMethod = @refine_method; 17 | end 18 | 19 | function actrec = refine_method(blkhdl) 20 | actrec = saRecorder; 21 | tag = get_param(blkhdl, 'VariableName'); 22 | newval=[tag,'_',get_param(blkhdl,'BlockType')]; 23 | actrec.SetParam(blkhdl, 'Name', newval); 24 | end -------------------------------------------------------------------------------- /@saProtoBlock/CreateRoutineMacro.m: -------------------------------------------------------------------------------- 1 | function sam = CreateRoutineMacro(obj) 2 | pattern = obj.RoutinePattern; 3 | if isempty(pattern) 4 | sam = []; return; 5 | end 6 | name = ['#',obj.MapKey]; 7 | 8 | sam = saMacro(name); 9 | sam.Type = 'Routine'; 10 | if pattern(1)~='^' 11 | sam.Pattern = ['^', pattern]; 12 | else 13 | sam.Pattern = pattern; 14 | end 15 | 16 | rtmethod = obj.RoutineMethod; 17 | if isa(rtmethod, 'function_handle') 18 | sam.Callback = rtmethod; 19 | else %isstr 20 | fcn = str2func(['Routines.', rtmethod]); 21 | sam.Callback = @(cmdstr) feval(fcn, obj, cmdstr, pattern); 22 | end 23 | if ~isempty(obj.RoutinePrompts) 24 | sam.PromptMethod = obj.RoutinePrompts; 25 | end 26 | if ~isempty(obj.RoutinePriority) 27 | sam.Priority = obj.RoutinePriority; %promote priority 28 | end 29 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_inport.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_inport 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Inport'); 6 | sabt.RoutineMethod = 'majorprop_str_num'; 7 | sabt.RoutinePattern = '^(inport|ipt|ip)'; 8 | 9 | sabt.ConnectPort = [0, 1]; 10 | 11 | sabt.MajorProperty = 'Name'; 12 | sabt.PropertyList = {'Name', 'Port'}; 13 | sabt.DictRenameMethod = 1; 14 | 15 | sabt.PropagateUpstreamStringMethod = 'Name'; 16 | sabt.PropagateDownstreamStringMethod = 'Name'; 17 | sabt.OutportStringMethod = 'Name'; 18 | 19 | sabt.BlockSize = [30 14]; 20 | 21 | sabt.BlockPreferOption.ShowName = 'on'; 22 | sabt.BlockPreferOption.AutoDataType = false; 23 | 24 | sabt.LayoutSize.VerticalMargin = 40; 25 | 26 | sabt.DataTypeMethod = 'OutDataTypeStr'; 27 | sabt.DefaultDataType = 'Inherit: auto'; 28 | 29 | end -------------------------------------------------------------------------------- /@saCmdParser/ParseStringAndInteger.m: -------------------------------------------------------------------------------- 1 | function [result, bclean] = ParseStringAndInteger(obj) 2 | % float numbers will also be considered as string, e.g., 1e-3, 12.345, etc. 3 | 4 | % find isolated integers, i.e., not trailing "." ,"-" or letters, and not 5 | % preceding "." 6 | numpattern = '(?'; 25 | 26 | sabt.DataTypeMethod = 'OutDataTypeStr'; 27 | sabt.DefaultDataType = 'Inherit: auto'; 28 | end 29 | -------------------------------------------------------------------------------- /@saAction/CheckLink.m: -------------------------------------------------------------------------------- 1 | function CheckLink(obj) 2 | % CURRENTLY NOT USED 3 | 4 | tmp_h=get_param(obj.Handle,'Parent'); 5 | %If in a library link, first disable it 6 | if strcmpi(get_param(tmp_h,'Type'),'block')&&strcmpi(get_param(tmp_h,'LinkStatus'),'resolved')% 7 | set_param(tmp_h,'LinkStatus','inactive'); 8 | warndlg(['Caution! Modifying inside a library link.',char(10),'Link disabled.']); 9 | elseif strcmpi(get_param(tmp_h,'Type'),'block')&&strcmpi(get_param(tmp_h,'LinkStatus'),'implicit')% 10 | while strcmpi(get_param(tmp_h,'LinkStatus'),'implicit') 11 | tmp_h=get_param(tmp_h,'Parent'); 12 | if strcmpi(get_param(tmp_h,'LinkStatus'),'resolved') 13 | set_param(tmp_h,'LinkStatus','inactive'); 14 | warndlg(['Caution! Modifying inside a library link.',char(10),'Link disabled.']); 15 | end 16 | end 17 | else 18 | end 19 | end -------------------------------------------------------------------------------- /@saBlockGroup/SplitToIntactBGs.m: -------------------------------------------------------------------------------- 1 | function objs=SplitToIntactBGs(obj) 2 | objs=[]; 3 | if obj.BlockCount==0 4 | return; 5 | end 6 | blkset=obj.BlockHandles; 7 | resid=blkset; 8 | while ~isempty(resid) 9 | subbg=resid(1); 10 | expdedblks=resid(1); 11 | while ~isempty(expdedblks) %as long as expanded connected blocks found 12 | adjblkspool=[]; 13 | for i=1:numel(expdedblks) 14 | tmpadjblks=GetAdjBlks(expdedblks(i)); 15 | adjblkspool=[adjblkspool;tmpadjblks.SrcBlockHandles;tmpadjblks.DstBlockHandles]; %add to adjacent blocks pool 16 | end 17 | expdedblks=intersect(adjblkspool,resid); % inside the block group 18 | subbg=[subbg;expdedblks]; % add into sub block group 19 | resid=setdiff(resid,subbg); %discard from the residual blocks 20 | end 21 | objs=[objs;saBlockGroup(subbg)]; 22 | end 23 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_mux.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_mux 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Mux'); 6 | sabt.RoutineMethod = 'dynamicinport'; 7 | sabt.RoutinePattern = '^mux'; 8 | sabt.RoutinePara.InportProperty = 'Inputs'; 9 | 10 | 11 | sabt.OutportStringMethod = @inport_string; 12 | 13 | sabt.SourcePath = 'Mux'; 14 | sabt.BlockSize = [5, 70]; 15 | 16 | sabt.DefaultParameters = {'DisplayOption', 'bar'}; 17 | 18 | sabt.LayoutSize.PortSpacing = 30; 19 | 20 | parobj = regblock_buscreator; % inherit from BusCreator 21 | sabt.Inherit(parobj, 'PlusMethod', 'MinusMethod'); 22 | end 23 | 24 | function str = inport_string(pthdl, appdata) 25 | parblk = get_param(pthdl, 'Parent'); 26 | ptnum = get_param(pthdl, 'PortNumber'); 27 | outstr = cellstr(appdata.Console.GetDownstreamString(parblk)); 28 | str = [outstr, '_D', int2str(ptnum)]; 29 | end -------------------------------------------------------------------------------- /+Routines/dynamicinport.m: -------------------------------------------------------------------------------- 1 | function [actrec, success] = dynamicinport(btobj, cmdstr, pattern, varargin) 2 | actrec = saRecorder; 3 | 4 | cmdpsr = saCmdParser(cmdstr, pattern); 5 | [numipt, bclean] = cmdpsr.ParseInteger; 6 | if ~bclean 7 | [actrec, success] = deal(saRecorder, false); 8 | return; 9 | end 10 | 11 | if isempty(numipt) 12 | tgtobjs = saFindSystem(gcs,'line_sender'); 13 | if isempty(tgtobjs) 14 | numipt = '1'; autoline = false; 15 | else 16 | numipt = int2str(numel(tgtobjs)); autoline = true; 17 | end 18 | [actrec2, block] = btobj.AddBlock(varargin{:}, btobj.RoutinePara.InportProperty, numipt); 19 | actrec + actrec2; 20 | if autoline 21 | actrec.MultiAutoLine(tgtobjs, block); 22 | end 23 | else 24 | actrec + btobj.AddBlock(varargin{:}, btobj.RoutinePara.InportProperty, int2str(numipt)); 25 | end 26 | success = true; 27 | end -------------------------------------------------------------------------------- /@saProtoBlock/GetMajorProperty.m: -------------------------------------------------------------------------------- 1 | function majprop = GetMajorProperty(obj, blkhdl) 2 | if isempty(obj.MajorProperty) 3 | majprop = 'Name'; 4 | elseif ischar(obj.MajorProperty) 5 | majprop = obj.MajorProperty; 6 | elseif iscell(obj.MajorProperty) 7 | majprop = obj.MajorProperty{1}; 8 | elseif isnumeric(obj.MajorProperty) 9 | dlgparas = fieldnames(get_param(blkhdl, 'DialogParameters')); 10 | if ~isempty(dlgparas) 11 | if obj.MajorProperty == -1 12 | majprop = dlgparas{1}; % use the first dialog parameter as major property 13 | else 14 | majprop = dlgparas{i}; % use the Nth dialog parameter 15 | end 16 | else 17 | majprop = ''; 18 | end 19 | elseif isa(obj.MajorProperty, 'function_handle') 20 | getmajpropmethod = obj.MajorProperty; 21 | majprop = getmajpropmethod(blkhdl); 22 | else 23 | majprop = 'Name'; 24 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_datastorewrite.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_datastorewrite 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('DataStoreWrite'); 6 | 7 | % routines for DataStore family are combined as a seperate macro, see macro 8 | % registration file 9 | sabt.RoutinePattern = ''; 10 | 11 | % bro-block properties 12 | sabt.BroBlockType = {'DataStoreRead', 'DataStoreMemory'}; 13 | sabt.CreateBroBlockMethod = -1; 14 | sabt.ConnectPort = [1, 0]; 15 | 16 | sabt.MajorProperty = 'DataStoreName'; 17 | sabt.DictRenameMethod = 1; % use major property 18 | 19 | sabt.PropagateUpstreamStringMethod = 'DataStoreName'; 20 | sabt.OutportStringMethod = 'DataStoreName'; 21 | 22 | sabt.BlockSize = [100, 30]; 23 | sabt.LayoutSize.CharWidth = 6; 24 | 25 | sabt.AutoSizeMethod = -3; % rightwards expand to show string 26 | 27 | sabt.GetBroMethod = @saFindBroBlocks; 28 | end 29 | 30 | -------------------------------------------------------------------------------- /@saProtoBlock/Plus.m: -------------------------------------------------------------------------------- 1 | function actrec = Plus(obj, blkhdl, operand) 2 | actrec = saRecorder; 3 | if isempty(obj.PlusMethod) 4 | return; 5 | else 6 | bkups = obj.TemporaryCurrentBlockBased(blkhdl); % backup default properties coz port spacing shall be based on current block 7 | %%%%%%%%% 8 | if isequal(obj.PlusMethod, -1) 9 | elseif isa(obj.PlusMethod, 'function_handle') 10 | nn = nargout(obj.PlusMethod); 11 | ni = nargin(obj.PlusMethod); 12 | args = {blkhdl, operand, obj.Console}; 13 | if nn~=0 %if mandatory output exist, must be saRecorder 14 | actrec.Merge(obj.PlusMethod(args{1:ni})); 15 | else 16 | obj.PlusMethod(args{1:ni}); 17 | end 18 | else 19 | end 20 | actrec + obj.AutoSize(blkhdl); 21 | %%%%%%%%%% 22 | obj.TemporaryCurrentBlockBased(bkups); % restore original object properties 23 | end 24 | end 25 | 26 | -------------------------------------------------------------------------------- /@saProtoBlock/RollProperty.m: -------------------------------------------------------------------------------- 1 | function actrec = RollProperty(obj, blkhdl) 2 | 3 | actrec = saRecorder; 4 | 5 | rollpropmethod = obj.RollPropertyMethod; 6 | if isequal(rollpropmethod, -1) 7 | rollpropmethod = obj.GetMajorProperty(blkhdl); 8 | end 9 | 10 | if isa(rollpropmethod, 'function_handle') 11 | nn = nargout(rollpropmethod); 12 | if nn~=0 %if mandatory output exist, must be saRecorder 13 | actrec.Merge(rollpropmethod(blkhdl)); 14 | else 15 | rollpropmethod(blkhdl); 16 | end 17 | elseif isstr(rollpropmethod) 18 | dlgparas = get_param(blkhdl,'DialogParameters'); 19 | lst = dlgparas.(rollpropmethod).Enum; 20 | ik = strmatch(get_param(blkhdl,rollpropmethod), lst, 'exact'); 21 | tmp = rem(ik+1, numel(lst)); 22 | i_next = tmp + (~tmp)*numel(lst); 23 | valnext=lst{i_next}; 24 | actrec.SetParam(blkhdl,rollpropmethod,valnext); 25 | else 26 | end 27 | 28 | 29 | end -------------------------------------------------------------------------------- /+Routines/majorprop_str_num.m: -------------------------------------------------------------------------------- 1 | function [actrec, success] = majorprop_str_num(btobj, cmdstr, pattern, varargin) 2 | cmdpsr = saCmdParser(cmdstr, pattern); 3 | [result, bclean] = cmdpsr.ParseValuesAndInteger; 4 | if bclean 5 | if ~isempty(result.Values) 6 | option.PropagateString = false; 7 | if numel(result.Values)==1 8 | pvpair = {varargin{:}, btobj.MajorProperty, result.Values{1}}; 9 | else 10 | pvpair = {varargin{:}, btobj.MajorProperty, result.Values}; 11 | end 12 | else 13 | option.PropagateString = true; 14 | pvpair = varargin; 15 | end 16 | if isempty(result.Integer) n0 = 0; 17 | else n0 = result.Integer; 18 | end 19 | num = max(n0,numel(result.Values)); 20 | actrec = btobj.GenericContextAdd(num, option, pvpair{:}); 21 | success = true; 22 | else 23 | [actrec, success] = deal(saRecorder, false); 24 | end 25 | end -------------------------------------------------------------------------------- /@saAction/set_param_stateflow.m: -------------------------------------------------------------------------------- 1 | function set_param_stateflow(obj,varargin) 2 | obj.Handle = varargin{1}; 3 | obj.Property = varargin{2}; 4 | obj.NewValue = varargin{3}; 5 | %action 6 | rt=sfroot; 7 | if isnumeric(varargin{1}) 8 | % currently only used for setting inport/outport name 9 | obj.OldValue = get_param(obj.Handle,'Name'); 10 | sfobj=get_param(obj.Handle,'Object'); 11 | if strcmpi(get_param(obj.Handle,'BlockType'),'Inport') 12 | sfdata=rt.find('-isa','Stateflow.Data','Scope','Input','Path',sfobj.Path,'Port',str2double(sfobj.Port)); 13 | elseif strcmpi(get_param(obj.Handle,'BlockType'),'Outport') 14 | sfdata=rt.find('Scope','Output','Path',sfobj.Path,'Port',str2double(sfobj.Port)); 15 | end 16 | sfdata.(obj.Property)=obj.NewValue; 17 | else 18 | sfobj = varargin{1}; 19 | obj.OldValue = sfobj.(obj.Property); 20 | sfobj.(obj.Property) = obj.NewValue; 21 | end 22 | 23 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_argout.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_argout 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('ArgOut'); 6 | sabt.RoutineMethod = 'majorprop_str_num'; 7 | sabt.RoutinePattern = '^argout'; 8 | 9 | sabt.MajorProperty = 'ArgumentName'; 10 | sabt.DictRenameMethod = 1; % use major property 11 | 12 | sabt.PropagateDownstreamStringMethod = -1; 13 | sabt.PropagateUpstreamStringMethod = 'ArgumentName'; 14 | sabt.InportStringMethod = 'ArgumentName'; 15 | sabt.OutportStringMethod = -1; 16 | 17 | sabt.RefineMethod = @refine_method; 18 | sabt.ColorMethod = {-1, false}; 19 | 20 | sabt.BlockSize = [100, 14]; 21 | sabt.LayoutSize.CharWidth = 6; 22 | 23 | end 24 | 25 | function actrec = refine_method(blkhdl) 26 | actrec = saRecorder; 27 | tag = get_param(blkhdl, 'ArgumentName'); 28 | newval=sprintf('ArgOut%s_%s',tag, get_param(blkhdl,'Port')); 29 | actrec.SetParamHighlight(blkhdl, 'Name', newval); 30 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_fromworkspace.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_fromworkspace 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('FromWorkspace'); 6 | 7 | sabt.RoutineMethod = 'majorprop_str_num'; 8 | sabt.RoutinePattern = '^(fromws|fromworkspace)'; 9 | sabt.RoutinePriority = 15; 10 | 11 | sabt.BroBlockType = {'ToWorkspace'}; 12 | sabt.CreateBroBlockMethod = -1; 13 | sabt.ConnectPort = [0, 1]; 14 | 15 | sabt.MajorProperty = 'VariableName'; 16 | sabt.DictRenameMethod = 1; % use major property 17 | sabt.BlockSize = [70, 20]; 18 | 19 | sabt.PropagateDownstreamStringMethod = 'VariableName'; 20 | sabt.OutportStringMethod = 'VariableName'; 21 | 22 | sabt.RefineMethod = @refine_method; 23 | end 24 | 25 | function actrec = refine_method(blkhdl) 26 | actrec = saRecorder; 27 | tag = get_param(blkhdl, 'VariableName'); 28 | newval=[tag,'_',get_param(blkhdl,'BlockType')]; 29 | actrec.SetParam(blkhdl, 'Name', newval); 30 | end -------------------------------------------------------------------------------- /@saConsole/AddCurrentBlockToMap.m: -------------------------------------------------------------------------------- 1 | function [sabt, sam] = AddCurrentBlockToMap(obj, blkhdl) 2 | % Add new block type to saBlock map 3 | [sabt, sam] = create_saobject(rawtxt{i,:}); 4 | sabt.Console = obj; 5 | obj.Map(sabt.MapKey) = sabt; 6 | sam.Console = obj; 7 | 8 | [tmp, iprio] = sort([macroobjs.Priority]); 9 | macroobjs = macroobjs(iprio); 10 | obj.Macros = macroobjs; 11 | end 12 | 13 | 14 | function [sabt, sam] = create_saobject(varargin) 15 | [msktyp, pattern, srcpath, priority] = varargin{1:4}; 16 | dlgparas = get_param(srcpath, 'DialogParameters'); 17 | if ~isempty(dlgparas) 18 | dlgparas = fieldnames(dlgparas); 19 | else 20 | dlgparas={}; 21 | end 22 | blktyp = get_param(srcpath, 'BlockType'); 23 | % create saBlock object 24 | sabt = saBlock(blktyp, msktyp, srcpath); 25 | if ~isempty(dlgparas) 26 | sabt.MajorProperty = dlgparas{1}; 27 | end 28 | % create macro object 29 | sam = saMacroAdder(sabt, pattern); 30 | sam.Priority = priority; 31 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_opsym_percent.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_opsym_percent 2 | % Registration of ??? macro in SimAssist 3 | 4 | sam = saMacro('opsym_percent'); 5 | sam.Pattern = '^%'; 6 | sam.Callback = @opsym_percent; 7 | sam.Priority = 1; % $ operator shall first be tested 8 | end 9 | 10 | function [actrec, success] = opsym_percent(cmdstr, console) 11 | actrec = saRecorder; success = false; 12 | optstr = cmdstr(2:end); 13 | otherpattern = ~isempty(strfind(optstr, '=>'))||~isempty(strfind(optstr, '>>')); 14 | if isempty(optstr)||otherpattern 15 | return; 16 | end 17 | % actrec + simassist_usermacro(cmdstr); 18 | fun_arg = regexp(optstr, ',|\s', 'split'); 19 | if exist(fun_arg{1}, 'file') 20 | if numel(fun_arg)>1 21 | arglist = sprintf('''%s'',',fun_arg{2:end}); arglist(end)=''; 22 | evalin('base', sprintf('%s(%s);', fun_arg{1}, arglist)); 23 | else 24 | evalin('base', fun_arg{1}); 25 | end 26 | success = true; 27 | end 28 | end -------------------------------------------------------------------------------- /@saLine/PropagateUpstreamString.m: -------------------------------------------------------------------------------- 1 | function actrec = PropagateUpstreamString(obj, lnhdl) 2 | actrec = saRecorder; 3 | hsrcblk=get_param(lnhdl,'SrcBlockHandle'); 4 | hsrcpt=get_param(lnhdl,'SrcPortHandle'); 5 | if hsrcblk<0 6 | return; 7 | elseif ismember(get_param(hsrcblk,'BlockType'),{'Inport','SubSystem'})%Try signal propagate first 8 | actrec.SetParam(lnhdl,'Name',''); 9 | try 10 | actrec.SetParam(hsrcpt,'ShowPropagatedSignals','on'); 11 | if isempty(get_param(hsrcpt,'PropagatedSignals')) 12 | actrec.SetParam(hsrcpt,'ShowPropagatedSignals','off'); 13 | name_got=obj.Console.GetUpstreamString(hsrcpt); 14 | actrec.SetParam(lnhdl,'Name',name_got); 15 | end 16 | catch 17 | name_got=obj.Console.GetUpstreamString(hsrcpt); 18 | actrec.SetParam(lnhdl,'Name',name_got); 19 | end 20 | else 21 | name_got=obj.Console.GetUpstreamString(hsrcpt); 22 | actrec.SetParam(lnhdl,'Name',name_got); 23 | end 24 | end -------------------------------------------------------------------------------- /@saRecorder/AddLine_LineToNoSrcLine.m: -------------------------------------------------------------------------------- 1 | function AddLine_LineToNoSrcLine(obj, srchdl, dsthdl, overlap_offset) 2 | % srchdl : line handle (connected) 3 | % dsthdl : line handle with source disconnected 4 | if nargin<4 5 | overlap_offset = [0, 0]; 6 | end 7 | dstpos = get_param(dsthdl,'Points'); 8 | points_layout = saLineRouteLineToDst(srchdl, dstpos(1,:), overlap_offset); 9 | parsys = get_param(srchdl,'Parent'); 10 | % backup line info to restore change of state after add_line 11 | lnname = regexprep(get_param(srchdl, 'Name'), '[<>]', ''); 12 | srcpt = get_param(srchdl,'SrcPortHandle'); 13 | if srcpt>0 14 | resolveflg = get_param(srcpt,'MustResolveToSignalObject'); 15 | else 16 | resolveflg = 'off'; 17 | end 18 | % add line 19 | obj.AddLine(parsys, round(points_layout)); 20 | % restore line state 21 | if ~isempty(lnname) 22 | set_param(newln, 'Name', lnname); 23 | if srcpt>0 24 | set_param(srcpt,'MustResolveToSignalObject',resolveflg); 25 | end 26 | end 27 | 28 | end -------------------------------------------------------------------------------- /@saAction/add_line.m: -------------------------------------------------------------------------------- 1 | function add_line(obj, sys, varargin) 2 | % varargin: {points, name} or 3 | % {srcport, dstport, name} 4 | if isempty(sys) 5 | sys = gcs; 6 | end 7 | name = ''; 8 | if size(varargin{1}, 2)==2 %given points format 9 | lnpos = varargin{1}; 10 | lnhdl=add_line(sys,lnpos); 11 | if numel(varargin)>1 12 | name = varargin{2}; 13 | end 14 | try % in cases for blocks that outport line cannot be renamed like BusSelector, etc. 15 | set_param(lnhdl,'Name',name); 16 | end 17 | else 18 | [pt1,pt2] = deal(varargin{1:2}); 19 | lnhdl=add_line(sys,pt1,pt2,'autorouting','on'); 20 | lnpos=get_param(lnhdl,'Points'); 21 | if numel(varargin)>2 22 | name = varargin{3}; 23 | end 24 | try % in cases for blocks that outport line cannot be renamed like BusSelector, etc. 25 | set_param(lnhdl,'Name',name); 26 | end 27 | end 28 | obj.Property = {'Name',name}; 29 | obj.Data.System = sys; 30 | obj.Data.Points = lnpos; 31 | obj.Handle = lnhdl; 32 | end -------------------------------------------------------------------------------- /@saCmdParser/ParseValuesAndInteger.m: -------------------------------------------------------------------------------- 1 | function [result, bclean] = ParseValuesAndInteger(obj) 2 | % float numbers will also be considered as string, e.g., 1e-3, 12.345, etc. 3 | 4 | % find isolated integers, i.e., not trailing "." ,"-" or letters, and not 5 | % preceding ".", and not in bracket (part of sequence expression) 6 | numpattern = '(?0 9 | lnpoints=get_param(ln,'Points'); 10 | dy_right=[dy_right;lnpoints(end,2)-lnpoints(1,2)]; 11 | end 12 | end 13 | for j=1:numel(pts.Inports) 14 | ln=get_param(pts.Inports(j),'Line'); 15 | if ln>0 16 | lnpoints=get_param(ln,'Points'); 17 | dy_left=[dy_left;lnpoints(1,2)-lnpoints(end,2)]; 18 | end 19 | end 20 | if (all(dy_right>0)||isempty(dy_right))&&(all(dy_left>0)||isempty(dy_left)) 21 | dy=min([dy_right;dy_left]); 22 | elseif (all(dy_right<0)||isempty(dy_right))&&(all(dy_left<0)||isempty(dy_left)) 23 | dy=max([dy_right;dy_left]); 24 | else 25 | dy=0; 26 | end 27 | if dy~=0 28 | actrec.Merge(objs(i).Move([0,dy])); 29 | end 30 | end 31 | end -------------------------------------------------------------------------------- /saLayoutAroundBlock.m: -------------------------------------------------------------------------------- 1 | function actrec=saLayoutAroundBlock(tgtblk) 2 | actrec=saRecorder; 3 | adjblks=GetAdjBlks(tgtblk); 4 | BGleft=saBlockGroup;BGright=saBlockGroup;BigBG=saBlockGroup(tgtblk); 5 | for i=1:numel(adjblks.SrcBlockHandles) 6 | BGleft(i)=saBlockGroup(saGetBlockClosure(adjblks.SrcBlockHandles(i),'left')); 7 | end 8 | for i=1:numel(adjblks.DstBlockHandles) 9 | BGright(i)=saBlockGroup(saGetBlockClosure(adjblks.DstBlockHandles(i),'right')); 10 | end 11 | if ~isempty(BGleft) 12 | actrec.Merge(BGleft.AlignPortsInside); 13 | actrec.Merge(BGleft.StraightenLinesInside); 14 | actrec.Merge(BGleft.AlignPortsOutside); 15 | actrec.Merge(BGleft.BGArrayUnion.VerticalAlign); 16 | BigBG=BigBG+BGleft.BGArrayUnion; 17 | end 18 | if ~isempty(BGright) 19 | actrec.Merge(BGright.AlignPortsInside); 20 | actrec.Merge(BGright.StraightenLinesInside); 21 | actrec.Merge(BGright.AlignPortsOutside); 22 | actrec.Merge(BGright.BGArrayUnion.VerticalAlign); 23 | BigBG=BigBG+BGright.BGArrayUnion; 24 | end 25 | actrec.Merge(BigBG.StraightenLinesInside); -------------------------------------------------------------------------------- /@saConsole/BuildMacros.m: -------------------------------------------------------------------------------- 1 | function varargout = BuildMacros(obj) 2 | pold = pwd; 3 | 4 | p = mfilename('fullpath'); 5 | sepidx = strfind(p, filesep); 6 | regfolder = [p(1:sepidx(end-1)), '_MacroRegistration']; 7 | fs = what(regfolder); 8 | regfs = [fs.m, fs.p]; 9 | regfs = regexprep(regfs, '\.(m|p)$',''); 10 | cd(regfolder); 11 | macros_tmp = obj.Macros; 12 | for i=1:numel(regfs) 13 | regobjs = eval(regfs{i}); 14 | macros_tmp = [macros_tmp; regobjs]; 15 | end 16 | 17 | %remove empty patterns 18 | idx = cellfun('isempty',{macros_tmp.Pattern}'); 19 | macros_tmp = macros_tmp(~idx); 20 | %sort by priority 21 | [tmp, iprio] = sort([macros_tmp.Priority]); 22 | macros_tmp = macros_tmp(iprio); 23 | 24 | obj.Macros = macros_tmp; 25 | [obj.Macros.Console] = deal(obj); 26 | % buffer prompt list 27 | prmpts = {obj.Macros.PromptMethod}; 28 | prmpts = prmpts(~cellfun('isempty', prmpts)); 29 | idxfun = cellfun(@(c)isa(c,'function_handle'), prmpts); 30 | obj.PromptBuffer.String = unique([{},prmpts{~idxfun}]); 31 | obj.PromptBuffer.FunctionHandle = prmpts(idxfun); 32 | % 33 | cd(pold); 34 | end -------------------------------------------------------------------------------- /@saRecorder/AddLine_LineToPort.m: -------------------------------------------------------------------------------- 1 | function AddLine_LineToPort(obj, srchdl, dsthdl, overlap_offset) 2 | % srchdl : line handle (connected) 3 | % dsthdl : inport 4 | if nargin<4 5 | overlap_offset = [0, 0]; 6 | end 7 | dstpos = get_param(dsthdl,'Position'); 8 | % offset by -10 to create horizontal segment before inport, 9 | % in future the offset may be calculated dynamically 10 | points_layout = saLineRouteLineToDst(srchdl, dstpos, [overlap_offset+[-10,0]]); 11 | parsys = get_param(srchdl,'Parent'); 12 | % backup line info to restore change of state after add_line 13 | lnname = regexprep(get_param(srchdl, 'Name'), '[<>]', ''); 14 | srcpt = get_param(srchdl,'SrcPortHandle'); 15 | if srcpt>0 16 | resolveflg = get_param(srcpt,'MustResolveToSignalObject'); 17 | else 18 | resolveflg = 'off'; 19 | end 20 | % add line 21 | newln = obj.AddLine(parsys, round(points_layout)); 22 | % restore line state 23 | if ~isempty(lnname) 24 | set_param(newln, 'Name', lnname); 25 | if srcpt>0 26 | set_param(srcpt,'MustResolveToSignalObject',resolveflg); 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /_BlockRegistration/regprotoblock_siltest.m: -------------------------------------------------------------------------------- 1 | function sabt = regprotoblock_siltest 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saProtoBlock('ricardo_siltest'); 6 | sabt.ProtoCheckMethod = @check_proto; 7 | sabt.ProtoProperty = {'MajorProperty', 'InportStringMethod', 'OutportStringMethod',... 8 | 'PropagateUpstreamStringMethod', 'PropagateDownstreamStringMethod'}; 9 | 10 | sabt.MajorProperty = 'varname'; 11 | 12 | sabt.InportStringMethod = 'varname'; 13 | sabt.OutportStringMethod = 'varname'; 14 | sabt.PropagateUpstreamStringMethod = @set_string; 15 | sabt.PropagateDownstreamStringMethod = @set_string; 16 | end 17 | 18 | function tf = check_proto(blkhdl) 19 | msktyp = get_param(blkhdl, 'MaskType'); 20 | if ~isempty(regexp(msktyp,'^Test\s', 'once')) 21 | tf = true; 22 | else 23 | tf = false; 24 | end 25 | end 26 | 27 | 28 | function actrec = set_string(blkhdl, str) 29 | actrec = saRecorder; 30 | objparas = get_param(blkhdl, 'ObjectParameters'); 31 | if isfield(objparas, 'varname') 32 | actrec.SetParam(blkhdl, 'varname', str); 33 | end 34 | end -------------------------------------------------------------------------------- /@saProtoBlock/Adapt.m: -------------------------------------------------------------------------------- 1 | function actrec = Adapt(obj, blkhdl, option) 2 | actrec = saRecorder; 3 | if nargin<3 4 | console = obj.Console; 5 | if ~isempty(console) 6 | option = console.RunOption; 7 | else 8 | return; 9 | end 10 | end 11 | if option.AutoSize && ~isempty(obj.AutoSizeMethod) 12 | actrec.Merge(obj.AutoSize(blkhdl)); 13 | end 14 | if option.Color && ~isempty(obj.ColorMethod) 15 | actrec.Merge(obj.Color(blkhdl)); 16 | end 17 | if option.Annotation && ~isempty(obj.AnnotationMethod) 18 | actrec.Merge(obj.Annotate(blkhdl)); 19 | end 20 | if option.Refine && ~isempty(obj.RefineMethod) 21 | actrec.Merge(obj.Refine(blkhdl)); 22 | end 23 | % note that SetDataType method uses SetParamHighlight, it shall be last executed 24 | if ~isempty(obj.Console) && isfield(obj.Console.SessionPara, 'DataType') && ~isempty(obj.Console.SessionPara.DataType) 25 | actrec.Merge(obj.SetDataType(blkhdl, obj.Console.SessionPara.DataType)); 26 | elseif option.AutoDataType && ~isempty(obj.DataTypeMethod) 27 | actrec.Merge(obj.SetDataType(blkhdl)); 28 | else 29 | end 30 | end -------------------------------------------------------------------------------- /@saRecorder/private/sa_get_bind_block.m: -------------------------------------------------------------------------------- 1 | function bindblks = sa_get_bind_block(lnhdl, direction) 2 | if nargin<2 3 | direction = 'downstream' 4 | end 5 | bindblks = []; 6 | switch direction 7 | case 'downstream' 8 | dstblks = get_param(lnhdl, 'DstBlockHandle'); 9 | dstpts = get_param(lnhdl, 'DstPortHandle'); 10 | dstpts(dstpts<0) = []; 11 | childptlns = get_param(dstpts, 'Line'); 12 | for i=1:numel(dstblks) 13 | if dstblks(i)<0 continue; end 14 | dstblklns = get_param(dstblks(i), 'LineHandles'); 15 | inlns = dstblklns.Inport(dstblklns.Inport>0); 16 | if isempty(setdiff(inlns, childptlns)) 17 | bindblks = [bindblks; dstblks(i)]; 18 | end 19 | end 20 | case 'upstream' 21 | srcblk = get_param(lnhdl, 'SrcBlockHandle'); 22 | if srcblk<0 return; end 23 | srcblklns = get_param(srcblk, 'LineHandles'); 24 | if ~any(srcblklns.Outport>0 & srcblklns.Outport~=lnhdl) 25 | bindblks = srcblk; 26 | end 27 | otherwise 28 | end 29 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_merge.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_merge 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Merge'); 6 | sabt.RoutineMethod = 'dynamicinport'; 7 | sabt.RoutinePattern = '^(mg|merge)'; 8 | sabt.RoutinePara.InportProperty = 'Inputs'; 9 | 10 | sabt.InportStringMethod = @inport_string; 11 | sabt.OutportStringMethod = 1; % use name from inport 1 12 | 13 | 14 | sabt.ArrangePortMethod{1} = 1; 15 | 16 | sabt.MajorProperty = 'Inputs'; 17 | 18 | sabt.BlockSize = [25, 70]; 19 | sabt.AutoSizeMethod = -1; 20 | sabt.DataTypeMethod = []; 21 | 22 | 23 | sabt.LayoutSize.PortSpacing = 35; 24 | sabt.LayoutSize.ToLineOffset = [50 100]; 25 | 26 | parbt = regblock_buscreator; 27 | sabt.Inherit(parbt, 'PlusMethod', 'MinusMethod', 'CleanMethod'); 28 | 29 | end 30 | 31 | function str = inport_string(hdl, appdata) 32 | parblk = get_param(hdl, 'Parent'); 33 | parpts = get_param(parblk, 'PortHandles'); 34 | ptnum = get_param(hdl, 'PortNumber'); 35 | outstr = appdata.Console.GetDownstreamString(parpts.Outport); 36 | str = [outstr, '_In', int2str(ptnum)]; 37 | end 38 | -------------------------------------------------------------------------------- /@saProtoBlock/private/override_option.m: -------------------------------------------------------------------------------- 1 | function [option, args, optarg] = override_option(args, btobj, local_opt) 2 | % Precondition: if exists, the first structure argument in cell array "args" is option 3 | % The option is in the following priority: 4 | % 1. Externally passed in option argument (as above) 5 | % 2. User specified console.SessionPara 6 | % 3. Prefered option for this specific block 7 | % 4. Local default inside the function 8 | % 5. Default console.RunOption 9 | 10 | 11 | % local option 12 | if nargin<3 13 | local_opt = []; 14 | end 15 | % external argument option 16 | i_optarg = find(cellfun(@isstruct, args), 1); 17 | if ~isempty(i_optarg) 18 | optarg = args{i_optarg}; 19 | args(i_optarg) = []; 20 | else 21 | optarg = []; 22 | end 23 | % 24 | blkprefer = btobj.BlockPreferOption; 25 | if ~isempty(btobj.Console) 26 | consoledefault = btobj.Console.RunOption; 27 | sessionpara = btobj.Console.SessionPara; 28 | else 29 | consoledefault = []; 30 | sessionpara = []; 31 | end 32 | option = saOverrideOption(optarg, sessionpara, blkprefer, local_opt, consoledefault); 33 | end -------------------------------------------------------------------------------- /@saLine/saLine.m: -------------------------------------------------------------------------------- 1 | classdef saLine < saObject 2 | %SA_SLBLOCK Summary of this class goes here 3 | % Detailed explanation goes here 4 | 5 | properties 6 | MajorProperty = 'Name'; 7 | 8 | OutportStringMethod = 'Name'; 9 | InportStringMethod = 'Name'; 10 | 11 | SetPropertyMethod = 'Name'; 12 | 13 | end 14 | 15 | properties (Constant) 16 | Dictionary = SACFG_DICTIONARY; 17 | end 18 | 19 | methods 20 | function obj = saLine(varargin) 21 | obj = obj@saObject('line'); 22 | obj.MapKey = 'line'; 23 | end 24 | 25 | % function lnhdls = RemoveChildren(obj,lnhdls) 26 | % lns = lnhdls(strcmp(get_param(lnhdls,'Type'),'line')); 27 | % lns_rmv = []; 28 | % for i=1:numel(lns) 29 | % if ismember(get_param(lns(i),'LineParent'), objs) 30 | % lns_rmv = [lns_rmv, lns(i)]; 31 | % end 32 | % end 33 | % lnhdls = setdiff(lnhdls, lns_rmv); 34 | % end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /@saConsole/saConsole.m: -------------------------------------------------------------------------------- 1 | classdef saConsole < handle 2 | %SA_OPERATIONCORE 3 | 4 | properties 5 | % All block regeistration info are collected in the following: 6 | ProtoBlocks % list array of saProtoBlock in order 7 | BlockMap = {} % map of saBlock 8 | 9 | % All macro regeistration info are collected in the following: 10 | Macros 11 | 12 | RunOption % if not specified, keep last value 13 | SessionPara = struct % always renewed on each run 14 | 15 | PromptBuffer = struct 16 | 17 | Newer 18 | end 19 | 20 | methods 21 | function obj = saConsole(varargin) 22 | obj.RunOption = struct(... 23 | 'Color', false, ... 24 | 'Annotation', false, ... 25 | 'AutoDataType', false, ... 26 | 'AutoSize', true, ... 27 | 'Refine', false, ... 28 | 'PropagateString', false, ... 29 | 'DataType', '',... 30 | 'GetMarginByMouse',true); 31 | end 32 | 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /_BlockRegistration/regblock_datastoreread.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_datastoreread 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('DataStoreRead'); 6 | 7 | % routines for DataStore family are combined as a seperate macro, see macro 8 | % registration file 9 | sabt.RoutinePattern = ''; 10 | 11 | %bro-block properties 12 | sabt.BroBlockType = {'DataStoreWrite', 'DataStoreMemory'}; 13 | sabt.CreateBroBlockMethod = -1; 14 | sabt.ConnectPort = [0, 1]; 15 | 16 | sabt.MajorProperty = 'DataStoreName'; 17 | sabt.DictRenameMethod = 1; % use major property 18 | 19 | sabt.PropagateDownstreamStringMethod = 'DataStoreName'; 20 | sabt.OutportStringMethod = 'DataStoreName'; 21 | sabt.RefineMethod = @refine_method; 22 | 23 | 24 | sabt.BlockSize = [100, 30]; 25 | sabt.LayoutSize.CharWidth = 6; 26 | 27 | sabt.AutoSizeMethod = -2; % leftwards expand to show string 28 | 29 | sabt.GetBroMethod = @saFindBroBlocks; 30 | end 31 | 32 | 33 | function actrec = refine_method(blkhdl) 34 | actrec = saRecorder; 35 | nam = get_param(blkhdl, 'DataStoreName'); 36 | actrec.SetParam(blkhdl, 'Name', [nam, '_DSRead']); 37 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_prelookup.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_prelookup 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('PreLookup'); 6 | sabt.RoutineMethod = 'majorprop_str_num'; 7 | sabt.RoutinePattern = '^(pl|prelookup)'; 8 | 9 | 10 | sabt.ConnectPort = [1, 0]; 11 | 12 | sabt.MajorProperty = 'BreakpointsData'; 13 | sabt.DictRenameMethod = {'BreakpointsData'}; 14 | sabt.DefaultParameters = {... 15 | 'AttributesFormatString',sprintf('%%\n%%'),... 16 | 'BeginIndexSearchUsingPreviousIndexResult','on',... 17 | 'ProcessOutOfRangeInput','Clip to range'}; 18 | 19 | sabt.PropagateUpstreamStringMethod = 'BreakpointsData'; 20 | sabt.OutportStringMethod = @outport_string; 21 | sabt.AnnotationMethod = sprintf('%%\n%%'); 22 | 23 | sabt.BlockSize = [80, 40]; 24 | end 25 | 26 | 27 | function outstr = outport_string(pthdl) 28 | parblk = get_param(pthdl, 'Parent'); 29 | ptnum = get_param(pthdl, 'PortNumber'); 30 | suffix = {'_k','_f'}; 31 | bpname = get_param(parblk, 'BreakpointsData'); 32 | outstr = [bpname, suffix{ptnum}]; 33 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SimAssist 2 | 3 | ## Email: 4 | jiangxinauto@163.com, xingxing993@gmail.com 5 | 6 | ## Guidelines and tutorials 7 | 8 | **[An online guideline on Youdao Note](https://note.youdao.com/s/Hfy8Df83)** 9 | > _May be later I'll transfer it to markdown here_ 10 | 11 | **[Video Tutorial](http://list.youku.com/albumlist/show?id=27863410&ascending=1&page=1)** 12 | 13 | Other tools open sourced (to be added in the future): 14 | - [Simport](https://github.com/xingxing993/Simport) 15 | - [CoROS](https://github.com/xingxing993/CoROS) 16 | - [DDTools](https://github.com/xingxing993/DDTools) 17 | 18 | ------------------------- 19 | 20 | **Some guide for developers interested:** 21 | 22 | - The folder "_BlockRegistration" contains files that define block behaviour, you can add your own block by adding another block file. The existing ones can be used as reference. Basically you have to define some attributes and callback functions for different scenarios. 23 | 24 | - The folder "_MacroRegistration" contains files that define macro scripts, you can add your own macro scripts here and then it can be called from SimAssist command shortcut. 25 | 26 | -------------------------------------------------------------------------------- /_BlockRegistration/regblock_minmax.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_minmax 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('MinMax'); 6 | sabt.RoutinePattern = '^mn|mx|min|max'; 7 | sabt.RoutineMethod = @routine_minmax; 8 | sabt.RoutinePara.InportProperty = 'Inputs'; 9 | 10 | sabt.MajorProperty = 'Function'; 11 | sabt.ArrangePortMethod{1} = 1; 12 | sabt.RollPropertyMethod = -1; 13 | sabt.DataTypeMethod = []; 14 | 15 | 16 | btlogic = regblock_logic; 17 | sabt.Inherit(btlogic,... 18 | 'BlockSize', 'AutoSizeMethod', 'LayoutSize', 'PlusMethod', 'MinusMethod','CleanMethod'); 19 | 20 | end 21 | 22 | 23 | function [actrec, success] = routine_minmax(cmdstr, console) 24 | actrec=saRecorder;success = false; 25 | btobj = console.MapTo('MinMax'); 26 | cmdpsr = saCmdParser(cmdstr, btobj.RoutinePattern); 27 | 28 | switch cmdpsr.PatternStr 29 | case {'mn','min'} 30 | opsym = 'Min'; 31 | case {'mx','max'} 32 | opsym = 'Max'; 33 | end 34 | 35 | pvpair = {'Function', opsym}; 36 | actrec = Routines.dynamicinport(btobj, cmdpsr.OptionStr, '', ... 37 | 'Function', opsym); 38 | success = true; 39 | end -------------------------------------------------------------------------------- /@saRecorder/AddBlock.m: -------------------------------------------------------------------------------- 1 | function block = AddBlock(obj,varargin) 2 | % varargin: {option, src, dst, prop1, val1, ...} 3 | % parse argument 4 | N = struct('flg',false,'extra',''); %-n/N: Hide/Show Name 5 | S = struct('flg',true,'extra',''); %-s/S: Selected Off/On 6 | D = struct('flg',false,'extra',''); %-d/D: Prefix with gcs/Use full path as destination 7 | optstr = varargin{1}; 8 | opts = regexp(optstr,'\-([a-zA-Z])(\w*)','tokens'); 9 | for i=1:numel(opts) 10 | tmp=struct('flg',logical(opts{i}{1}-lower(opts{i}{1})),'extra',opts{i}{2}); 11 | eval([upper(opts{i}{1}),'=tmp;']); % override 12 | end 13 | src = varargin{2}; 14 | if D.flg 15 | dst = varargin{3}; 16 | else 17 | dst = [gcs, '/', varargin{3}]; 18 | end 19 | if isempty(strfind(src, '/')) 20 | src = ['built-in/', src]; 21 | end 22 | prop=varargin(4:end); 23 | if S.flg 24 | prop=[prop,{'Selected','on'}]; 25 | else 26 | prop=[prop,{'Selected','off'}]; 27 | end 28 | if N.flg 29 | prop=[prop,{'ShowName','on'}]; 30 | else 31 | prop=[prop,{'ShowName','off'}]; 32 | end 33 | sa = saAction('add_block', src, dst, prop{:}); 34 | obj.PushItem(sa); 35 | block = sa.Handle; 36 | end -------------------------------------------------------------------------------- /@saProtoBlock/Grounds.m: -------------------------------------------------------------------------------- 1 | function actrec = Grounds(obj, hdls, varargin) 2 | actrec = saRecorder; 3 | total = numel(hdls); 4 | if total>obj.ShowWaitbarThreshold 5 | hwtbar=waitbar(0,sprintf('Adding <%s> block to ...',obj.BlockType)); 6 | end 7 | for i=1:numel(hdls) 8 | if total>obj.ShowWaitbarThreshold 9 | waitbar(i/total,hwtbar,sprintf('Adding <%s> block to %s...',obj.BlockType,strrep(getfullname(hdls(i)),'_','\_'))); 10 | end 11 | 12 | if strcmp(get_param(hdls(i), 'Type'), 'line') 13 | actrec + obj.AddBlockToLine(hdls(i),varargin{:}); 14 | elseif strcmp(get_param(hdls(i), 'Type'), 'port') 15 | if get_param(hdls(i),'Line')<0 16 | actrec + obj.AddBlockToPort(hdls(i),varargin{:}); 17 | end 18 | elseif strcmp(get_param(hdls(i), 'Type'), 'block') 19 | pts = get_param(hdls(i),'PortHandles'); 20 | for k=1:numel(pts.Inport) 21 | if get_param(pts.Inport(k),'Line')<0 22 | actrec + obj.AddBlockToPort(pts.Inport(k),varargin{:}); 23 | end 24 | end 25 | end 26 | end 27 | if total>obj.ShowWaitbarThreshold 28 | close(hwtbar); 29 | end 30 | end -------------------------------------------------------------------------------- /@saProtoBlock/SetProperty.m: -------------------------------------------------------------------------------- 1 | function actrec = SetProperty(obj, blkhdl, propval, nthprop) 2 | 3 | if nargin<4 4 | nthprop = 1; 5 | end 6 | 7 | actrec = saRecorder; 8 | 9 | setpropmethod = obj.SetPropertyMethod; 10 | if isa(setpropmethod, 'function_handle') 11 | nn = nargout(setpropmethod); 12 | if nn~=0 %if mandatory output exist, must be saRecorder 13 | actrec.Merge(setpropmethod(blkhdl, propval)); 14 | else 15 | setpropmethod(blkhdl, propval); 16 | end 17 | elseif isequal(setpropmethod, -1) 18 | dynmajprop = obj.GetMajorProperty(blkhdl); 19 | if ~isempty(dynmajprop) && nthprop==1 20 | actrec.SetParamHighlight(blkhdl, dynmajprop, propval); 21 | elseif ~isempty(obj.PropertyList) 22 | actrec.SetParamHighlight(blkhdl, obj.PropertyList{min(nthprop,end)}, propval); 23 | else 24 | dlgpstru = get_param(blkhdl,'DialogParameters'); 25 | if isstruct(dlgpstru) 26 | dlgp = fieldnames(dlgpstru); 27 | if ~isempty(dlgp) 28 | actrec.SetParamHighlight(blkhdl, dlgp{min(nthprop, end)}, propval); 29 | end 30 | end 31 | end 32 | end 33 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_annotation.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_annotation 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('script_annotation'); 6 | sam.Pattern = '^anno'; 7 | sam.Callback = @script_annotation; 8 | 9 | end 10 | 11 | function [actrec, success] =script_annotation(cmdstr, console) 12 | actrec=saRecorder;success = false; 13 | optstr = strtrim(regexprep(cmdstr,'^anno\s*','', 'once')); 14 | tgtobjs= saFindSystem(gcs, 'block'); 15 | if isempty(optstr) 16 | for i=1:numel(tgtobjs) 17 | actrec + console.MapTo(tgtobjs(i)).Annotate(tgtobjs(i)); 18 | end 19 | else %customize annotation 20 | for i=1:numel(tgtobjs) 21 | if strcmp(optstr, '-') 22 | actrec.SetParam(tgtobjs(i),'AttributesFormatString',''); 23 | elseif strncmp(optstr,'+',1) 24 | oldanno = get_param(tgtobjs(i),'AttributesFormatString'); 25 | actrec.SetParam(tgtobjs(i),'AttributesFormatString',[oldanno, optstr(2:end)]); 26 | else 27 | actrec.SetParam(tgtobjs(i),'AttributesFormatString',optstr); 28 | end 29 | end 30 | end 31 | success = true; 32 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_deadzone.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_deadzone 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('DeadZone'); 6 | 7 | sabt.RoutineMethod = 'multiprop'; 8 | sabt.RoutinePattern = '^(dzone|dz|deadzone)'; 9 | 10 | sabt.MajorProperty = {'LowerValue', '_Lb';'UpperValue','_Ub'}; 11 | sabt.DictRenameMethod = {'UpperValue','LowerValue'}; 12 | 13 | sabt.PropagateUpstreamStringMethod = @set_string; 14 | sabt.PropagateDownstreamStringMethod = @set_string; 15 | sabt.InportStringMethod = @inport_string; 16 | 17 | sabt.BlockPreferOption.Annotation = true; 18 | sabt.AnnotationMethod = 'DeadZone: % - %'; 19 | end 20 | 21 | 22 | function thestr = inport_string(pthdl, appdata) 23 | ptnum = get_param(pthdl, 'PortNumber'); 24 | parblk = get_param(pthdl, 'Parent'); 25 | parpts = get_param(parblk, 'PortHandles'); 26 | outstr = appdata.Console.GetDownstreamString(parpts.Outport); 27 | thestr = [outstr, 'Raw']; 28 | end 29 | 30 | function actrec = set_string(blkhdl, instr) 31 | actrec = saRecorder; 32 | actrec.SetParam(blkhdl, 'UpperValue', [instr, '_Ub']); 33 | actrec.SetParam(blkhdl, 'LowerValue', [instr, '_Lb']); 34 | end -------------------------------------------------------------------------------- /@saProtoBlock/PropagateDownstreamString.m: -------------------------------------------------------------------------------- 1 | function actrec = PropagateDownstreamString(obj, blkhdl) 2 | actrec = saRecorder; 3 | down_prpg_method = obj.PropagateDownstreamStringMethod; 4 | if isempty(down_prpg_method) 5 | return; 6 | end 7 | 8 | console = obj.Console; 9 | if isstruct(down_prpg_method) % struct: StringPortNum, Method 10 | pts = get_param(blkhdl, 'PortHandles'); 11 | blkostr = console.GetDownstreamString(pts.Outport(down_prpg_method.StringPortNum)); 12 | down_prpg_method = down_prpg_method.Method; 13 | else 14 | blkostr = console.GetDownstreamString(blkhdl); 15 | end 16 | 17 | if isa(down_prpg_method, 'function_handle') 18 | nn = nargout(down_prpg_method); 19 | ni = nargin(down_prpg_method); 20 | argsin = {blkhdl, blkostr}; 21 | if nn~=0 %if mandatory output exist, must be saRecorder 22 | actrec.Merge(down_prpg_method(argsin{1:ni})); 23 | else 24 | down_prpg_method(argsin{1:ni}); 25 | end 26 | elseif isstr(down_prpg_method) && ~isempty(blkostr) 27 | if iscell(blkostr) 28 | blkostr = blkostr{1}; 29 | end 30 | actrec.SetParam(blkhdl, down_prpg_method, blkostr); 31 | else 32 | end 33 | % actrec + obj.AutoSize(blkhdl); -------------------------------------------------------------------------------- /@saConsole/ImportBlockTypesExcel.m: -------------------------------------------------------------------------------- 1 | function [btobjs, macroobjs] = ImportBlockTypesExcel(obj) 2 | excel = actxGetRunningServer('excel.application'); 3 | sht = excel.ActiveSheet; 4 | rawtxt = sht.UsedRange.Value; 5 | btobjs = []; 6 | macroobjs = []; 7 | for i=2:size(rawtxt, 1) % start from 2nd row 8 | [sabt, sam] = create_saobject(rawtxt{i,:}); 9 | sabt.Console = obj; 10 | obj.Map(sabt.MapKey) = sabt; 11 | sam.Console = obj; 12 | btobjs = [btobjs; sabt]; 13 | macroobjs = [macroobjs; sam]; 14 | end 15 | [tmp, iprio] = sort([macroobjs.Priority]); 16 | macroobjs = macroobjs(iprio); 17 | obj.Macros = macroobjs; 18 | end 19 | 20 | 21 | function [sabt, sam] = create_saobject(varargin) 22 | [msktyp, pattern, srcpath, priority] = varargin{1:4}; 23 | dlgparas = get_param(srcpath, 'DialogParameters'); 24 | if ~isempty(dlgparas) 25 | dlgparas = fieldnames(dlgparas); 26 | else 27 | dlgparas={}; 28 | end 29 | blktyp = get_param(srcpath, 'BlockType'); 30 | % create saBlock object 31 | sabt = saBlock(blktyp, msktyp, srcpath); 32 | if ~isempty(dlgparas) 33 | sabt.MajorProperty = dlgparas{1}; 34 | end 35 | % create macro object 36 | sam = saMacroAdder(sabt, pattern); 37 | sam.Priority = priority; 38 | end 39 | -------------------------------------------------------------------------------- /_BlockRegistration/regblock_goto.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_goto 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Goto'); 6 | sabt.RoutineMethod = 'majorprop_str_num'; 7 | sabt.RoutinePattern = '^goto'; 8 | 9 | %bro-block properties 10 | sabt.BroBlockType = {'From', 'GotoTagVisibility'}; 11 | sabt.CreateBroBlockMethod = -1; 12 | sabt.ConnectPort = [1, 0]; 13 | 14 | sabt.MajorProperty = 'GotoTag'; 15 | sabt.DictRenameMethod = 1; % use major property 16 | 17 | sabt.PropagateDownstreamStringMethod = -1; 18 | sabt.PropagateUpstreamStringMethod = 'GotoTag'; 19 | sabt.InportStringMethod = 'GotoTag'; 20 | sabt.OutportStringMethod = -1; 21 | 22 | sabt.AnnotationMethod = 'Scope: %'; 23 | sabt.RefineMethod = @refine_method; 24 | sabt.ColorMethod = {-1, false}; 25 | 26 | sabt.BlockSize = [100, 14]; 27 | sabt.LayoutSize.CharWidth = 6; 28 | 29 | parobj = regblock_datastorewrite; 30 | sabt.Inherit(parobj, 'AutoSizeMethod'); 31 | 32 | sabt.GetBroMethod = @saFindBroBlocks; 33 | end 34 | 35 | function actrec = refine_method(blkhdl) 36 | actrec = saRecorder; 37 | tag = get_param(blkhdl, 'GotoTag'); 38 | newval=[tag,'_',get_param(blkhdl,'BlockType')]; 39 | actrec.SetParam(blkhdl, 'Name', newval); 40 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_datastorememory.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_datastorememory 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('DataStoreMemory'); 6 | 7 | % routines for DataStore family are combined as a seperate macro, see macro 8 | % registration file 9 | sabt.RoutinePattern = ''; 10 | 11 | %bro-block properties 12 | sabt.BroBlockType = {'DataStoreWrite', 'DataStoreRead'}; 13 | sabt.CreateBroBlockMethod = -1; 14 | sabt.ConnectPort = [0, 0]; 15 | 16 | sabt.MajorProperty = 'DataStoreName'; 17 | sabt.DictRenameMethod = 1; % use major property 18 | 19 | sabt.PropagateDownstreamStringMethod = 'DataStoreName'; 20 | sabt.OutportStringMethod = 'DataStoreName'; 21 | sabt.AnnotationMethod = 'DT: %'; 22 | sabt.RefineMethod = @refine_method; 23 | 24 | 25 | sabt.BlockSize = [100, 30]; 26 | sabt.LayoutSize.CharWidth = 6; 27 | 28 | % use the same sizing method with Constant 29 | parobj = regblock_constant; 30 | sabt.Inherit(parobj, 'AutoSizeMethod'); 31 | 32 | sabt.GetBroMethod = @saFindBroBlocks; 33 | end 34 | 35 | function actrec = refine_method(blkhdl) 36 | actrec = saRecorder; 37 | nam = get_param(blkhdl, 'DataStoreName'); 38 | actrec.SetParam(blkhdl, 'Name', [nam, '_DataStore']); 39 | end -------------------------------------------------------------------------------- /@saProtoBlock/DictRename.m: -------------------------------------------------------------------------------- 1 | function actrec = DictRename(obj, blkhdl) 2 | % 3 | actrec = saRecorder; 4 | 5 | if isempty(obj.DictRenameMethod) 6 | return; 7 | elseif isa(obj.DictRenameMethod, 'function_handle') 8 | dictrename_method = obj.DictRenameMethod; 9 | nn = nargout(dictrename_method); 10 | if nn~=0 %if mandatory output exist, must be saRecorder 11 | actrec.Merge(dictrename_method(blkhdl, obj.Dictionary)); 12 | else 13 | dictrename_method(blkhdl, obj.Dictionary); 14 | end 15 | else 16 | if isequal(obj.DictRenameMethod, 1) % set to 1 to use major property by default 17 | props = cellstr(obj.MajorProperty); 18 | elseif isequal(obj.DictRenameMethod, -1) % set to -1 to use auto generated string parameter list 19 | props = saGetStringDialogParameter(blkhdl); 20 | else 21 | props = cellstr(obj.DictRenameMethod); 22 | end 23 | objprops=get_param(blkhdl,'ObjectParameters'); 24 | for kk=1:numel(props) 25 | if isfield(objprops,props{kk}) 26 | valstr=get_param(blkhdl,props{kk}); 27 | newvalstr=saDictRenameString(valstr,obj.Dictionary); 28 | actrec.SetParam(blkhdl, props{kk}, newvalstr); 29 | end 30 | end 31 | end 32 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_from.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_from 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('From'); 6 | 7 | sabt.RoutineMethod = 'majorprop_str_num'; 8 | sabt.RoutinePattern = '^from'; 9 | 10 | %bro-block properties 11 | sabt.BroBlockType = {'Goto', 'GotoTagVisibility'}; 12 | sabt.CreateBroBlockMethod = -1; 13 | sabt.ConnectPort = [0, 1]; 14 | 15 | 16 | sabt.MajorProperty = 'GotoTag'; 17 | sabt.DictRenameMethod = 1; % use major property 18 | 19 | sabt.PropagateUpstreamStringMethod = -1; 20 | sabt.PropagateDownstreamStringMethod = 'GotoTag'; 21 | sabt.OutportStringMethod = 'GotoTag'; 22 | sabt.InportStringMethod = -1; 23 | 24 | sabt.RefineMethod = @refine_method; 25 | sabt.ColorMethod = {-1, false}; 26 | 27 | sabt.BlockSize = [100, 14]; 28 | sabt.LayoutSize.CharWidth = 6; 29 | 30 | sabt.AutoSizeMethod = -2; % leftwards expand to show string 31 | 32 | sabt.GetBroMethod = @saFindBroBlocks; 33 | end 34 | 35 | function actrec = refine_method(blkhdl) 36 | actrec = saRecorder; 37 | tag = get_param(blkhdl, 'GotoTag'); 38 | newval=[tag,'_',get_param(blkhdl,'BlockType')]; 39 | actrec.SetParamHighlight(blkhdl, 'Name', newval); 40 | end 41 | 42 | 43 | function broblks = get_bro_blocks(blkhdl) 44 | end -------------------------------------------------------------------------------- /@saAction/set_param.m: -------------------------------------------------------------------------------- 1 | function set_param(obj,varargin) 2 | if isstr(varargin{1}) 3 | obj.Handle = get_param(varargin{1},'Handle'); 4 | else 5 | obj.Handle = varargin{1}; 6 | end 7 | obj.Property = varargin{2}; 8 | obj.OldValue = get_param(varargin{1}, varargin{2}); 9 | obj.NewValue = varargin{3}; 10 | try 11 | set_param(varargin{1}, varargin{2}, varargin{3}); 12 | catch err 13 | act = 'retry'; 14 | switch err.identifier 15 | case {'Simulink:SL_DupBlockName', 'Simulink:blocks:DupBlockName'} 16 | parsys=get_param(obj.Handle,'Parent'); 17 | obj.NewValue = gen_unique_name(parsys, obj.NewValue); 18 | case 'Simulink:SL_LockViolation' 19 | unlock_library(obj.Handle); 20 | case {'Simulink:SL_LookupMismatchedParams','Simulink:SL_RowMismatch'} 21 | act = 'ignore'; 22 | case {'Simulink:SL_BlkParamEvalErr','Simulink:blocks:BusSelectorCantChangeSignalLabel'} 23 | act = 'ignore'; 24 | case {'Simulink:SL_InvGotoFromTagName', 'Simulink:blocks:InvGotoFromTagName'} 25 | obj.NewValue = genvarname(obj.NewValue); 26 | otherwise 27 | end 28 | if strcmp(act, 'retry') 29 | set_param(varargin{1}, varargin{2}, obj.NewValue); 30 | end 31 | end 32 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_colorit.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_colorit 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('script_colorit'); 6 | sam.Pattern = '^[bf]?color'; 7 | sam.PromptMethod = {'bcolor','color','fcolor','color=='}; 8 | sam.Callback = @script_colorit; 9 | sam.Priority = 19; 10 | end 11 | 12 | function [actrec, success] =script_colorit(cmdstr, console) 13 | actrec=saRecorder;success = false; 14 | rtsys = gcs; 15 | if cmdstr(1)=='b' 16 | bg = true; 17 | else 18 | bg = false; 19 | end 20 | optstr=strtrim(regexprep(cmdstr,'^[bf]?color\s*','','once')); 21 | if ismember(optstr, {'same','=', '=='}) 22 | optstr = mat2str(rand(1,3)); 23 | end 24 | tgtblks = saFindSystem(rtsys, 'block'); 25 | for i=1:numel(tgtblks) 26 | if isempty(optstr) 27 | rgb=mat2str(rand(1,3)); 28 | else 29 | rgb=optstr; 30 | end 31 | if bg 32 | rgb = {[], rgb}; 33 | end 34 | btobj = console.MapTo(tgtblks(i)); 35 | actrec + btobj.Color(tgtblks(i), rgb); 36 | broblks = btobj.GetBroBlocks(tgtblks(i)); 37 | for k=1:numel(broblks) 38 | brobtobj = console.MapTo(broblks(k)); 39 | actrec + brobtobj.Color(broblks(k), rgb); 40 | end 41 | end 42 | success = true; 43 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_majorprop.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_majorprop 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('setter_majorprop'); 6 | sam.Pattern = '^[\\]'; 7 | sam.Callback = @setter_majorprop; 8 | 9 | end 10 | 11 | 12 | function [actrec, success] =setter_majorprop(cmdstr, console) 13 | actrec=saRecorder;success = false; 14 | n=1; 15 | while cmdstr(n)=='\' 16 | n=n+1; %number of preceding \ 17 | end 18 | nthprop = n-1; 19 | if numel(cmdstr)0 % backup action: varargin should be {blkhdl} in this condition 3 | info.LayoutSize = obj.LayoutSize; 4 | % modify default port spacing 5 | ps = gcps(varargin{1}); 6 | if ps>0 7 | obj.LayoutSize.PortSpacing = ps; 8 | end 9 | varargout = {info}; 10 | else % restore action: varargin should be structure to be restored 11 | stru = varargin{1}; 12 | flds = fieldnames(stru); 13 | for i=1:numel(flds) 14 | obj.(flds{i}) = stru.(flds{i}); 15 | end 16 | end 17 | 18 | end 19 | 20 | 21 | function ps = gcps(blkhdl) % get current port spacing 22 | ptcnt = get_param(blkhdl, 'Ports'); 23 | lns = get_param(blkhdl, 'LineHandles'); 24 | blkpos = get_param(blkhdl, 'Position'); 25 | ht = blkpos(4)-blkpos(2); 26 | ps = 0; 27 | if ptcnt(1)==0 && ptcnt(2)==0 28 | elseif ptcnt(1)>ptcnt(2) 29 | if sum(lns.Inport>0)>1 30 | ps = ceil(ht/ptcnt(1)); 31 | end 32 | elseif ptcnt(1)0)>1 34 | ps = ceil(ht/ptcnt(2)); 35 | end 36 | else 37 | if sum(lns.Outport>0) > sum(lns.Inport>0) 38 | ps = ceil(ht/ptcnt(2)); 39 | else 40 | ps = ceil(ht/ptcnt(1)); 41 | end 42 | end 43 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_sfstrrep.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_sfstrrep 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('setter_strrep'); 6 | sam.Pattern = '^[^=].*>>.*'; 7 | sam.Callback = @setter_sfstrrep; 8 | sam.Priority = 2; 9 | 10 | end 11 | 12 | 13 | function [actrec, success] =setter_sfstrrep(cmdstr, console) 14 | actrec=saRecorder;success = false; 15 | regtmp = regexp(cmdstr, '^([^=].*)>>(.*)','once','tokens'); 16 | [oldstr, newstr] = regtmp{:}; 17 | sfobjs = sfgco; 18 | renameprops = {'Name', 'LabelString'}; 19 | for i=1:numel(sfobjs) 20 | for k=1:numel(renameprops) 21 | if sfobjs(i).isprop(renameprops{k}) 22 | if strcmp(oldstr, '^') % add prefix 23 | newpropstr = [newstr, sfobjs(i).(renameprops{k})]; 24 | elseif strcmp(oldstr, '$') % append suffix 25 | newpropstr = [sfobjs(i).(renameprops{k}), newstr]; 26 | else 27 | newpropstr = regexprep(sfobjs(i).(renameprops{k}), oldstr, newstr); 28 | end 29 | actrec.StateflowSetParam(sfobjs(i), renameprops{k}, newpropstr); 30 | end 31 | % break; % CAUTION: Temporary solution: 'Name', 'LabelString' always changes as binding pair 32 | end 33 | end 34 | success = true; 35 | end -------------------------------------------------------------------------------- /saGetBlockClosure.m: -------------------------------------------------------------------------------- 1 | function blkgrps=saGetBlockClosure(tgtblk,direction); 2 | if isstr(tgtblk) 3 | tgtblk=get_param(tgtblk,'Handle'); 4 | end 5 | blkgrps=tgtblk; 6 | adjblks=GetAdjBlks(tgtblk); 7 | if strcmpi(direction,'Left') 8 | adjblks=adjblks.SrcBlockHandles; 9 | else 10 | adjblks=adjblks.DstBlockHandles; 11 | end 12 | intactblks=adjblks(isintact(adjblks,direction)); 13 | for i=1:numel(intactblks) 14 | blkgrps=[blkgrps;saGetBlockClosure(intactblks(i),direction)]; 15 | end 16 | 17 | 18 | function bItct=isintact(blkhdls,direction) 19 | bItct=~boolean(blkhdls); 20 | for i=1:numel(blkhdls) 21 | adjblks=GetAdjBlks(blkhdls(i)); 22 | if strcmpi(direction,'Left') 23 | if numel(adjblks.DstBlockHandles)==1 24 | bItct(i)=boolean(1); 25 | elseif numel(adjblks.DstBlockHandles)==2 26 | if ismember('Goto',get_param(adjblks.DstBlockHandles,'BlockType')) 27 | bItct(i)=boolean(1); 28 | end 29 | end 30 | else 31 | if numel(adjblks.SrcBlockHandles)==1 32 | bItct(i)=boolean(1); 33 | elseif numel(adjblks.SrcBlockHandles)==2 34 | if ismember('From',get_param(adjblks.SrcBlockHandles,'BlockType')) 35 | bItct(i)=boolean(1); 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /+Routines/multiprop.m: -------------------------------------------------------------------------------- 1 | function [actrec, success] = multiprop(btobj, cmdstr, pattern, varargin) 2 | % btobj.MajorProperty = {'PROP1','_SUFFIX1'; 'PROP2','_SUFFIX2'; 'PROP3','_SUFFIX3'} 3 | % note that _SUFFIXN can be a function handle takes the basic string as input 4 | actrec = saRecorder; success = false; 5 | % parse input 6 | cmdpsr = saCmdParser(cmdstr, pattern); 7 | [vals, bclean] = cmdpsr.ParseMultiValues; % intended for no more that three values 8 | if ~bclean 9 | [actrec, success] = deal(saRecorder, false); return; 10 | end 11 | 12 | propdef = btobj.MajorProperty; 13 | pvpair = varargin; option = struct; 14 | if isempty(vals) 15 | elseif numel(vals)==1 16 | for i=1:size(propdef,1) 17 | if isstr(propdef{i,2}) 18 | pvpair = [pvpair, propdef{i,1}, strcat(vals{1}, propdef{i,2})]; 19 | else 20 | fh = propdef{i,2}; 21 | pvpair = [pvpair, propdef{i,1}, fh(vals{1})]; 22 | end 23 | end 24 | option.PropagateString = false; % turn off propagate behaviour to avoid override 25 | else 26 | for i=1:numel(vals) 27 | pvpair = [pvpair, propdef{i,1}, vals{i}]; 28 | end 29 | option.PropagateString = false; % turn off propagate behaviour to avoid override 30 | end 31 | actrec + btobj.GenericContextAdd(pvpair{:}, option); 32 | success = true; 33 | end -------------------------------------------------------------------------------- /@saProtoBlock/Align.m: -------------------------------------------------------------------------------- 1 | function actrec = Align(obj, blkhdl, direction) 2 | actrec = saRecorder; 3 | if nargin<3 4 | direction = '[]'; 5 | end 6 | if isempty(obj.AlignMethod) 7 | return; 8 | else 9 | if isequal(obj.AlignMethod, -1) 10 | actrec = layout_around_block(blkhdl, direction); 11 | elseif isa(obj.AlignMethod, 'function_handle') 12 | nn = nargout(obj.AlignMethod); 13 | ni = nargin(obj.AlignMethod); 14 | argsin = {blkhdl, obj.LayoutSize, obj}; 15 | if nn~=0 %if mandatory output exist, must be saRecorder 16 | actrec.Merge(obj.AlignMethod(argsin{1:ni})); 17 | else 18 | obj.AlignMethod(argsin{1:ni}); 19 | end 20 | else 21 | end 22 | end 23 | end 24 | 25 | function actrec = layout_around_block(blkhdl, direction) 26 | if nargin<2 27 | direction = '[]'; 28 | end 29 | actrec = saRecorder; 30 | lns = get_param(blkhdl, 'LineHandles'); 31 | if any(direction=='[') 32 | for i=1:numel(lns.Inport) 33 | if lns.Inport(i)>0 34 | actrec.NeatenLine(lns.Inport(i), 'd2s+'); 35 | end 36 | end 37 | end 38 | if any(direction==']') 39 | for i=1:numel(lns.Outport) 40 | if lns.Outport(i)>0 41 | actrec.NeatenLine(lns.Outport(i), 's2d+'); 42 | end 43 | end 44 | end 45 | end 46 | 47 | 48 | -------------------------------------------------------------------------------- /_BlockRegistration/regblock_saturate.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_saturate 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Saturate'); 6 | sabt.RoutineMethod = 'multiprop'; 7 | sabt.RoutinePattern = '^(saturate|sat)'; 8 | 9 | 10 | sabt.MajorProperty = {'LowerLimit','_Lo';'UpperLimit','_Hi'}; 11 | sabt.DictRenameMethod = {'UpperLimit','LowerLimit'}; 12 | 13 | sabt.PropagateUpstreamStringMethod = @set_string; 14 | sabt.PropagateDownstreamStringMethod = @set_string; 15 | sabt.InportStringMethod = @inport_string; 16 | sabt.AnnotationMethod = 'Limit: % - %'; 17 | 18 | sabt.BlockSize = [30, 30]; 19 | 20 | sabt.BlockPreferOption.Annotation = true; % turn on annotation for this block type 21 | 22 | sabt.DataTypeMethod = []; 23 | sabt.DefaultDataType = 'Inherit: Same as input'; 24 | 25 | end 26 | 27 | function thestr = inport_string(pthdl, appdata) 28 | ptnum = get_param(pthdl, 'PortNumber'); 29 | parblk = get_param(pthdl, 'Parent'); 30 | parpts = get_param(parblk, 'PortHandles'); 31 | outstr = appdata.Console.GetDownstreamString(parpts.Outport); 32 | thestr = [outstr, 'Raw']; 33 | end 34 | 35 | function actrec = set_string(blkhdl, instr) 36 | actrec = saRecorder; 37 | actrec.SetParam(blkhdl, 'UpperLimit', [instr, '_Hi']); 38 | actrec.SetParam(blkhdl, 'LowerLimit', [instr, '_Lo']); 39 | end -------------------------------------------------------------------------------- /@saAction/replace_block.m: -------------------------------------------------------------------------------- 1 | function replace_block(obj,varargin) 2 | obj.Data.Path = getfullname(varargin{1}); 3 | blktyp = get_param(varargin{1}, 'BlockType'); 4 | lnkst = get_param(varargin{1},'LinkStatus'); 5 | switch lnkst 6 | case 'none' 7 | obj.Data.OldBlockSrc = ['built-in/', blktyp]; 8 | case 'implicit' 9 | % Not available because support for modifying inside 10 | % library links is not implemented in this version 11 | case 'resolved' 12 | obj.Data.OldBlockSrc = get_param(varargin{1},'ReferenceBlock'); 13 | case 'inactive' 14 | obj.Data.OldBlockSrc = get_param(varargin{1},'AncestorBlock'); 15 | otherwise 16 | end 17 | obj.Data.NewBlockSrc = varargin{2}; 18 | dlgparastru = get_param(obj.Data.Path, 'DialogParameters'); 19 | if ~isempty(dlgparastru) 20 | dlgparas = fieldnames(dlgparastru)'; 21 | else 22 | dlgparas = {}; 23 | end 24 | dlgparas = [dlgparas, 'ShowName', 'AttributesFormatString']; 25 | paravals = cell(1, numel(dlgparas)); 26 | for i=1:numel(dlgparas) 27 | paravals{i} = get_param(obj.Data.Path, dlgparas{i}); 28 | end 29 | % action 30 | newblk = replace_block(obj.Data.Path, blktyp,obj.Data.NewBlockSrc, 'noprompt'); 31 | if iscell(newblk) 32 | newblk = newblk{1}; 33 | end 34 | obj.Handle = get_param(newblk, 'Handle'); 35 | obj.Property = [dlgparas; paravals]; 36 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_product.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_product 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Product'); 6 | 7 | parsabt = regblock_sum; 8 | sabt.Inherit(parsabt); 9 | 10 | sabt.RoutinePattern = '^[*/]+'; 11 | sabt.RoutineMethod = @routine_multiply_divide; 12 | 13 | end 14 | 15 | 16 | function [actrec, success] =routine_multiply_divide(cmdstr, console) 17 | actrec=saRecorder;success = false; 18 | btobj = console.MapTo('Product'); 19 | cmdpsr = saCmdParser(cmdstr, btobj.RoutinePattern); 20 | if numel(cmdpsr.PatternStr)==1 21 | operator = ['*', cmdpsr.PatternStr]; 22 | else 23 | operator = cmdpsr.PatternStr; 24 | end 25 | [operand, bclean] = cmdpsr.ParseSingleValue; 26 | if ~bclean [actrec, success]=deal(saRecorder, false); return; end 27 | 28 | [actrec2, block] = btobj.AddBlock('Inputs', operator); actrec.Merge(actrec2); 29 | if ~isempty(operand) %add 2nd operand 30 | btobjcnst = console.MapTo('Constant'); 31 | pts = get_param(block, 'PortHandles'); 32 | option.PropagateString = false; 33 | actrec + btobjcnst.AddBlockToPort(pts.Inport(2), option, 'Value', operand); 34 | else 35 | srchdls = saFindSystem(gcs,'line_sender'); 36 | if ~isempty(srchdls) 37 | actrec.MultiAutoLine(srchdls, block); 38 | end 39 | end 40 | success = true; 41 | end 42 | 43 | -------------------------------------------------------------------------------- /@saProtoBlock/PropagateUpstreamString.m: -------------------------------------------------------------------------------- 1 | function actrec = PropagateUpstreamString(obj, blkhdl) 2 | actrec = saRecorder; 3 | up_prpg_method = obj.PropagateUpstreamStringMethod; 4 | if isempty(up_prpg_method) 5 | return; 6 | end 7 | 8 | console = obj.Console; 9 | if isstruct(up_prpg_method) % struct: StringPortNum, Method 10 | pts = get_param(blkhdl, 'PortHandles'); 11 | if ischar(up_prpg_method.StringPortNum) % Trigger or Enable 12 | blkistr = console.GetUpstreamString(pts.(up_prpg_method.StringPortNum)); 13 | else 14 | blkistr = console.GetUpstreamString(pts.Inport(up_prpg_method.StringPortNum)); 15 | up_prpg_method = up_prpg_method.Method; 16 | end 17 | else 18 | blkistr = console.GetUpstreamString(blkhdl); 19 | end 20 | 21 | if isa(up_prpg_method, 'function_handle') 22 | nn = nargout(up_prpg_method); 23 | ni = nargin(up_prpg_method); 24 | argsin = {blkhdl, blkistr, console}; 25 | if nn~=0 %if mandatory output exist, must be saRecorder 26 | actrec.Merge(up_prpg_method(argsin{1:ni})); 27 | else 28 | up_prpg_method(argsin{1:ni}); 29 | end 30 | elseif isstr(up_prpg_method) && ~isempty(blkistr) 31 | if iscell(blkistr) 32 | blkistr = blkistr{1}; 33 | end 34 | actrec.SetParam(blkhdl, up_prpg_method, blkistr); 35 | else 36 | end 37 | % actrec + obj.AutoSize(blkhdl); -------------------------------------------------------------------------------- /@saBlockGroup/AlignPortsInside.m: -------------------------------------------------------------------------------- 1 | function actrec=AlignPortsInside(objs) 2 | actrec=saRecorder; 3 | for kk=1:numel(objs) 4 | obj=objs(kk); 5 | for i=1:numel(obj.BlockHandles) 6 | lns=get_param(obj.BlockHandles(i),'LineHandles'); 7 | dy_right=[];dy_left=[]; 8 | for j=1:numel(lns.Outport) 9 | if lns.Outport(j)>0 10 | lnpoints=get_param(lns.Outport(j),'Points'); 11 | dy_right=[dy_right;lnpoints(end,2)-lnpoints(1,2)]; 12 | end 13 | end 14 | for j=1:numel(lns.Inport) 15 | if lns.Inport(j)>0 16 | lnpoints=get_param(lns.Inport(j),'Points'); 17 | dy_left=[dy_left;lnpoints(1,2)-lnpoints(end,2)]; 18 | end 19 | end 20 | if (all(dy_right>0)||isempty(dy_right))&&(all(dy_left>0)||isempty(dy_left)) 21 | dy=min([dy_right;dy_left]); 22 | elseif (all(dy_right<0)||isempty(dy_right))&&(all(dy_left<0)||isempty(dy_left)) 23 | dy=max([dy_right;dy_left]); 24 | else 25 | dy=0; 26 | end 27 | if dy~=0 28 | oldpos=get_param(obj.BlockHandles(i),'Position'); 29 | newpos=oldpos; 30 | newpos([2,4])=newpos([2,4])+dy; 31 | appdata=[]; 32 | actrec.SetParam(obj.BlockHandles(i),'Position',newpos); 33 | end 34 | end 35 | end 36 | end -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017, Yair Altman 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /@saMacro/saMacro.m: -------------------------------------------------------------------------------- 1 | classdef saMacro < handle 2 | %SAMACRO Summary of this class goes here 3 | % Detailed explanation goes here 4 | 5 | properties 6 | Name = '' 7 | Pattern = '' 8 | PromptMethod 9 | Callback 10 | 11 | Type = '' 12 | % This property controls whether the macro will be tested run 13 | % earlier, generally: 14 | % the shorter the command string pattern is, the lower priority 15 | % (larger number) it shall possess. In this way it is guaranteed 16 | % that the longer pattern will not be preempted by the shorter 17 | % pattern when they have same beginning characters 18 | Priority = 50; 19 | Console 20 | end 21 | 22 | methods 23 | function obj=saMacro(varargin) 24 | if isstr(varargin{1}) 25 | obj.Name = varargin{1}; 26 | end 27 | end 28 | 29 | function set.Pattern(obj, val) 30 | obj.Pattern = val; 31 | if isempty(obj.PromptMethod) 32 | if val(1)=='^' 33 | val(1)=''; 34 | end 35 | prompts = regexp(val, '\|', 'split'); 36 | prompts = regexprep(prompts, '(^\()|(\)$)', ''); 37 | obj.PromptMethod = prompts; 38 | end 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /_BlockRegistration/regblock_interpnd.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_interpnd 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Interpolation_n-D'); 6 | 7 | sabt.RoutineMethod = @routine_interpnd; 8 | sabt.RoutinePattern = '^(itp|interpnd)'; 9 | 10 | 11 | sabt.ConnectPort = [0, 1]; 12 | 13 | sabt.MajorProperty = 'Table'; 14 | sabt.DictRenameMethod = {'Table'}; 15 | sabt.DefaultParameters = {'AttributesFormatString','%','ExtrapMethod','None - Clip'}; 16 | 17 | sabt.LayoutSize.PortSpacing = 15; 18 | 19 | sabt.PropagateDownstreamStringMethod = 'Table'; 20 | sabt.OutportStringMethod = 'Table'; 21 | sabt.AnnotationMethod = sprintf('%%
'); 22 | 23 | sabt.BlockSize = [50, 50]; 24 | 25 | end 26 | 27 | 28 | function [actrec, success] = routine_interpnd(cmdstr, console) 29 | actrec=saRecorder;success = false; 30 | btobj = console.MapTo('Interpolation_n-D'); 31 | %parse input command 32 | cmdpsr = saCmdParser(cmdstr, btobj.RoutinePattern); 33 | [result, bclean] = cmdpsr.ParseStringAndInteger; 34 | if ~bclean 35 | [actrec, success] = deal(saRecorder, false);return; 36 | end 37 | 38 | pvpair = {}; 39 | if ~isempty(result.String) 40 | pvpair = [pvpair, 'Table', result.String]; 41 | end 42 | if ~isempty(result.Integer) 43 | pvpair = [pvpair, 'NumberOfTableDimensions', int2str(result.Integer)]; 44 | end 45 | actrec = btobj.GenericContextAdd(pvpair{:}); 46 | success = true; 47 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_clean.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_clean 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('script_clean'); 6 | sam.Pattern = '^clean'; 7 | sam.Callback = @script_clean; 8 | 9 | end 10 | 11 | function [actrec, success] =script_clean(cmdstr, console) 12 | actrec=saRecorder; 13 | % 1. clean unconnected lines 14 | lns = saFindSystem(gcs, 'line_unconnected'); 15 | actrec.DeleteLine(lns); 16 | % 2. clean unconnected blocks 17 | blocks = saFindSystem(gcs, 'block'); 18 | for i=1:numel(blocks) 19 | lns = get_param(blocks(i),'LineHandles'); 20 | flds = fieldnames(lns); 21 | for kf = 1:numel(flds) 22 | tmplnhdls = lns.(flds{kf}); 23 | if isempty(tmplnhdls)||all(tmplnhdls<0) 24 | haveline = false; 25 | else 26 | haveline = true; break; 27 | end 28 | end 29 | if ~haveline 30 | actrec.Dummy;% use this trick to make actrec not empty (otherwise this action may be taken as unsuccessful) 31 | delete(blocks(i)); 32 | end 33 | end 34 | % 3. Call clean method of blocks 35 | blocks = saFindSystem(gcs, 'block'); % must find again 36 | optstr = strtrim(regexprep(cmdstr, '^clean\s*', '' ,'once')); 37 | for i=1:numel(blocks) 38 | btobj = console.MapTo(blocks(i)); 39 | actrec + btobj.ArrangePort(blocks(i), optstr); 40 | actrec + btobj.Clean(blocks(i)); 41 | end 42 | success = true; 43 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_switch.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_switch 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Switch'); 6 | 7 | sabt.RoutinePattern = '^(switch|sw)'; 8 | sabt.RoutineMethod = @routine_switch; 9 | 10 | sabt.DefaultParameters = {'Criteria', 'u2 ~= 0'}; 11 | 12 | sabt.InportStringMethod = 1; % pass through 13 | sabt.OutportStringMethod = 3; % pass through the 3rd inport 14 | 15 | sabt.RefineMethod = @refine_method; 16 | sabt.AnnotationMethod = '%'; 17 | sabt.DataTypeMethod = []; 18 | 19 | sabt.ConnectPort = [2, 1]; 20 | 21 | sabt.BlockSize = [20, 60]; 22 | 23 | end 24 | 25 | function actrec = refine_method(blkhdl) 26 | actrec = saRecorder; 27 | actrec.SetParamHighlight(blkhdl,'Criteria','u2 ~= 0'); 28 | end 29 | 30 | 31 | function [actrec, success] =routine_switch(cmdstr, console) 32 | btobj = console.MapTo('Switch'); 33 | bkup = btobj.ConnectPort; 34 | 35 | cmdpsr = saCmdParser(cmdstr, btobj.RoutinePattern); 36 | if ismember(cmdpsr.OptionStr, {'1', '3'}) 37 | btobj.ConnectPort = [str2double(cmdpsr.OptionStr), 1]; 38 | else 39 | if isempty(cmdpsr.OptionStr)||isequal(cmdpsr.OptionStr,'2') 40 | btobj.ConnectPort(2)=0; % disable insert to line behavior 41 | else 42 | [actrec, success] = deal(saRecorder, false); return; 43 | end 44 | end 45 | [actrec, success] = Routines.simple(btobj, '', ''); 46 | btobj.ConnectPort = bkup; % RESTORE 47 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_motohawk_probe.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_motohawk_probe 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('MotoHawk_lib/Calibration & Probing Blocks/motohawk_probe'); 6 | 7 | sabt.RoutinePattern = '^mh\s*(prb|probe)'; 8 | sabt.RoutineMethod = @routine_motohawk_probe; 9 | sabt.RoutinePrompts = {'mh prb', 'mh probe'}; 10 | sabt.RoutinePriority = 20; 11 | 12 | sabt.ConnectPort = [1, 0]; 13 | 14 | sabt.MajorProperty = 'nam'; 15 | sabt.DictRenameMethod = {'nam'}; 16 | 17 | parbt = regprotoblock_motohawk_general; 18 | sabt.Inherit(parbt, ... 19 | 'InportStringMethod',... 20 | 'OutportStringMethod',... 21 | 'PropagateUpstreamStringMethod',... 22 | 'RefineMethod'); 23 | 24 | sabt.BlockSize = [20, 25]; 25 | sabt.LayoutSize.CharWidth = 6; 26 | sabt.AutoSizeMethod = -3; % rightwards expand to show string 27 | end 28 | 29 | 30 | function [actrec, success] = routine_motohawk_probe(cmdstr, console) 31 | actrec=saRecorder;success = false; 32 | saLoadLib('MotoHawk_lib'); 33 | btobj = console.MapTo('MotoHawk Probe'); 34 | cmdpsr = saCmdParser(cmdstr, btobj.RoutinePattern); 35 | [result, bclean] = cmdpsr.ParseStringAndInteger; 36 | if ~bclean [actrec, success]=deal(saRecorder, false); return;end 37 | if isempty(result.String) 38 | pvpair = {}; 39 | else 40 | pvpair = {'nam', ['''',result.String,'''']}; 41 | end 42 | actrec + btobj.GenericContextAdd(result.Integer, pvpair{:}); 43 | success = true; 44 | end -------------------------------------------------------------------------------- /saAnnotation.m: -------------------------------------------------------------------------------- 1 | classdef saAnnotation < saObject 2 | %SA_SLBLOCK Summary of this class goes here 3 | % Detailed explanation goes here 4 | 5 | properties 6 | MajorProperty = 'Text'; 7 | SetPropertyMethod = 'Text'; 8 | end 9 | 10 | properties (Constant) 11 | Dictionary = SACFG_DICTIONARY; 12 | end 13 | 14 | methods 15 | function obj = saAnnotation(varargin) 16 | obj = obj@saObject('annotation'); 17 | obj.MapKey = 'annotation'; 18 | end 19 | 20 | function actrec = DictRename(obj, hdl) 21 | % 22 | actrec = saRecorder; 23 | nam=get_param(hdl,'Text'); 24 | newnam=saDictRenameString(nam,obj.Dictionary); 25 | actrec.SetParam(hdl, 'Text', newnam); 26 | end 27 | 28 | function actrec = ReplaceStr(obj, hdl, oldstr, newstr) 29 | % 30 | actrec = saRecorder; 31 | nam = get_param(hdl, 'Text'); 32 | if isempty(nam) 33 | return; 34 | end 35 | if strcmp(oldstr, '^') % add prefix 36 | newnam = [newstr, nam]; 37 | elseif strcmp(oldstr, '$') % append suffix 38 | newnam = [nam, newstr]; 39 | else 40 | newnam = regexprep(nam, oldstr, newstr); 41 | end 42 | actrec.SetParam(hdl, 'Text',newnam); 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /saGetBlockMapKey.m: -------------------------------------------------------------------------------- 1 | function mapkey = saGetBlockMapKey(blkhdl) 2 | if isstr(blkhdl) 3 | if ~isempty(strfind(blkhdl, '/')) 4 | libname = strtok(blkhdl, '/'); 5 | if ~bdIsLoaded(libname) 6 | if exist(libname, 'file')==4 7 | load_system(libname); 8 | else %if given string but cannot find corresponding MDL file 9 | mapkey = []; % return mapkey as empty 10 | return; 11 | end 12 | end 13 | blkhdl = get_param(blkhdl, 'Handle'); 14 | else 15 | mapkey = blkhdl; 16 | return; 17 | end 18 | end 19 | msktyp = get_param(blkhdl,'MaskType'); 20 | blktyp = get_param(blkhdl,'BlockType'); 21 | if ~isempty(msktyp) 22 | mapkey = msktyp; 23 | else 24 | if ismember(blktyp, {'S-Function','SubSystem'}) 25 | [issf, sftyp] = saIsStateflow(blkhdl); 26 | if issf % bug fix for version after 2012b wherein "Stateflow" is not MaskType property anymore 27 | mapkey = sftyp; 28 | else 29 | refblk = get_param(blkhdl, 'ReferenceBlock'); 30 | ancblk = get_param(blkhdl, 'AncestorBlock'); 31 | if ~isempty(refblk) 32 | mapkey = refblk; 33 | elseif ~isempty(ancblk) 34 | mapkey = ancblk; 35 | % elseif 36 | else 37 | mapkey = blktyp; 38 | end 39 | end 40 | else 41 | mapkey = blktyp; 42 | end 43 | end 44 | end -------------------------------------------------------------------------------- /releasepack.m: -------------------------------------------------------------------------------- 1 | function releasepack(p) 2 | if nargin<1 3 | p=true; 4 | end 5 | if ~isdir('releases') 6 | mkdir('releases'); 7 | end 8 | rtdir = pwd; 9 | packdir = ['.\releases\SimAssist_V', datestr(now, 'yyyymmddHHMM')]; 10 | mkdir(packdir); 11 | 12 | df = dir; 13 | copy_exlist = {'releases','demos','releasepack','Version.txt','^\.git','\.asv$'}; 14 | for i=1:numel(df) 15 | if ismember(df(i).name, {'.', '..'}) 16 | continue; 17 | end 18 | if isempty(cell2mat(regexp(df(i).name, copy_exlist, 'once'))) 19 | copyfile(df(i).name, fullfile(packdir, df(i).name)); 20 | end 21 | end 22 | cd(packdir); 23 | pcode_exlist = {'^SACFG_', 'whichtorun', 'findjobj'}; 24 | if p 25 | pfolder(pwd, pcode_exlist); 26 | end 27 | cd('..'); 28 | 29 | % zip file 30 | [~, packname] = fileparts(packdir); 31 | zip(packname, packname); 32 | 33 | cd(rtdir); 34 | 35 | 36 | function pfolder(fd, pcode_exlist) 37 | dfs = dir(fd); 38 | ds = dfs([dfs.isdir]); 39 | %remove .asv files 40 | asvs = dfs(~cellfun(@isempty, regexp({dfs.name}, '\.asv$', 'once'))); 41 | for i=1:numel(asvs) 42 | delete(fullfile(fd, asvs(i).name)); 43 | end 44 | 45 | mfs = what(fd); 46 | mfs = mfs.m; 47 | for i=1:numel(mfs) 48 | if isempty(cell2mat(regexp(mfs{i}, pcode_exlist))) 49 | fmf = fullfile(fd, mfs{i}); 50 | pcode(fmf, '-inplace'); 51 | delete(fmf); 52 | end 53 | end 54 | for i=1:numel(ds) 55 | if ds(i).name~='.' 56 | pfolder(fullfile(fd, ds(i).name), pcode_exlist); 57 | end 58 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_sum.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_sum 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Sum'); 6 | 7 | sabt.RoutinePattern = '^[+-]+'; 8 | sabt.RoutineMethod = @routine_plus_minus; 9 | 10 | 11 | sabt.MajorProperty = 'Inputs'; 12 | 13 | sabt.OutportStringMethod = 1; 14 | sabt.InportStringMethod = 1; 15 | 16 | sabt.BlockSize = [25, 70]; 17 | sabt.AutoSizeMethod = -1; 18 | 19 | sabt.LayoutSize.PortSpacing = 35; 20 | sabt.LayoutSize.ToLineOffset = [50 100]; 21 | end 22 | 23 | 24 | function [actrec, success] = routine_plus_minus(cmdstr, console) 25 | actrec=saRecorder;success = false; 26 | btobj = console.MapTo('Sum'); 27 | cmdpsr = saCmdParser(cmdstr, btobj.RoutinePattern); 28 | if numel(cmdpsr.PatternStr)==1 29 | operator = ['+', cmdpsr.PatternStr]; 30 | else 31 | operator = cmdpsr.PatternStr; 32 | end 33 | [operand, bclean] = cmdpsr.ParseSingleValue; 34 | if ~bclean [actrec, success]=deal(saRecorder, false); return;end 35 | 36 | [actrec2, block] = btobj.AddBlock('Inputs', operator); actrec.Merge(actrec2); 37 | if ~isempty(operand) %add 2nd operand 38 | btobjcnst = console.MapTo('Constant'); 39 | pts = get_param(block, 'PortHandles'); 40 | option.PropagateString = false; 41 | actrec + btobjcnst.AddBlockToPort(pts.Inport(2), option, 'Value', operand); 42 | else 43 | srchdls = saFindSystem(gcs,'line_sender'); 44 | if ~isempty(srchdls) 45 | actrec.MultiAutoLine(srchdls, block); 46 | end 47 | end 48 | success = true; 49 | end -------------------------------------------------------------------------------- /@saBlockGroup/VerticalAlign.m: -------------------------------------------------------------------------------- 1 | function actrec=VerticalAlign(objs) 2 | actrec=saRecorder; 3 | for i=1:numel(objs); 4 | obj=objs(i); 5 | blks=obj.BlockHandles; 6 | while ~isempty(blks) 7 | sameblks=blks(1); 8 | blktyp=get_param(blks(1),'BlockType'); 9 | basepos=get_param(blks(1),'Position'); 10 | [x1,x2]=deal(basepos(1),basepos(3)); 11 | basewidth=x2-x1; 12 | lbd=x1-30;%left bound 13 | rbd=x2+30;%right bound 14 | for i=2:numel(blks) 15 | tmppos=get_param(blks(i),'Position'); 16 | [r1,r2]=deal(tmppos(1),tmppos(3)); 17 | if strcmp(blktyp,get_param(blks(i),'BlockType'))&& ...%Same type 18 | ((lbd-r1)*(rbd-r1)<=0||(lbd-r2)*(rbd-r2)<=0)&& ...%intersect vertically 19 | (r2-r1)<=1.5*basewidth %width around 20 | sameblks=[sameblks;blks(i)]; 21 | end 22 | end 23 | pos=get_param(sameblks,'Position'); 24 | if iscell(pos) 25 | pos=cell2mat(pos); 26 | end 27 | mxwidth=mean(pos(:,3)-pos(:,1)); %change from max to mean 28 | l_edge=ceil((min(pos(:,1))+max(pos(:,3))-mxwidth)/2); 29 | for i=1:numel(sameblks) 30 | tsblkpos=get_param(sameblks(i),'Position'); 31 | tsblkpos(1)=l_edge; 32 | tsblkpos(3)=l_edge+mxwidth; 33 | actrec.SetParam(sameblks(i),'Position',tsblkpos); 34 | end 35 | 36 | blks=setdiff(blks,sameblks); 37 | end 38 | end 39 | end -------------------------------------------------------------------------------- /saGetLineDominantBlock.m: -------------------------------------------------------------------------------- 1 | function blocks = saGetLineDominantBlock(lnhdl, direction) 2 | if nargin<2 3 | direction = 'downstream' 4 | end 5 | domblks = []; 6 | ndomblks = []; 7 | if lnhdl<0 8 | blocks.Dominant = domblks; 9 | blocks.Recessive = ndomblks; 10 | return; 11 | end 12 | 13 | switch direction 14 | case 'downstream' 15 | dstblks = unique(get_param(lnhdl, 'DstBlockHandle')); 16 | dstpts = get_param(lnhdl, 'DstPortHandle'); 17 | srcpt = get_param(lnhdl, 'SrcPortHandle'); 18 | dstpts(dstpts<0) = []; 19 | for i=1:numel(dstblks) 20 | if dstblks(i)<0 continue; end 21 | dstblklns = get_param(dstblks(i), 'LineHandles'); 22 | inlns = dstblklns.Inport(dstblklns.Inport>0); 23 | insrcpts = get_param(inlns, 'SrcPortHandle'); 24 | if iscell(insrcpts) 25 | srcpts = unique(cell2mat(insrcpts)); 26 | end 27 | if isequal(srcpt, insrcpts) 28 | domblks = [domblks; dstblks(i)]; 29 | else 30 | ndomblks = [ndomblks; dstblks(i)]; 31 | end 32 | end 33 | case 'upstream' 34 | srcblk = get_param(lnhdl, 'SrcBlockHandle'); 35 | if srcblk<0 return; end 36 | srcblklns = get_param(srcblk, 'LineHandles'); 37 | if ~any(srcblklns.Outport>0 & srcblklns.Outport~=lnhdl) 38 | domblks = srcblk; 39 | else 40 | ndomblks = srcblk; 41 | end 42 | otherwise 43 | end 44 | blocks.Dominant = domblks; 45 | blocks.Recessive = ndomblks; 46 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_routine_datastore.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_routine_datastore 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('adder_datastore'); 6 | sam.Pattern = '^ds(w|r|m)'; 7 | sam.PromptMethod = {'dsm','dsr','dsw'}; 8 | sam.Callback = @adder_datastore; 9 | 10 | end 11 | 12 | function [actrec, success] =adder_datastore(cmdstr, console) 13 | actrec=saRecorder;success = false; 14 | %parse input command 15 | regtmp = regexp(cmdstr, '^ds(w|r|m)\s*', 'tokens','once'); 16 | dstype=regtmp{1}; 17 | optstr = strtrim(regexprep(cmdstr, '^ds(w|r|m)\s*','')); 18 | % 19 | dsrsel=find_system(gcs,'SearchDepth',1,'LookUnderMasks','on','FollowLinks','on','FindAll','on','BlockType','DataStoreRead','Selected','on'); 20 | dswsel=find_system(gcs,'SearchDepth',1,'LookUnderMasks','on','FollowLinks','on','FindAll','on','BlockType','DataStoreWrite','Selected','on'); 21 | dsmsel=find_system(gcs,'SearchDepth',1,'LookUnderMasks','on','FollowLinks','on','FindAll','on','BlockType','DataStoreMemory','Selected','on'); 22 | dsblksel=[dsrsel; dswsel; dsmsel]; 23 | switch dstype 24 | case 'w' 25 | btobj = console.MapTo('DataStoreWrite'); 26 | case 'r' 27 | btobj = console.MapTo('DataStoreRead'); 28 | case 'm' 29 | btobj = console.MapTo('DataStoreMemory'); 30 | end 31 | if isempty(dsblksel) 32 | actrec + Routines.majorprop_str_num(btobj, optstr, ''); 33 | else 34 | for i=1:numel(dsblksel) 35 | dsbtobj = console.MapTo(dsblksel(i)); 36 | actrec + dsbtobj.CreateBroBlock(dsblksel(i), btobj.ConnectPort); 37 | end 38 | end 39 | success = true; 40 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_relationaloperator.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_relationaloperator 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('RelationalOperator'); 6 | 7 | sabt.RoutinePattern = '^[><=~]+'; 8 | sabt.RoutineMethod = @routine_compare; 9 | sabt.RoutinePrompts = {'==' '~=' '<' '<=' '>=' '>'}; 10 | 11 | 12 | 13 | sabt.MajorProperty = 'Operator'; 14 | sabt.RollPropertyMethod = -1; 15 | 16 | sabt.BlockPreferOption.AutoDataType = false; 17 | 18 | sabt.BlockSize = [25, 70]; 19 | 20 | sabt.AutoSizeMethod = []; % no need for auto size 21 | sabt.DataTypeMethod = []; 22 | 23 | end 24 | 25 | 26 | function [actrec, success] = routine_compare(cmdstr, console) 27 | actrec=saRecorder;success = false; 28 | btobj = console.MapTo('RelationalOperator'); 29 | cmdpsr = saCmdParser(cmdstr, btobj.RoutinePattern); 30 | if ~ismember(cmdpsr.PatternStr, {'==' '~=' '<' '<=' '>=' '>'}) 31 | return; 32 | end 33 | option1.AutoDataType = false; % disable auto-datatype coz output always boolean 34 | [actrec2, block] = btobj.AddBlock('RelationalOperator','Operator', cmdpsr.PatternStr, option1); actrec.Merge(actrec2); 35 | % add second operand if necessary 36 | if isempty(cmdpsr.OptionStr) 37 | srchdls = saFindSystem(gcs,'line_sender'); 38 | if ~isempty(srchdls) 39 | actrec.MultiAutoLine(srchdls, block); 40 | end 41 | else 42 | btobjcnst = console.MapTo('Constant'); 43 | pts = get_param(block, 'PortHandles'); 44 | option2.PropagateString = false; 45 | actrec + btobjcnst.AddBlockToPort(pts.Inport(2), option2, 'Value', cmdpsr.OptionStr); 46 | end 47 | success = true; 48 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_constant.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_constant 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Constant'); 6 | 7 | sabt.RoutineMethod = 'majorprop_value'; 8 | sabt.RoutinePattern = '^(constant|const|cnst)'; 9 | 10 | sabt.ConnectPort = [0, 1]; 11 | 12 | sabt.MajorProperty = 'Value'; 13 | sabt.DictRenameMethod = 1; % use major property 14 | 15 | sabt.PropagateDownstreamStringMethod = @dwnstream_prop; 16 | sabt.OutportStringMethod = @outportstr; 17 | sabt.AnnotationMethod = 'DT: %'; 18 | sabt.RefineMethod = @refine_constant; 19 | 20 | sabt.BlockSize = [70, 25]; 21 | sabt.LayoutSize.CharWidth = 6; 22 | 23 | sabt.AutoSizeMethod = -2; % leftwards expand to show string 24 | 25 | sabt.DefaultDataType = 'Inherit: Inherit from ''Constant value'''; 26 | sabt.DataTypeMethod = -1; 27 | 28 | sabt.GetBroMethod = @get_bro_blocks; 29 | end 30 | 31 | 32 | function actrec = refine_constant(blkhdl) 33 | actrec = saRecorder; 34 | actrec.SetParamHighlight(blkhdl, 'Name', get_param(blkhdl, 'Value')); 35 | end 36 | 37 | function broblks = get_bro_blocks(blkhdl) 38 | parsys = get_param(blkhdl, 'Parent'); 39 | val = get_param(blkhdl,'Value'); 40 | broblks = find_system(parsys,'SearchDepth',1,'FindAll','on','FollowLinks','on','BlockType','Constant','Value',val); 41 | end 42 | 43 | 44 | function str = outportstr(hdl, appdata) 45 | rawstr = get_param(get_param(hdl,'Parent'), 'Value'); 46 | str = regexprep(rawstr, '^K([A-Z]+_)', 'V$1'); 47 | end 48 | 49 | function dwnstream_prop(blkhdl, instr) 50 | valstr = regexprep(instr, '^V([A-Z]+_)', 'K$1'); 51 | set_param(blkhdl, 'Value',valstr); 52 | end -------------------------------------------------------------------------------- /info.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 2008a-2015b 9 | 10 | SimAssist 11 | 12 | 13 | toolbox 14 | 15 | \help\book.gif 16 | 17 | \help\html 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | disp('SimAssist Help Documentation') 27 | 28 | $toolbox/matlab/icons/bookicon.gif 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /@saProtoBlock/SetDataType.m: -------------------------------------------------------------------------------- 1 | function actrec = SetDataType(obj, blkhdl, dt) 2 | actrec = saRecorder; 3 | 4 | setdtmethod = obj.DataTypeMethod; 5 | console = obj.Console; 6 | 7 | if isempty(setdtmethod) 8 | return; 9 | end 10 | 11 | if nargin<3 12 | dt=''; hilite = false; 13 | else 14 | hilite = true; 15 | end 16 | 17 | if isempty(dt) 18 | majprop = obj.GetMajorProperty(blkhdl); 19 | if ~isempty(majprop) % analyzed take priority over default RunOption 20 | dt = analyze_datatype(get_param(blkhdl, majprop)); 21 | end 22 | end 23 | if isempty(dt) && ~isempty(console) 24 | dt = console.RunOption.DataType; 25 | end 26 | 27 | if isa(setdtmethod, 'function_handle') 28 | nn = nargout(setdtmethod); 29 | ni = nargin(setdtmethod); 30 | argsin = {blkhdl, dt}; 31 | if nn~=0 %if mandatory output exist, must be saRecorder 32 | actrec.Merge(setdtmethod(argsin{1:ni})); 33 | else 34 | setdtmethod(setdtmethod(argsin{1:ni})); 35 | end 36 | elseif ischar(setdtmethod) % if string, it shall be the data type property 37 | if ~isempty(dt) 38 | if hilite 39 | actrec.SetParamHighlight(blkhdl, setdtmethod, dt); 40 | else 41 | actrec.SetParam(blkhdl, setdtmethod, dt); 42 | end 43 | end 44 | elseif isequal(setdtmethod, -1) 45 | if ~isempty(dt) 46 | dlgparas = get_param(blkhdl, 'ObjectParameters'); 47 | if isfield(dlgparas, 'OutDataTypeStr') 48 | if hilite 49 | actrec.SetParamHighlight(blkhdl, 'OutDataTypeStr', dt); 50 | else 51 | actrec.SetParam(blkhdl, 'OutDataTypeStr', dt); 52 | end 53 | end 54 | end 55 | else 56 | end 57 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_motohawk_calibration.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_motohawk_calibration 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('MotoHawk_lib/Calibration & Probing Blocks/motohawk_calibration'); 6 | 7 | sabt.RoutinePattern = '^mh\s*(cal)'; 8 | sabt.RoutineMethod = @routine_motohawk_calibration; 9 | sabt.RoutinePrompts = {'mhcal'}; 10 | sabt.RoutinePriority = 20; 11 | 12 | 13 | sabt.ConnectPort = [0, 1]; 14 | sabt.MajorProperty = 'nam'; 15 | sabt.DictRenameMethod = {'nam', 'val'}; 16 | 17 | parbt = regprotoblock_motohawk_general; 18 | sabt.Inherit(parbt, ... 19 | 'PropagateDownstreamStringMethod',... 20 | 'RefineMethod',... 21 | 'DataTypeMethod'); 22 | 23 | sabt.InportStringMethod = 'val'; 24 | sabt.OutportStringMethod = 'val'; 25 | 26 | sabt.BlockSize = [20, 25]; 27 | sabt.LayoutSize.CharWidth = 8; 28 | sabt.AutoSizeMethod = -2; % rightwards expand to show string 29 | end 30 | 31 | 32 | function [actrec, success] = routine_motohawk_calibration(cmdstr, console) 33 | saLoadLib('MotoHawk_lib'); 34 | btobj = console.MapTo('MotoHawk Calibration'); 35 | cmdpsr = saCmdParser(cmdstr, btobj.RoutinePattern); 36 | [result, bclean] = cmdpsr.ParseNumericAndString; 37 | if ~bclean [actrec, success]=deal(saRecorder, false); return;end 38 | [num, val] = deal(result.NumericStr, result.String); 39 | 40 | if isempty(num) && isempty(val) 41 | pvpair = {}; 42 | elseif isempty(num) && ~isempty(val) 43 | pvpair = {'nam', ['''',val,''''], 'val', val}; 44 | elseif ~isempty(num) && isempty(val) 45 | pvpair={'val', num}; 46 | else 47 | pvpair={'nam', ['''',val,''''], 'val', num}; 48 | end 49 | actrec = btobj.GenericContextAdd(pvpair{:}); 50 | success = true; 51 | end -------------------------------------------------------------------------------- /@saProtoBlock/AddBlockArray.m: -------------------------------------------------------------------------------- 1 | function [actrec, blkhdls] = AddBlockArray(obj, varargin) 2 | % Similar to AddBlock except that this function creates array of blocks 3 | % Order of different types of arguments is insignificant 4 | % obj.AddBlockArray(N, ...); 5 | % obj.AddBlockArray(startpos, N, ...); 6 | % obj.AddBlockArray(startpos, N, blksize, ...); 7 | % obj.AddBlockArray(N, startpos, 'PROP1', 'VAL1', ... blksize, ... POSTFUN); 8 | % obj.AddBlockArray(N, startpos, 'PROP1', {'VAL1','VAL2','VAL3'}, ... blksize, ... POSTFUN); 9 | 10 | actrec = saRecorder;blkhdls = []; 11 | 12 | i_argnum = cellfun(@isnumeric, varargin); 13 | argnum = varargin(i_argnum); 14 | argnnum = varargin(~i_argnum); 15 | 16 | iN = cellfun(@isscalar, argnum); 17 | if isempty(iN) 18 | error('saBlock:AddBlockArray: Number of block must be specified'); 19 | return; 20 | else 21 | N = argnum{iN}; 22 | end 23 | 24 | szpara = argnum(~iN); % the vector numeric paramters must be in "startpos, blksize" order 25 | if numel(szpara)<2 26 | blksize = obj.GetBlockSize; 27 | else 28 | blksize = szpara{2}; 29 | end 30 | if numel(szpara)<1 31 | startpos = saGetMousePosition; 32 | else 33 | startpos = szpara{1}; 34 | end 35 | 36 | 37 | DH = obj.LayoutSize.VerticalMargin + blksize(2); 38 | for i=1:N 39 | ltpos = startpos+[0, DH*(i-1)]; 40 | blkpos = [ltpos, ltpos+blksize]; 41 | argnnum_decell = cellfun(@(arg)get_nth_cell(arg, i), argnnum, 'UniformOutput', false); 42 | [actrec2, blkhdl] = obj.AddBlock(blkpos, argnnum_decell{:}); actrec + actrec2; 43 | blkhdls = [blkhdls; blkhdl]; 44 | end 45 | end 46 | 47 | function argout = get_nth_cell(arg, n) 48 | argout = arg; 49 | if iscell(arg) 50 | argout = arg{min(n,end)}; 51 | end 52 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_busassignment.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_busassignment 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('BusAssignment'); 6 | sabt.RoutineMethod = 'majorprop_str_num'; 7 | sabt.RoutinePattern = '^(busassign|busassignment)'; 8 | 9 | sabt.MajorProperty = 'Name'; 10 | sabt.BlockSize = [100, 120]; 11 | 12 | sabt.PropagateUpstreamStringMethod = @propagate_upstream; 13 | sabt.PropagateDownstreamStringMethod = @propagate_downstream; 14 | sabt.InportStringMethod = @inport_string_busassignement; 15 | 16 | end 17 | 18 | 19 | function thestr = inport_string_busassignement(pthdl, appdata) 20 | ptnum = get_param(pthdl, 'PortNumber'); 21 | parblk = get_param(pthdl, 'Parent'); 22 | pttyp = get_param(pthdl, 'PortType'); 23 | sigs=regexp(get_param(parblk,'AssignedSignals'),',','split'); 24 | if ptnum>1 25 | thestr=sigs{ptnum-1}; 26 | else 27 | pts = get_param(parblk, 'PortHandles'); 28 | thestr = appdata.Console.GetDownstreamString(pts.Outport(1)); 29 | end 30 | end 31 | 32 | 33 | function actrec = propagate_upstream(blkhdl, instr) 34 | actrec = saRecorder; 35 | sigstr = ''; 36 | sigs=regexp(get_param(blkhdl,'AssignedSignals'),',','split'); 37 | for i=2:numel(instr) 38 | if ~isempty(instr{i}) 39 | sigs{i-1} = instr{i}; 40 | end 41 | end 42 | sigstr = sprintf('%s,',sigs{:}); sigstr(end)=''; 43 | actrec.SetParam(blkhdl, 'AssignedSignals', sigstr); 44 | end 45 | 46 | function actrec = propagate_downstream(blkhdl) 47 | actrec = saRecorder; 48 | bussigs = saBusTraceForward(blkhdl); 49 | if numel(bussigs)<1 50 | return; 51 | else 52 | sigstr = sprintf('%s,',bussigs{:}); sigstr(end)=''; 53 | actrec.SetParam(blkhdl, 'AssignedSignals', sigstr); 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /_BlockRegistration/regblock_logic.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_logic 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Logic'); 6 | 7 | sabt.RoutineMethod = @routine_logical; 8 | sabt.RoutinePara.InportProperty = 'Inputs'; 9 | sabt.RoutinePattern = '^(and|or|not|xor|nor|nand)'; 10 | 11 | sabt.ArrangePortMethod{1} = 1; 12 | sabt.BlockPreferOption.AutoDataType = false; 13 | 14 | sabt.MajorProperty = 'Operator'; 15 | 16 | sabt.InportStringMethod = @inport_string; 17 | sabt.OutportStringMethod = @outport_string; 18 | sabt.RollPropertyMethod = -1; 19 | 20 | sabt.BlockSize = [25, 70]; 21 | sabt.AutoSizeMethod = -1; 22 | sabt.DataTypeMethod = []; 23 | 24 | sabt.LayoutSize.ToLineOffset = [50 100]; 25 | 26 | parbt = regblock_buscreator; 27 | sabt.Inherit(parbt, 'PlusMethod', 'MinusMethod', 'CleanMethod'); 28 | 29 | end 30 | 31 | 32 | function str = inport_string(hdl, appdata) 33 | parblk = get_param(hdl, 'Parent'); 34 | parpts = get_param(parblk, 'PortHandles'); 35 | ptnum = get_param(hdl, 'PortNumber'); 36 | opstr = get_param(parblk, 'Operator'); 37 | outstr = appdata.Console.GetDownstreamString(parpts.Outport); 38 | str = [outstr, '_', opstr, int2str(ptnum)]; 39 | end 40 | 41 | function str = outport_string(hdl, appdata) 42 | parblk = get_param(hdl, 'Parent'); 43 | parpts = get_param(parblk, 'PortHandles'); 44 | opstr = get_param(parblk, 'Operator'); 45 | instr = cellstr(appdata.Console.GetUpstreamString(parblk)); 46 | str = [opstr, '_', instr{:}]; 47 | end 48 | 49 | 50 | function [actrec, success] =routine_logical(cmdstr, console) 51 | btobj = console.MapTo('Logic'); 52 | cmdpsr = saCmdParser(cmdstr, btobj.RoutinePattern); 53 | [actrec, success] = Routines.dynamicinport(btobj, cmdpsr.OptionStr, '', ... 54 | 'Operator', cmdpsr.PatternStr); 55 | end -------------------------------------------------------------------------------- /@saAction/saAction.m: -------------------------------------------------------------------------------- 1 | classdef saAction < handle 2 | properties 3 | Type = '' 4 | Handle = -1 5 | Property = [] 6 | OldValue = '' 7 | NewValue = '' 8 | Data = [] 9 | end 10 | methods 11 | function obj=saAction(type, varargin) 12 | obj.Type=type; 13 | if nargin<2 14 | return; 15 | end 16 | switch obj.Type 17 | case 'set_param' 18 | obj.set_param(varargin{:}); 19 | case 'set_param_stateflow' 20 | obj.set_param_stateflow(varargin{:}); 21 | case 'add_block' 22 | obj.add_block(varargin{:}); 23 | case 'add_line' 24 | obj.add_line(varargin{:}); 25 | case 'delete_line' 26 | obj.delete_line(varargin{:}); 27 | case 'replace_block' 28 | obj.replace_block(varargin{:}); 29 | otherwise 30 | end 31 | end 32 | end 33 | methods(Access = private) 34 | set_param(obj,varargin) 35 | set_param_stateflow(obj,varargin) 36 | add_block(obj,varargin) 37 | add_line(obj, sys, varargin) 38 | replace_block(obj,varargin) 39 | delete_line(obj,varargin) 40 | 41 | undo_delete_line(obj) 42 | undo_set_param(obj) 43 | undo_set_param_stateflow(obj) 44 | undo_add_block(obj) 45 | undo_add_line(obj) 46 | undo_replace_block(obj) 47 | 48 | redo_set_param(obj) 49 | redo_delete_line(obj) 50 | redo_replace_block(obj) 51 | redo_set_param_stateflow(obj) 52 | redo_add_block(obj) 53 | redo_add_line(obj) 54 | end 55 | end 56 | 57 | -------------------------------------------------------------------------------- /@saBlockGroup/saBlockGroup.m: -------------------------------------------------------------------------------- 1 | classdef saBlockGroup 2 | properties 3 | Name 4 | BlockHandles 5 | end 6 | 7 | properties (Dependent = true) 8 | BlockCount 9 | Boundary 10 | end 11 | 12 | methods 13 | function obj=saBlockGroup(varargin) 14 | if nargin==1 15 | if isnumeric(varargin{1}) 16 | obj.BlockHandles=varargin{1}; 17 | obj.Name=''; 18 | elseif isstr(varargin{1}) 19 | strin=varargin{1}; 20 | if strcmpi(strin,'Selected') 21 | blks=find_system(gcs,'FindAll','on','SearchDepth',1,'Type','block','Selected','on'); 22 | obj.BlockHandles=setdiff(blks,get_param(gcs,'Handle')); 23 | obj.Name=''; 24 | end 25 | end 26 | elseif nargin==2 27 | obj.BlockHandles=varargin{2}; 28 | obj.Name=varargin{1}; 29 | else 30 | obj.BlockHandles=[]; 31 | obj.Name=''; 32 | end 33 | end 34 | %% 35 | function BlockCount=get.BlockCount(obj) 36 | BlockCount=numel(obj.BlockHandles); 37 | end 38 | %% 39 | function bd=get.Boundary(obj) 40 | if obj.BlockCount<1 41 | bd=[]; 42 | return; 43 | end 44 | blks=obj.BlockHandles; 45 | bd=get_param(blks(1),'Position'); 46 | for i=2:obj.BlockCount 47 | pos=get_param(blks(i),'Position'); 48 | mintmp=min(bd,pos); 49 | maxtmp=max(bd,pos); 50 | bd=[mintmp(1:2),maxtmp(3:4)]; 51 | end 52 | end 53 | end 54 | end -------------------------------------------------------------------------------- /@saProtoBlock/Color.m: -------------------------------------------------------------------------------- 1 | function actrec = Color(obj, blkhdl, colorspec) 2 | % Depends on ColorMethod of saBlock 3 | % ColorMethod can be the following types: 4 | % 2-element cell array: {1}: ForegroundColor, {2}:BackgroundColor 5 | % if not cell, then by default indicates the foreground color: 6 | % -1 : use random color 7 | % [R G B]: numeric 3-element array 8 | % 'string' : e.g., 'red', 'blue', '[0.6 0.3 0.9]' 9 | % @function_handle : customize way of coloring the block 10 | actrec = saRecorder; 11 | if nargin<3 12 | color_method = obj.ColorMethod; 13 | else 14 | color_method = colorspec; 15 | end 16 | if isempty(color_method) 17 | return; 18 | else 19 | if iscell(color_method) 20 | actrec + set_color(color_method{1}, blkhdl, 'ForegroundColor'); 21 | actrec + set_color(color_method{2}, blkhdl, 'BackgroundColor'); 22 | else 23 | actrec + set_color(color_method, blkhdl, 'ForegroundColor'); 24 | end 25 | end 26 | 27 | end 28 | 29 | 30 | function actrec = set_color(colorspec, blkhdl, fbprop) 31 | if nargin<3 32 | fbprop = 'ForegroundColor'; 33 | end 34 | actrec = saRecorder; 35 | if isempty(colorspec) || (isscalar(colorspec)&&~colorspec) 36 | return; 37 | elseif isstr(colorspec) 38 | actrec.SetParam(blkhdl, fbprop, colorspec); 39 | else 40 | if isnumeric(colorspec) 41 | if numel(colorspec)==3 42 | actrec.SetParam(blkhdl, fbprop, mat2str(colorspec)); 43 | elseif colorspec < 0 44 | actrec.SetParam(blkhdl, fbprop, mat2str(rand(1,3))); 45 | else 46 | end 47 | elseif isa(colorspec, 'function_handle') 48 | nn = nargout(colorspec); 49 | if nn~=0 %if mandatory output exist, must be saRecorder 50 | actrec.Merge(colorspec(blkhdl)); 51 | else 52 | colorspec(blkhdl); 53 | end 54 | else 55 | end 56 | end 57 | end -------------------------------------------------------------------------------- /@saRecorder/AutoLine.m: -------------------------------------------------------------------------------- 1 | function AutoLine(obj, srchdl, dsthdl, overlap_offset, varargin) 2 | % wrapper function for line connection between two objects 3 | % (line, port, block) 4 | if nargin<4 5 | overlap_offset = [0, 0]; 6 | end 7 | % input parameter parse and redefinition 8 | srctyp = get_param(srchdl, 'type'); 9 | dsttyp = get_param(dsthdl, 'type'); 10 | if strcmp(srctyp, 'block') 11 | srcblkpts = get_param(srchdl, 'PortHandles'); 12 | ptline = get_param(srcblkpts.Outport(1),'Line'); 13 | if ptline>0 14 | srchdl = ptline; srctyp = 'line'; 15 | else 16 | srchdl = srcblkpts.Outport(1); srctyp = 'port'; 17 | end 18 | end 19 | if strcmp(dsttyp, 'block') 20 | dstblkpts= get_param(dsthdl, 'PortHandles'); 21 | ptline = get_param(dstblkpts.Inport(1),'Line'); 22 | if ptline<0 23 | dsthdl = dstblkpts.Inport(1); dsttyp = 'port'; 24 | else 25 | return; 26 | end 27 | end 28 | if strcmp(srctyp,'line') 29 | if strcmp(get_param(srchdl, 'Connected'),'on') 30 | srcindex = 2; 31 | else 32 | srcindex = 3; 33 | end 34 | else 35 | srcindex = 1; 36 | end 37 | if strcmp(dsttyp,'port') 38 | dstindex = 2; 39 | else 40 | dstindex = 1; 41 | end 42 | switch srcindex 43 | case 1 44 | if dstindex == 1 45 | obj.AddLine_PortToNoSrcLine(srchdl, dsthdl); 46 | else 47 | obj.AddLine_PortToPort(srchdl, dsthdl); 48 | end 49 | case 2 50 | if dstindex == 1 51 | obj.AddLine_LineToNoSrcLine(srchdl, dsthdl, overlap_offset); 52 | else 53 | obj.AddLine_LineToPort(srchdl, dsthdl, overlap_offset); 54 | end 55 | case 3 56 | if dstindex == 1 57 | obj.AddLine_NoDstLineToNoSrcLine(srchdl, dsthdl); 58 | else 59 | obj.AddLine_NoDstLineToPort(srchdl, dsthdl); 60 | end 61 | otherwise 62 | end 63 | end -------------------------------------------------------------------------------- /@saConsole/LibScan.m: -------------------------------------------------------------------------------- 1 | function [blks, msktyps] = LibScan(obj, libnames) 2 | if nargin<2 || isempty(libnames) 3 | syss = find_system('SearchDepth',0); 4 | if ~isempty(syss) 5 | [si,v] = listdlg('PromptString','Select from current loaded block diagrams:',... 6 | 'ListSize', [160, 300],... 7 | 'ListString',syss); 8 | if v 9 | rtsys = syss(si); 10 | else 11 | return; 12 | end 13 | else 14 | [mdlfile, pathname] = uigetfile('*.mdl', 'Pick an model file','MultiSelect', 'on'); 15 | if isequal(mdlfile,0) || isequal(pathname,0) 16 | return; 17 | else 18 | open(fullfile(pathname, mdlfile)); 19 | rtsys = regexprep(mdlfile, '\.mdl$', '', 'once'); 20 | end 21 | end 22 | rtsys = cellstr(rtsys); 23 | else 24 | rtsys = cellstr(libnames); 25 | end 26 | for i=1:numel(rtsys) 27 | load_system(rtsys{i}); 28 | blks = find_system(rtsys{i}, 'Mask', 'on'); 29 | msktyps = get_param(blks,'MaskType'); 30 | blks = blks(~cellfun('isempty', msktyps)); 31 | msktyps = get_param(blks, 'MaskType'); 32 | % generate excel 33 | excel = actxserver('excel.application'); 34 | excel.Visible = true; 35 | wbk = excel.Workbooks.Add; 36 | sht = wbk.ActiveSheet; 37 | sht.Cells.Font.Name='Arial Unicode MS'; sht.Cells.Font.Size=10; 38 | nblk = numel(blks); 39 | actrng = sht.Range('A1:D1'); 40 | actrng.Value = {'MaskType', 'ShortCut', 'SourcePath', 'Priority'}; 41 | actrng.Interior.Color=13995603; 42 | actrng.Font.Bold=1; 43 | actrng.HorizontalAlignment=3; 44 | actrng.BorderAround(true); 45 | sht.Range(['A2:A', int2str(1+nblk)]).Value = msktyps; 46 | sht.Range(['B2:B', int2str(1+nblk)]).Value = lower(msktyps); 47 | sht.Range(['C2:C', int2str(1+nblk)]).Value = blks; 48 | sht.Range(['D2:D', int2str(1+nblk)]).Value = 50; 49 | end 50 | -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_autoline.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_autoline 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('script_autoline'); 6 | sam.Pattern = '^autoline'; 7 | sam.Callback = @script_autoline; 8 | 9 | end 10 | 11 | function [actrec, success] =script_autoline(cmdstr, console) 12 | actrec=saRecorder;success = false; 13 | % name based connection 14 | % first priority: unconnected ports and lines 15 | dsthdls = saFindSystem(gcs,'line_receiver'); 16 | if isempty(dsthdls) 17 | return; 18 | else 19 | dstinfo(numel(dsthdls)) = struct('handle',[],'name',[]); 20 | for i=1:numel(dsthdls) 21 | dstinfo(i).handle = dsthdls(i); 22 | dstinfo(i).name = console.GetDownstreamString(dsthdls(i)); 23 | end 24 | end 25 | srchdls = [saFindSystem(gcs,'outport_unconnected');saFindSystem(gcs,'line_nodst')]; 26 | if ~isempty(srchdls) 27 | srcinfo(numel(srchdls)) = struct('handle',[],'name',[]); 28 | for i=1:numel(srchdls) 29 | srcinfo(i).handle = srchdls(i); 30 | srcinfo(i).name = console.GetUpstreamString(srchdls(i)); 31 | end 32 | end 33 | if exist('srcinfo','var') 34 | [dummy,ia,ib] = intersect({srcinfo.name}, {dstinfo.name}); 35 | lnsrc = [srcinfo(ia).handle]'; 36 | lndst = [dstinfo(ib).handle]'; 37 | for i=1:numel(lnsrc) 38 | actrec.AutoLine(lnsrc(i), lndst(i)); 39 | end 40 | dstinfo = dstinfo(setdiff(1:numel(dstinfo), ib)); % remove from destination list 41 | end 42 | % second priority: already has goto 43 | btfrom = console.MapTo('From'); 44 | for i=1:numel(dstinfo) 45 | goto = find_system(gcs, 'FollowLinks','on','LookUnderMasks','on','FindAll', 'on', 'SearchDepth',1,'BlockType','Goto','GotoTag',dstinfo(i).name); 46 | if ~isempty(goto) 47 | actrec + btfrom.AddBlockToPort(dstinfo(i).handle); 48 | end 49 | end 50 | % third: automatically select from BusSelector 51 | 52 | success = true; 53 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_change_size.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_change_size 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('script_change_size'); 6 | sam.Pattern = '^(short|long|narrow|wide)'; 7 | sam.Callback = @script_change_size; 8 | 9 | end 10 | 11 | function [actrec, success] =script_change_size(cmdstr, console) 12 | actrec=saRecorder;success = false; 13 | objhdls = saFindSystem(gcs,'block'); 14 | type = regexp(cmdstr,'^(short|long|narrow|wide)','match','once'); 15 | opt = regexprep(cmdstr,'^(short|long|narrow|wide)e?r?\s*','','once'); 16 | if isempty(opt) 17 | scale = 1.1; 18 | else 19 | scale = str2double(opt); 20 | if isnan(scale) || ~scale 21 | success = false; return; 22 | end 23 | end 24 | for i=1:numel(objhdls) 25 | oldpos = get_param(objhdls(i),'Position'); 26 | oldsz = oldpos(3:4)-oldpos(1:2); 27 | W0 = oldsz(1); H0 = oldsz(2); 28 | dW = 0; dH = 0; 29 | switch type 30 | case 'long' 31 | dH = max(H0*scale-H0, 1); 32 | case 'short' 33 | dH = min(H0/scale-H0, -1); 34 | case 'narrow' 35 | dW = min(W0/scale-W0, -1); 36 | case 'wide' 37 | dW = max(W0*scale-W0, 1); 38 | otherwise 39 | end 40 | newpos = saRectifyPos(oldpos + round([-dW, -dH, dW, dH]/2)); 41 | actrec.SetParam(objhdls(i), 'Position', newpos); 42 | % ## some times position change fails if delta value too small, the 43 | % following code segment intends to handle this situation 44 | retrymax = 8; 45 | for k=1:retrymax 46 | rdbkpos = get_param(objhdls(i), 'Position'); 47 | if all(rdbkpos == oldpos) 48 | retrypos = saRectifyPos(oldpos+ 2^(k+1)*[-dW, -dH, dW, dH]); 49 | actrec.SetParam(objhdls(i), 'Position', retrypos); 50 | else 51 | break; 52 | end 53 | end 54 | end 55 | success = true; 56 | end -------------------------------------------------------------------------------- /@saProtoBlock/ReplaceStr.m: -------------------------------------------------------------------------------- 1 | function actrec = ReplaceStr(obj, blkhdl, oldstr, newstr) 2 | % 3 | actrec = saRecorder; 4 | 5 | if isempty(obj.StrReplaceMethod) 6 | return; 7 | elseif isa(obj.StrReplaceMethod, 'function_handle') 8 | strrep_method = obj.StrReplaceMethod; 9 | nn = nargout(strrep_method); 10 | if nn~=0 %if mandatory output exist, must be saRecorder 11 | actrec.Merge(strrep_method(blkhdl, oldstr, newstr)); 12 | else 13 | strrep_method(blkhdl, oldstr, newstr); 14 | end 15 | else % number of string 16 | if isequal(obj.StrReplaceMethod, 1) || ismember(oldstr, {'^','$'}) % set to 1 to use major property by default 17 | if ischar(obj.MajorProperty) 18 | props = cellstr(obj.MajorProperty); 19 | else 20 | props={}; 21 | end 22 | elseif isequal(obj.StrReplaceMethod, -1) % set to -1 to use auto generated string parameter list 23 | props = saGetStringDialogParameter(blkhdl); 24 | elseif isequal(obj.StrReplaceMethod, 2) 25 | props = obj.StrReplaceDefaults; 26 | elseif ischar(obj.StrReplaceMethod) 27 | props = cellstr(obj.StrReplaceMethod); 28 | elseif iscellstr(obj.StrReplaceMethod) 29 | props = obj.StrReplaceMethod; 30 | end 31 | objprops=get_param(blkhdl,'ObjectParameters'); 32 | for k=1:numel(props) 33 | thisprop = props{k}; 34 | if isfield(objprops, thisprop) 35 | oldpropstr = get_param(blkhdl, thisprop); 36 | if strcmp(oldstr, '^') % add prefix 37 | newpropstr = [newstr, oldpropstr]; 38 | elseif strcmp(oldstr, '$') % append suffix 39 | newpropstr = [oldpropstr, newstr]; 40 | else 41 | newpropstr = regexprep(oldpropstr, oldstr, newstr); 42 | end 43 | if ~strcmp(oldpropstr, newpropstr) 44 | actrec.SetParam(blkhdl, thisprop, newpropstr); 45 | end 46 | end 47 | end 48 | end 49 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_triggerport.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_triggerport 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('TriggerPort'); 6 | 7 | sabt.RoutinePattern = '^(trigger|trig|fc)'; 8 | sabt.RoutineMethod = @routine_trigger; 9 | 10 | sabt.PropagateUpstreamStringMethod = @trigpropupstream; 11 | 12 | sabt.BlockSize = [20, 20]; 13 | sabt.BlockPreferOption.ShowName = 'on'; 14 | 15 | sabt.AnnotationMethod = 'Upon enable: %'; 16 | 17 | sabt.DefaultParameters = {'TriggerType', 'function-call'}; 18 | end 19 | 20 | function [actrec, success] = routine_trigger(cmdstr, console) 21 | actrec=saRecorder;success = false; 22 | btobj = console.MapTo('TriggerPort'); 23 | cmdpsr = saCmdParser(cmdstr, btobj.RoutinePattern); 24 | 25 | if strcmp(cmdpsr.PatternStr, 'fc') 26 | if isempty(cmdpsr.OptionStr) 27 | pvpair = {'TriggerType', 'function-call', 'Name', 'Fcn'}; 28 | else 29 | pvpair = {'TriggerType', 'function-call', 'Name', cmdpsr.OptionStr}; 30 | end 31 | elseif ~isempty(cmdpsr.OptionStr) 32 | switch cmdpsr.OptionStr 33 | case 'fc' %function-call 34 | pvpair = {'TriggerType', 'function-call', 'Name', 'Fcn'}; 35 | case 'r' %rising 36 | pvpair = {'TriggerType', 'rising', 'Name', 'TrigRising'}; 37 | case 'f' %falling 38 | pvpair = {'TriggerType', 'rising', 'Name', 'TrigFalling'}; 39 | case 'e' %either 40 | pvpair = {'TriggerType', 'either', 'Name', 'TrigEither'}; 41 | otherwise 42 | pvpair = {'TriggerType', 'function-call', 'Name', cmdpsr.OptionStr}; 43 | end 44 | else 45 | pvpair = {}; 46 | end 47 | actrec + btobj.AddBlock(pvpair{:}); 48 | success = true; 49 | end 50 | 51 | function actrec = trigpropupstream(blkhdl, dummy, console) 52 | actrec = saRecorder; 53 | parsys = get_param(blkhdl, 'Parent'); 54 | pts = get_param(parsys,'PortHandles'); 55 | thestr = console.GetUpstreamString(pts.Trigger); 56 | actrec.SetParam(blkhdl, 'Name', thestr); 57 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_temp_dsmlib.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_temp_dsmlib 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('temp_dsmlib'); 6 | sam.Pattern = '^(tmpaddio)'; 7 | sam.Callback = @temp_dsmlib; 8 | 9 | end 10 | 11 | function [actrec, success] =temp_dsmlib(cmdstr, console) 12 | actrec=saRecorder;success = false; 13 | optstr = regexprep(cmdstr, 'tmpaddio', ''); 14 | lns = get_param(gcb,'LineHandles'); 15 | pts = get_param(gcb,'PortHandles'); 16 | lnname = get_param(lns.Inport(1),'Name'); 17 | kw = regexprep(lnname, 'VDSM_(\w+?)(Err|Warn)?_flg', '$1'); 18 | cnstbt = console.MapTo('Constant'); 19 | opbt = console.MapTo('Outport'); 20 | termbt = console.MapTo('Terminator'); 21 | gndbt = console.MapTo('Ground'); 22 | option.PropagateString = false; 23 | if optstr=='1' 24 | cnstbt.AddBlockToPort(pts.Inport(2), option, 'Value', ['VDSM_', kw, 'ErrThld1_cnt']); 25 | gndbt.AddBlockToPort(pts.Inport(3)); 26 | opbt.AddBlockToPort(pts.Outport(1), option, 'Name', ['VDSM_', kw, 'ErrAct1_flg']); 27 | termbt.AddBlockToPort(pts.Outport(2)); 28 | elseif optstr=='2' 29 | cnstbt.AddBlockToPort(pts.Inport(2), option, 'Value', ['VDSM_', kw, 'ErrThld1_cnt']); 30 | cnstbt.AddBlockToPort(pts.Inport(3), option, 'Value', ['VDSM_', kw, 'ErrThld2_cnt']); 31 | opbt.AddBlockToPort(pts.Outport(1), option, 'Name', ['VDSM_', kw, 'ErrAct1_flg']); 32 | opbt.AddBlockToPort(pts.Outport(2), option, 'Name', ['VDSM_', kw, 'ErrAct2_flg']); 33 | else 34 | cnstbt.AddBlockToPort(pts.Inport(3), option, 'Value', ['VDSM_', kw, 'WarnThld_cnt']); 35 | cnstbt.AddBlockToPort(pts.Inport(4), option, 'Value', ['VDSM_', kw, 'ErrThld1_cnt']); 36 | cnstbt.AddBlockToPort(pts.Inport(5), option, 'Value', ['VDSM_', kw, 'ErrThld2_cnt']); 37 | opbt.AddBlockToPort(pts.Outport(1), option, 'Name', ['VDSM_', kw, 'WarnAct_flg']); 38 | opbt.AddBlockToPort(pts.Outport(2), option, 'Name', ['VDSM_', kw, 'ErrAct1_flg']); 39 | opbt.AddBlockToPort(pts.Outport(3), option, 'Name', ['VDSM_', kw, 'ErrAct2_flg']); 40 | end 41 | success = true; 42 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_memory.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_memory 2 | %This function is automatically generated to represent the saBlock object that describes the behaviour of the block type 3 | sabt = saBlock('Memory'); 4 | sabt.RoutinePattern = '^memory|mem'; 5 | sabt.RoutinePriority = 20; 6 | sabt.RoutineMethod = 'majorprop_value'; 7 | sabt.BlockPreferOption.ShowName = 'off'; 8 | sabt.BlockPreferOption.Selected = 'off'; 9 | 10 | 11 | % CUSTOMIZE FUNCTIONS, SEE PROGRAMING REFERENCE DOCUMENT FOR DETAIL 12 | %sabt.PropagateUpstreamStringMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 13 | %sabt.PropagateDownstreamStringMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 14 | %sabt.OutportStringMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 15 | %sabt.InportStringMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 16 | %sabt.SetPropertyMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 17 | %sabt.RollPropertyMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 18 | %sabt.AnnotationMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 19 | %sabt.RefineMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 20 | %sabt.DictRenameMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 21 | %sabt.StrReplaceMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 22 | %sabt.AutoSizeMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 23 | %sabt.AlignMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 24 | %sabt.ColorMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 25 | %sabt.CleanMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 26 | %sabt.DataTypeMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 27 | %sabt.ArrangePortMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 28 | %sabt.PlusMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 29 | %sabt.MinusMethod = @SUBFUNCTION/INTEGER/STRING/CELL...; 30 | end 31 | 32 | 33 | 34 | %function actrec = SUBFUNCTION1(blkhdl, varargin) 35 | % % blkhdl: Handle of block to be dealt with 36 | % % actrec: saRecorder object that records the actions for undo and redo, optional 37 | %end 38 | 39 | %function actrec = SUBFUNCTION2(blkhdl, varargin) 40 | % % blkhdl: Handle of block to be dealt with 41 | % % actrec: saRecorder object that records the actions for undo and redo, optional 42 | %end 43 | 44 | -------------------------------------------------------------------------------- /@saConsole/MapTo.m: -------------------------------------------------------------------------------- 1 | function varargout = MapTo(obj, recvr) 2 | 3 | % SAOBJ = MAPTO(OBJ, RECVR) determines the map key, and gets the saObject, saBlock or 4 | % saProtoBlock type definition object 5 | % RECVR may be: 6 | % - handle of a block, line, port, annotation 7 | % - string of map key (blocktype, masktype, blockpath or #protoblock) 8 | % - string of block full path 9 | 10 | saobj = []; 11 | % first try exact match in BlockMap 12 | if isnumeric(recvr) 13 | typ = get_param(recvr,'Type'); 14 | switch typ 15 | case {'line','port','annotation'} 16 | saobj = getkey(obj.BlockMap, typ); 17 | case 'block' 18 | mapkey = saGetBlockMapKey(recvr); 19 | saobj = getkey(obj.BlockMap, mapkey); 20 | otherwise 21 | end 22 | elseif ischar(recvr) 23 | mapkey = saGetBlockMapKey(recvr); 24 | saobj = getkey(obj.BlockMap,mapkey); 25 | else 26 | % DEAD CODE 27 | end 28 | 29 | % if exact map not found in BlockMap, try to locate in ProtoBlocks 30 | if isempty(saobj) 31 | for i=1:numel(obj.ProtoBlocks) 32 | mapkey = obj.ProtoBlocks(i).MapKey; 33 | if ischar(recvr) && ismember(mapkey, {recvr, ['#',recvr]}) 34 | saprotoobj = obj.ProtoBlocks(i);break; 35 | else 36 | try 37 | blkhdl = get_param(recvr, 'Handle'); 38 | if obj.ProtoBlocks(i).Check(blkhdl) 39 | saprotoobj = obj.ProtoBlocks(i);break; 40 | end 41 | end 42 | end 43 | end 44 | end 45 | 46 | % if still failed to map, return a new saBlock object 47 | if isempty(saobj) 48 | saobj = saBlock(recvr); 49 | if exist('saprotoobj', 'var')==1 && ~isempty(saprotoobj) 50 | saobj.UseProto(saprotoobj); 51 | saobj.Console = obj; 52 | end 53 | end 54 | varargout{1} = saobj; 55 | end 56 | 57 | 58 | 59 | function res = getkey(map, key) 60 | ir = strcmp(map(:,1), key); 61 | if any(ir) 62 | res = map{ir, 2}; 63 | else 64 | res = []; 65 | end 66 | end 67 | 68 | % function tf = iskey(map, key) 69 | % tf = any(strcmp(map(:,1), key)); 70 | % end -------------------------------------------------------------------------------- /@saRecorder/AddLine.m: -------------------------------------------------------------------------------- 1 | function lnhdl = AddLine(obj, sys, varargin) 2 | % #1: obj.AddLine(sys, points, name); 3 | % #2: obj.AddLine(sys, srcblock, dstblock, name, port_spec); 4 | % #3: obj.AddLine(sys, srcport, dstport, name); 5 | % #4: obj.AddLine(sys, srcport, dstpos, name); 6 | % #5: obj.AddLine(sys, srcpos, dstport, name); 7 | if isempty(sys) 8 | sys = gcs; 9 | end 10 | arg1sz = size(varargin{1}); 11 | if arg1sz(2)==2 && arg1sz(1)>1 %given points format 12 | sa = saAction('add_line', sys, varargin{:}); 13 | else 14 | [arg1, arg2] = varargin{1:2}; 15 | % given both handle, auto routing mode 16 | if numel(varargin)>2 17 | name = varargin{3}; 18 | else 19 | name=''; 20 | end 21 | if numel(varargin)>3 %it is possible to specify the port number of connection 22 | tmp = varargin{4};n1 = tmp(1);n2 = tmp(2); 23 | else 24 | n1=1;n2=1; 25 | end 26 | mode = 'auto'; 27 | if numel(arg1)==1 28 | if strcmp(get_param(arg1, 'type'), 'block') 29 | pts = get_param(arg1, 'PortHandles'); pt1 = pts.Outport(n1); 30 | else 31 | pt1 = arg1; 32 | end 33 | pos1 = get_param(pt1, 'Position'); 34 | else 35 | mode = 'points'; 36 | pos1 = arg1; 37 | end 38 | if numel(arg2)==1 39 | if strcmp(get_param(arg2, 'type'), 'block') 40 | pts = get_param(arg2, 'PortHandles'); pt2 = pts.Inport(n2); 41 | else 42 | pt2 = arg2; 43 | end 44 | pos2 = get_param(pt2, 'Position'); 45 | else 46 | mode = 'points'; 47 | pos2 = arg2; 48 | end 49 | if strcmp(mode, 'auto') 50 | %varargin = {sys, pt1, pt2, name*} 51 | sa = saAction('add_line', sys, pt1, pt2, name); 52 | else 53 | if pos1(2)==pos2(2) 54 | lnpos = [pos1; pos2]; 55 | else 56 | xmid = ceil((pos1(1)+pos2(1))/2); 57 | lnpos = [pos1; [xmid, pos1(2)]; [xmid, pos2(2)]; pos2]; 58 | end 59 | sa = saAction('add_line', sys, lnpos, name); 60 | end 61 | end 62 | lnhdl = sa.Handle; 63 | obj.PushItem(sa); 64 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_line2fromgoto.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_line2fromgoto 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('script_line2fromgoto'); 6 | sam.Pattern = '^line2fg'; 7 | sam.Callback = @script_line2fromgoto; 8 | 9 | sam.Priority = 20; 10 | 11 | end 12 | 13 | function [actrec, success] =script_line2fromgoto(cmdstr, console) 14 | actrec=saRecorder;success = false; 15 | optstr=strrep(cmdstr,'line2fg',''); 16 | givenname = strtrim(optstr); 17 | lnhdls=saFindSystem(gcs,'line'); 18 | if isempty(lnhdls) 19 | return; 20 | end 21 | btfrom = console.MapTo('From'); 22 | btgoto = console.MapTo('Goto'); 23 | option.PropagateString = false; % do not propagate 24 | option.GetMarginByMouse = false; 25 | for i=1:numel(lnhdls) 26 | % collect informations 27 | if isempty(givenname) 28 | gototag = console.GetUpstreamString(lnhdls(i)); 29 | if isempty(gototag) 30 | gototag = ['line', int2str(i)]; 31 | end 32 | else 33 | gototag = givenname; 34 | end 35 | dstpts = get_param(lnhdls(i),'DstPortHandle'); 36 | srcpt = get_param(lnhdls(i),'SrcPortHandle'); 37 | srclinepoints = shorten_line(lnhdls(i)); 38 | % start take action 39 | actrec.DeleteLine(lnhdls(i)); 40 | newsrclnhdl = actrec.AddLine(gcs, srclinepoints); 41 | [actrec2, gotoblock] = btgoto.AddBlockToLine(newsrclnhdl, option, 'GotoTag', gototag); 42 | actrec + actrec2; 43 | fcolor = get_param(gotoblock, 'ForegroundColor'); 44 | option.Color = false; % turn off auto color behaviour 45 | for k=1:numel(dstpts) 46 | actrec + btfrom.AddBlockToPort(dstpts(k), option, 'GotoTag', gototag, 'ForegroundColor', fcolor); 47 | end 48 | end 49 | success = true; 50 | end 51 | 52 | function newpts = shorten_line(lnhdl) 53 | lnpoints = get_param(lnhdl,'Points'); 54 | tmppts=lnpoints(1:2,:); 55 | vec = lnpoints(2,:)-lnpoints(1,:);pn = vec; 56 | pn(pn>0)=1; pn(pn<0)=-1; 57 | tmppts(2,:) = tmppts(1,:) + min(abs(vec), [20, 10]).*pn; 58 | if tmppts(1,2)==tmppts(2,2) 59 | newpts = tmppts; 60 | else 61 | newpts = [tmppts; tmppts(2,:)+[15,0]]; 62 | end 63 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_datacompare.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_datacompare 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('script_datacompare'); 6 | sam.Pattern = '^datacompare'; 7 | sam.Callback = @script_datacompare; 8 | 9 | end 10 | 11 | function [actrec, success] =script_datacompare(cmdstr, console) 12 | actrec=saRecorder;success = false; 13 | 14 | if ~strcmpi(get_param(gcb,'BlockType'),'SubSystem') 15 | return; 16 | end 17 | opblks = find_system(gcb,'FollowLinks','on','LookUnderMasks','on','SearchDepth',1,'BlockType','Outport'); 18 | pts=get_param(gcb,'PortHandles'); 19 | pts = pts.Outport; 20 | for i=1:numel(pts) 21 | if get_param(pts(i),'Line')~=-1 22 | continue; 23 | end 24 | ptpos=get_param(pts(i),'Position'); 25 | signame = get_param(opblks{i},'Name'); 26 | blk_inport = add_block(['built-in/Inport'], [gcs, '/', signame], 'MakeNameUnique', 'on', 'Position', [ptpos(1)+25,ptpos(2)+13,ptpos(1)+25+30,ptpos(2)+13+14]); 27 | blk_dtcnv = add_block(['built-in/DataTypeConversion'], [gcs, '/conv_', signame], 'MakeNameUnique', 'on', 'Position', [ptpos(1)+80,ptpos(2)+12,ptpos(1)+80+50,ptpos(2)+12+16], 'ShowName','off'); 28 | blk_mux = add_block(['built-in/Mux'], [gcs, '/mux_', signame], 'MakeNameUnique', 'on', 'Position', [ptpos(1)+180,ptpos(2)-10,ptpos(1)+180+5,ptpos(2)-10+40], 'ShowName','off','DisplayOption','bar','Inputs','2'); 29 | blk_scope = add_block(['built-in/Scope'], [gcs, '/Scope_', signame], 'MakeNameUnique', 'on', 'Position', [ptpos(1)+210,ptpos(2)-5,ptpos(1)+210+30,ptpos(2)-5+30], 'LimitDataPoints','off'); 30 | pts_inport = get_param(blk_inport,'PortHandles'); 31 | pts_dtcnv = get_param(blk_dtcnv,'PortHandles'); 32 | pts_mux = get_param(blk_mux,'PortHandles'); 33 | pts_scope = get_param(blk_scope,'PortHandles'); 34 | add_line(gcs,pts(i),pts_mux.Inport(1),'autorouting','on'); 35 | add_line(gcs,pts_inport.Outport(1),pts_dtcnv.Inport(1),'autorouting','on'); 36 | add_line(gcs,pts_dtcnv.Outport(1),pts_mux.Inport(2),'autorouting','on'); 37 | add_line(gcs,pts_mux.Outport(1),pts_scope.Inport(1),'autorouting','on'); 38 | end 39 | 40 | success = true; 41 | end -------------------------------------------------------------------------------- /@saProtoBlock/AutoSize.m: -------------------------------------------------------------------------------- 1 | function actrec = AutoSize(obj, blkhdl) 2 | actrec = saRecorder; 3 | if isempty(obj.AutoSizeMethod) 4 | return; 5 | else 6 | if isequal(obj.AutoSizeMethod, -1) % downwards extend based on port spacing 7 | actrec = resize_height(blkhdl, obj.LayoutSize); 8 | elseif isequal(obj.AutoSizeMethod, -2) % leftwards extend based on string of major property 9 | actrec = resize_leftwards(blkhdl, obj.LayoutSize, get_param(blkhdl, obj.GetMajorProperty(blkhdl))); 10 | elseif isequal(obj.AutoSizeMethod, -3) % rightwards extend based on string of major property 11 | actrec = resize_rightwards(blkhdl, obj.LayoutSize, get_param(blkhdl, obj.GetMajorProperty(blkhdl))); 12 | elseif isa(obj.AutoSizeMethod, 'function_handle') 13 | nn = nargout(obj.AutoSizeMethod); 14 | ni = nargin(obj.AutoSizeMethod); 15 | argsin = {blkhdl, obj.LayoutSize, obj}; 16 | if nn~=0 %if mandatory output exist, must be saRecorder 17 | actrec.Merge(obj.AutoSizeMethod(argsin{1:ni})); 18 | else 19 | obj.AutoSizeMethod(argsin{1:ni}); 20 | end 21 | else 22 | end 23 | end 24 | end 25 | 26 | 27 | function actrec = resize_height(blkhdl, szlayout) 28 | actrec = saRecorder; 29 | ptcnt = get_param(blkhdl, 'Ports'); 30 | if ptcnt(1)<2 && ptcnt(2)<2 31 | return; 32 | end 33 | oldpos = get_param(blkhdl, 'Position'); 34 | h2 = szlayout.PortSpacing * max([ptcnt(1:2), 2]); 35 | newpos = oldpos; 36 | newpos(4) = newpos(2)+h2; 37 | actrec.SetParam(blkhdl, 'Position', newpos); 38 | end 39 | 40 | function actrec = resize_leftwards(blkhdl, szlayout, majorpropval) 41 | actrec = saRecorder; 42 | oldpos = get_param(blkhdl, 'Position'); 43 | w2 = szlayout.CharWidth*(numel(majorpropval)+3); 44 | newpos = oldpos; 45 | newpos(1) = newpos(3)-w2; 46 | actrec.SetParam(blkhdl, 'Position', saRectifyPos(newpos)); 47 | end 48 | 49 | function actrec = resize_rightwards(blkhdl, szlayout, majorpropval) 50 | actrec = saRecorder; 51 | oldpos = get_param(blkhdl, 'Position'); 52 | w2 = szlayout.CharWidth*(numel(majorpropval)+3); 53 | newpos = oldpos; 54 | newpos(3) = newpos(1)+w2; 55 | actrec.SetParam(blkhdl, 'Position', newpos); 56 | end -------------------------------------------------------------------------------- /@saCmdParser/ParseSeqExpr.m: -------------------------------------------------------------------------------- 1 | function seq = ParseSeqExpr(obj, strin) 2 | % check bracket sequence expression [] 3 | % Allows sequence expression in bracket includes ("#" indicates number(s)): 4 | % "#:#", #:#:#, A:#:Z, a:#:z, "STR1, STR2, STR3", "STR1 STR2 STR3" and mix 5 | % of the above 6 | % Examples: 7 | % "PRE[1:10]TAIL", "PRE[1:2:10,AA,BB,CC]TAIL" 8 | % "PRE[a:e]TAIL, "PRE[a:3:z]TAIL", "PRE[AA,BB,CC,A:3:Z]TAIL" 9 | if nargin<2 10 | strin = obj.OptionStr; 11 | end 12 | [seqstrs,pre_trail] = regexp(strin, '\[([\w\s,:]+)\]','tokens','split'); 13 | if isempty(seqstrs) 14 | seq = {strin}; return; 15 | end 16 | seqparts = cell(size(seqstrs)); 17 | for k=1:numel(seqstrs) 18 | seqstr = seqstrs{k}{1}; 19 | seqel = regexp(seqstr, '\s|,','split'); 20 | seq_part = {}; 21 | for i=1:numel(seqel) 22 | if isempty(seqel) 23 | continue; 24 | end 25 | % convert number pattern into string if necessary, like 1:5, 1:2:9 26 | tmpseqpat1 = regexp(seqel{i}, '\d+:(\d+:)?\d+', 'match','once'); 27 | if ~isempty(tmpseqpat1) 28 | seqnum = eval(tmpseqpat1); 29 | seq_part = [seq_part, arrayfun(@int2str, seqnum, 'UniformOutput',false)]; 30 | else 31 | % convert number pattern into string if necessary, like A:E, a:2:k 32 | tmpseqpat2 = regexp(seqel{i}, '[A-Za-z]:(\d+:)?[A-Za-z]', 'match','once'); 33 | if ~isempty(tmpseqpat2) 34 | tmpseqpat2 = eval(regexprep(tmpseqpat2, '([A-Za-z]):(\d+:)?([A-Za-z])', '''$1'':$2''$3''')); 35 | seq_part = [seq_part, arrayfun(@(x)x, tmpseqpat2, 'UniformOutput',false)]; 36 | else 37 | seq_part = [seq_part, seqel{i}]; 38 | end 39 | end 40 | seqparts{k} = seq_part; 41 | end 42 | end 43 | % extend align with the longest sequence 44 | cnt_max = max(cellfun(@numel, seqparts)); 45 | for i=1:numel(seqparts) 46 | tmp = repmat(seqparts{i}, 1, ceil(cnt_max/numel(seqparts{i}))); 47 | seqparts{i} = tmp(1:cnt_max); 48 | end 49 | % 50 | [tmpvarlist{1:2:2*numel(pre_trail)-1}] = deal(pre_trail{:}); 51 | [tmpvarlist{2:2:2*numel(pre_trail)-1}] = deal(seqparts{:}); 52 | seq = strcat(tmpvarlist{:}); 53 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_queryexplanation.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_queryexplanation 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('script_queryexplanation'); 6 | sam.Pattern = '^\?'; 7 | sam.Callback = @script_queryexplanation; 8 | 9 | end 10 | 11 | function [actrec, success] =script_queryexplanation(cmdstr, console) 12 | actrec=saRecorder;success = false; 13 | 14 | nameprop={ 15 | 'Constant', 'Value'; 16 | 'Goto', 'GotoTag'; 17 | 'From', 'GotoTag'; 18 | 'SubSystem', 'Name'; 19 | 'Lookup', 'Table'; 20 | 'Lookup2D', 'Table'; 21 | 'UnitDelay', 'X0'; 22 | 'Interpolation_n-D','Table'; 23 | 'Prelookup', 'BreakpointsData'; 24 | 'Inport', 'Name'; 25 | 'Outport', 'Name'; 26 | 'DataStoreMemory', 'DataStoreName'; 27 | 'DataStoreWrite', 'DataStoreName'; 28 | 'DataStoreRead', 'DataStoreName'; 29 | }; 30 | blktype=get_param(gcb,'BlockType'); 31 | p=nameprop(strcmp(blktype, nameprop(:,1)),:); 32 | opt = strtrim(cmdstr(2:end)); 33 | if ~isempty(opt) && opt(1) == '>' % > means modify the block annotation 34 | opt = opt(2:end); 35 | opt_anno = true; 36 | else 37 | opt_anno = false; 38 | end 39 | if ~isempty(p)||~isempty(opt) 40 | inca = []; idxtry = 1; 41 | incavers = {'INCA.INCA', 'INCA.INCA.6', 'INCA.INCA.7', 'INCA.INCA.8'}; 42 | while isempty(inca) && idxtryobj.ShowWaitbarThreshold 5 | hwtbar=waitbar(0,sprintf('Adding <%s> block to ...',obj.BlockType)); 6 | end 7 | 8 | % adjust block position according to mouse position 9 | if numel(hdls)>0 10 | lnhdls = hdls(strcmp(get_param(hdls, 'Type'), 'line')); 11 | if ~isempty(lnhdls) 12 | if obj.Console.RunOption.GetMarginByMouse 13 | c_lnpts = get_param(lnhdls, 'Points'); 14 | if ~iscell(c_lnpts) 15 | c_lnpts = {c_lnpts}; 16 | end 17 | ps = cat(1, c_lnpts{:}); 18 | ymx = max(ps(:,2)); ymn = min(ps(:,2)); 19 | xy0 = saGetMousePosition; 20 | % prepare local option 21 | local_opt.ToLineOffset = obj.LayoutSize.ToLineOffset; 22 | if xy0(2)>ymx 23 | local_opt.ToLineOffset(2) = xy0(2)-ymx; 24 | elseif xy0(2)obj.ShowWaitbarThreshold 39 | waitbar(i/total,hwtbar,sprintf('Adding <%s> block to %s...',obj.BlockType,strrep(getfullname(hdls(i)),'_','\_'))); 40 | end 41 | 42 | if strcmp(get_param(hdls(i), 'Type'), 'line') 43 | actrec + obj.AddBlockToLine(hdls(i),varargin{:}); 44 | elseif strcmp(get_param(hdls(i), 'Type'), 'port') 45 | if get_param(hdls(i),'Line')<0 46 | actrec + obj.AddBlockToPort(hdls(i),varargin{:}); 47 | end 48 | elseif strcmp(get_param(hdls(i), 'Type'), 'block') 49 | pts = get_param(hdls(i),'PortHandles'); 50 | for k=1:numel(pts.Outport) 51 | if get_param(pts.Outport(k),'Line')<0 52 | actrec + obj.AddBlockToPort(pts.Outport(k),varargin{:}); 53 | end 54 | end 55 | end 56 | end 57 | if total>obj.ShowWaitbarThreshold 58 | close(hwtbar); 59 | end 60 | end -------------------------------------------------------------------------------- /_MacroRegistration/regmacro_script_ovrd.m: -------------------------------------------------------------------------------- 1 | function sam = regmacro_script_ovrd 2 | %REGMACRO_??? 3 | % Registration of ??? macro in SimAssist 4 | 5 | sam = saMacro('script_ovrd'); 6 | sam.Pattern = '^ovrd'; 7 | sam.Callback = @script_ovrd; 8 | 9 | end 10 | 11 | function [actrec, success] =script_ovrd(cmdstr, console) 12 | actrec=saRecorder;success = false; 13 | rtsys = gcs; 14 | optstr=strtrim(regexprep(cmdstr,'^ovrd\s*','','once')); 15 | lns = saFindSystem(rtsys, 'line'); 16 | ucpts = saFindSystem(rtsys, 'outport_unconnected'); 17 | 18 | WAITBARTHLD = 5; 19 | total = numel(lns)+numel(ucpts); 20 | if total>WAITBARTHLD 21 | hwtbar=waitbar(0,sprintf('Adding override block to ...')); 22 | showwtbar = true; wtbcntr = 0; 23 | else 24 | showwtbar = false;wtbcntr = 0; 25 | end 26 | 27 | swobj = console.MapTo('Switch'); 28 | cnstobj = console.MapTo('Constant'); 29 | option.PropagateString = false; 30 | option.AutoSize = true; 31 | option.GetMarginByMouse = false; 32 | for i=1:numel(lns) 33 | if showwtbar 34 | wtbcntr = wtbcntr+1; 35 | waitbar(wtbcntr/total,hwtbar,sprintf('Adding override block to line ...')); 36 | end 37 | signame = console.GetUpstreamString(lns(i)); 38 | [actrec2, swblk] = swobj.InsertBlockToLine(lns(i), [3, 1], option); 39 | actrec + actrec2; 40 | swpts = get_param(swblk, 'PortHandles'); 41 | actrec + cnstobj.AddBlockToPort(swpts.Inport(1), option, 'Value', [signame, '_ovrdval']); 42 | actrec + cnstobj.AddBlockToPort(swpts.Inport(2), option, 'Value', [signame, '_ovrdflg'], 'OutDataTypeStr','boolean'); 43 | end 44 | for i=1:numel(ucpts) 45 | if showwtbar 46 | wtbcntr = wtbcntr+1; 47 | waitbar(wtbcntr/total,hwtbar,sprintf('Adding override block to unconnected port ...')); 48 | end 49 | signame = console.GetUpstreamString(ucpts(i)); 50 | swobj.ConnectPort = [3, 1]; %temporarily change to 3rd inport first 51 | [actrec2, swblk] = swobj.AddBlockToPort(ucpts(i), option); 52 | actrec + actrec2; 53 | swobj.ConnectPort = [2, 1]; %restore 54 | swpts = get_param(swblk, 'PortHandles'); 55 | actrec + cnstobj.AddBlockToPort(swpts.Inport(1), option, 'Value', [signame, '_ovrdval']); 56 | actrec + cnstobj.AddBlockToPort(swpts.Inport(2), option, 'Value', [signame, '_ovrdflg'], 'OutDataTypeStr','boolean'); 57 | end 58 | if showwtbar 59 | close(hwtbar); 60 | end 61 | success = true; 62 | end -------------------------------------------------------------------------------- /_BlockRegistration/regblock_demux.m: -------------------------------------------------------------------------------- 1 | function sabt = regblock_demux 2 | %REGTYPE_??? 3 | % Registration of ??? type in SimAssist 4 | 5 | sabt = saBlock('Demux'); 6 | 7 | sabt.RoutineMethod = @routine_demux; 8 | sabt.RoutinePattern = '^demux'; 9 | 10 | sabt.OutportStringMethod = @outport_string; 11 | 12 | sabt.BlockSize = [5, 70]; 13 | 14 | sabt.DefaultParameters = {'DisplayOption', 'bar'}; 15 | 16 | sabt.LayoutSize.PortSpacing = 30; 17 | 18 | sabt.PlusMethod = @(blkhdl, operand) operator_plus_minus(blkhdl, '+', operand); 19 | sabt.MinusMethod = @(blkhdl, operand) operator_plus_minus(blkhdl, '-', operand); 20 | end 21 | 22 | function str = outport_string(pthdl, appdata) 23 | parblk = get_param(pthdl, 'Parent'); 24 | ptnum = get_param(pthdl, 'PortNumber'); 25 | instr = cellstr(appdata.Console.GetUpstreamString(parblk)); 26 | str = [instr, '_D', int2str(ptnum)]; 27 | end 28 | 29 | 30 | function actrec = operator_plus_minus(blkhdl, operator, operand) 31 | actrec = saRecorder; 32 | output0 = str2double(get_param(blkhdl,'Outputs')); 33 | if operator=='+' sn = 1; 34 | else sn = -1; 35 | end 36 | if isempty(operand) % default add/minus 1 37 | output1 = output0 + sn; 38 | else 39 | if isequal(operand, operator) 40 | output1 = max(output0 + sn, 1); 41 | else 42 | operand = str2double(operand); 43 | if isnan(operand) || isempty(operand) 44 | return; 45 | else 46 | output1 = max(output0 + sn*(operand), 1); 47 | end 48 | end 49 | end 50 | actrec.SetParam(blkhdl, 'Outputs', int2str(output1)); 51 | end 52 | 53 | 54 | function [actrec, success] = routine_demux(cmdstr, console) 55 | [actrec, success] = deal(saRecorder, false); 56 | btobj = console.MapTo('Demux'); 57 | %parse input command 58 | cmdpsr = saCmdParser(cmdstr, btobj.RoutinePattern); 59 | [numopt, bclean] = cmdpsr.ParseInteger; 60 | if ~bclean return; end 61 | 62 | if ~isempty(numopt) 63 | actrec + btobj.AddBlock('Outputs', int2str(numopt)); 64 | else 65 | dsthdls = saFindSystem(gcs,'line_receiver'); 66 | if ~isempty(dsthdls) 67 | pvpair = {'Outputs', int2str(numel(dsthdls))}; 68 | autoline = true; 69 | else 70 | pvpair = {}; 71 | autoline = false; 72 | end 73 | [actrec2, blkhdl] = btobj.AddBlock(pvpair{:}); actrec + actrec2; 74 | if autoline 75 | actrec.MultiAutoLine(blkhdl, dsthdls); 76 | end 77 | end 78 | success = true; 79 | end -------------------------------------------------------------------------------- /@saBlockGroup/StraightenLinesInside.m: -------------------------------------------------------------------------------- 1 | function actrec=StraightenLinesInside(objs) 2 | actrec=saRecorder; 3 | for kk=1:numel(objs) 4 | obj=objs(kk); 5 | lns=[]; 6 | for i=1:obj.BlockCount 7 | tmpln=get_param(obj.BlockHandles(i),'LineHandles'); 8 | lns=[lns;tmpln.Inport';tmpln.Outport']; 9 | end 10 | lns=unique(lns(lns>0)); %get all the lines 11 | tmpvar1=get_param(lns,'LineParent'); 12 | if iscell(tmpvar1) 13 | tmpvar1=cell2mat(tmpvar1); 14 | end 15 | trunklns=lns(tmpvar1<0); 16 | branchlns=get_param(trunklns,'LineChildren'); 17 | if iscell(branchlns) 18 | branchlns=cell2mat(branchlns); 19 | end 20 | for i=1:numel(trunklns) %first handle the trunk lines 21 | lnpoints=get_param(trunklns(i),'Points'); 22 | dstpts=get_param(trunklns(i),'DstPortHandle'); 23 | if numel(dstpts)>1 24 | for jj=1:numel(dstpts)%discard those that has only one inport and no outport 25 | if dstpts(jj)<0 26 | continue; 27 | end 28 | dstblk=get_param(dstpts(jj),'Parent'); 29 | dstblkptnum=get_param(dstblk,'Ports'); 30 | if dstblkptnum(1)==1&&dstblkptnum(2)==0 31 | dstpts(jj)=-1; %mark as -1 32 | end 33 | end 34 | dstpts=dstpts(dstpts>0); 35 | end 36 | if numel(dstpts)==1 && dstpts>0%only when single valid port left 37 | ptpos=get_param(dstpts,'Position'); 38 | if lnpoints(1,2)~=ptpos(2) %if source port and dest port not aligned 39 | newlnpoints=[lnpoints(1,:);lnpoints(2,1),lnpoints(1,2);lnpoints(2,1),ptpos(2);lnpoints(end,1),ptpos(2)]; %4 points pattern 40 | else 41 | newlnpoints=[lnpoints(1,:);lnpoints(end,1),ptpos(2)]; %2 points straight line pattern 42 | end 43 | actrec.SetParam(trunklns(i),'Points',newlnpoints); 44 | end 45 | end 46 | for i=1:numel(branchlns) % then neaten the branch lines 47 | lnpoints=get_param(branchlns(i),'Points'); 48 | if lnpoints(1,2)~=lnpoints(end,2) 49 | newlnpoints=[lnpoints(1,:);lnpoints(2,1),lnpoints(1,2);lnpoints(2,1),lnpoints(end,2);lnpoints(end,:)]; 50 | else 51 | newlnpoints=[lnpoints([1,end],:)]; 52 | end 53 | actrec.SetParam(branchlns(i),'Points',newlnpoints); 54 | end 55 | end 56 | end -------------------------------------------------------------------------------- /@saProtoBlock/CreateBroBlock.m: -------------------------------------------------------------------------------- 1 | function actrec = CreateBroBlock(obj, blkhdl, varargin) 2 | % obj.CreateBroBlock(blkhdl) creates bro-block by default 3 | % obj.CreateBroBlock(blkhdl, cnnttype) creates bro-block of specified type 4 | % obj.CreateBroBlock(blkhdl, cnnttype, PROP1, VAL1, PROP2, VAL2, ...) using the prop-value pairs in when creating 5 | % obj.CreateBroBlock(blkhdl, cnnttype, POSTFUN) suffix with the post-process function handle 6 | 7 | actrec = saRecorder; 8 | cr_pair_method = obj.CreateBroBlockMethod; 9 | 10 | if isempty(obj.BroBlockType) 11 | return; 12 | elseif isa(cr_pair_method, 'function_handle') 13 | nn = nargout(cr_pair_method); 14 | ni = nargin(cr_pair_method); 15 | varlist = [blkhdl, varargin]; 16 | if nn~=0 %if mandatory output exist, must be saRecorder 17 | actrec.Merge(cr_pair_method(varlist{1:ni})); 18 | else 19 | cr_pair_method(varlist{1:ni}); 20 | end 21 | else 22 | % input parsing 23 | i_strarg = cellfun(@isstr, varargin); 24 | propvals = varargin(i_strarg); 25 | i_fh = cellfun(@(c) isa(c, 'function-handle'), varargin); 26 | postfun = varargin(i_fh); 27 | i_num = cellfun(@(c) isnumeric(c), varargin); 28 | cnnttype = varargin(i_num); 29 | [~, ~, optarg] = override_option(varargin, obj); 30 | optarg.Color = false; 31 | optarg.AutoSize = false; 32 | %use default creation method 33 | majorval=get_param(blkhdl,obj.GetMajorProperty(blkhdl)); 34 | refpos=get_param(blkhdl,'Position'); 35 | fcolor=get_param(blkhdl,'ForegroundColor'); 36 | bcolor=get_param(blkhdl,'BackgroundColor'); 37 | refsz = refpos(3:4) - refpos(1:2); 38 | xy0 = refpos(3:4) + ceil([refsz(1)/3, obj.LayoutSize.VerticalMargin]); 39 | if isempty(cnnttype) 40 | cnnttype = ~obj.ConnectPort; 41 | else 42 | cnnttype = cnnttype{1}; 43 | end 44 | broblktyps = cellstr(obj.BroBlockType); 45 | for i=1:numel(broblktyps) % find the target BroBlockType 46 | brobtobj = obj.Console.MapTo(broblktyps{i}); 47 | if ~any(xor(brobtobj.ConnectPort, cnnttype)) % if match 48 | actrec + brobtobj.AddBlock(xy0, refsz, optarg, ... 49 | obj.GetMajorProperty(blkhdl), majorval,... 50 | 'ForegroundColor',fcolor,... 51 | 'BackgroundColor',bcolor,... 52 | 'Selected','on',... 53 | propvals{:},... 54 | postfun{:}); 55 | break; 56 | end 57 | end 58 | set_param(blkhdl,'Selected','off'); 59 | end 60 | end --------------------------------------------------------------------------------