How to know the contexte (simulation, code generation ...) when running a mask init function?

I got trouble in a bloc with a mask I have created in a personal librairi.
In the mask,I change some block type according to the parameter (set by user in the mask dialog panel).
It alow to change a block input to constant (and resip.) in order to remove inputs when unused.
The code I used is given here:
ParamCheckbox = get_param(gcb,'Pid_En');
BlockName = 'Enable';
MyBlocType = get_param([gcb '/' BlockName],'BlockType');
pos = get_param([gcb '/' BlockName],'Position');
orient = get_param([gcb '/' BlockName],'Orientation');
if(strcmp(ParamCheckbox,'on'))
if(strcmp(MyBlocType,'Constant'))
delete_block([gcb '/' BlockName]);
add_block('built-in/Inport',[gcb '/' BlockName],'Position',pos,'Orientation',orient);
set_param([gcb '/' BlockName],'OutDataTypeStr','boolean');
end
else
if(strcmp(MyBlocType,'Inport'))
delete_block([gcb '/' BlockName]);
add_block('built-in/Constant',[gcb '/' BlockName],'Position',pos,'Orientation',orient);
set_param([gcb '/' BlockName],'OutDataTypeStr','boolean');
set_param([gcb '/' BlockName],'Value','true');
end
end
The problem is that during code generation, the init function is called.
It reset the corresponding port: the input port is removed and set again according to the user selection in dialog panel.
But the line connected to the block are not well "reconnected" to the block and the code generation produce a code where the connection is not done.
And that is not what I expect.
A solution I see is to "read" the execution context in the init function (simulation, code generation ...) and avoid to execute the code during code generation.
Any other solution is of course welcome.
What is strange, is that I allready use the same pattern in other library bloc without trouble.

Réponses (1)

Generally, your mask initialization code should be written in a context-free manner. With the way you've writting your mask initialization function, the connections to the block will be severed every time that the mask initialization code runs. Instead, you should only perform the block replacement if necessary, i.e. the BlockType doesn't match the expected BlockType. You can see the following class for some inspiration on how you can do that:
mf = metafunction("slcontrollib.internal.maskutils.OptionalPortManager");
type(mf.FullPath);
classdef OptionalPortManager < handle %OPTIONALPORTMANAGER Manage optional block inports/outports and labels % OPM = OPTIONALPORTMANAGER(Name,Value) creates a utility object for % programmatically adding/removing optional block inports/outports % and their custom port label display. % % OPTIONALPORTMANAGER properties: % BlockPath - Path of the block being managed % UseMaskDisplay - Flag to use mask display % MaskDisplayString - String for mask display % % OPTIONALPORTMANAGER methods: % changeToInport - Change a block to an inport % changeToGround - Change a block to a ground % changeToConstant - Change a block to a constant % changeToOutport - Change a block to an outport % changeToTerminator - Change a block to a terminator % % Name-Value pair options: % 'BlockPath' - Path of the block (default: gcb) % 'FirstOptionalInport' - Number of first optional inport (default: 1) % 'FirstOptionalOutport' - Number of first optional outport (default: 1) % 'PermanentMaskDisplay' - Permanent mask display string (default: '') % % Example: % % blockDisplay = "fprintf('My Block');"; % blockDisplay = sprintf('%s\n%s', blockDisplay, "port_label('input',1,'u');"); % blockDisplay = sprintf('%s\n%s', blockDisplay, "port_label('output',1,'y');"); % % portManager = OptionalPortManager('BlockPath',gcb,... % 'FirstOptionalInport',2,... % 'FirstOptionalOutport',2,... % 'PermanentMaskDisplay',blockDisplay); % % if UseInportABC % portManager.changeToInport('abc','PortDimensions','[1 1]','SampleTime','Ts'); % else % portManager.changeToGround('abc'); % end % % if UseOutportXYZ % portManager.changeToOutport('xyz','Label','XYZ_{K}','TexMode','on'); % else % portManager.changeToTerminator('xyz'); % end % Copyright 2025 The MathWorks, Inc. %% Properties properties (SetAccess = private) BlockPath (1,1) string = "" MaskDisplayString (1,1) string = "" end properties (SetAccess=immutable) UseMaskDisplay (1,1) logical = true end properties (Access = private) Inport (1,1) double {mustBePositive,mustBeInteger} = 1 Outport (1,1) double {mustBePositive,mustBeInteger} = 1 end methods function obj = OptionalPortManager(arguments) %OPTIONALPORTMANAGER Construct an instance of this class % OBJ = OPTIONALPORTMANAGER(ARGUMENTS) creates an OptionalPortManager % object with the specified name-value pair arguments. % % Name-Value pair arguments: % 'BlockPath' - Path of the block (default: gcb) % 'FirstOptionalInport' - Number of first optional inport (default: 1) % 'FirstOptionalOutport' - Number of first optional outport (default: 1) % 'PermanentMaskDisplay' - Permanent mask display string (default: '') % % See also OPTIONALPORTMANAGER arguments arguments.BlockPath (1,1) string = gcb() arguments.FirstOptionalInport (1,1) double {mustBePositive,mustBeInteger} = 1 arguments.FirstOptionalOutport (1,1) double {mustBePositive,mustBeInteger} = 1 arguments.PermanentMaskDisplay (1,1) string = "" end obj.BlockPath = arguments.BlockPath; obj.Inport = arguments.FirstOptionalInport; obj.Outport = arguments.FirstOptionalOutport; obj.MaskDisplayString = arguments.PermanentMaskDisplay; obj.UseMaskDisplay = strlength(obj.MaskDisplayString)~=0; % always reset mask display first to avoid warning if obj.UseMaskDisplay maskobj = get_param(obj.BlockPath,'MaskObject'); maskobj.Display = ""; end end end %% Public methods methods function h = changeToInport(obj, name, arguments) %CHANGETOINPORT Change a block to an inport % H = CHANGETOINPORT(OBJ, NAME, ARGUMENTS) changes the specified % block to an inport and returns its handle. % % Name-Value pair arguments: % 'PortDimensions' - Dimensions of the port (default: '-1') % 'OutDataTypeStr' - Output data type (default: 'Inherit: auto') % 'SignalType' - Signal type (default: 'auto') % 'SampleTime' - Sample time (default: '-1') % 'Label' - Port label (default: '') % 'TexMode' - TeX mode for label (default: 'off') % % See also OPTIONALPORTMANAGER arguments obj (1,1) slcontrollib.internal.maskutils.OptionalPortManager name (1,1) string arguments.PortDimensions (1,1) string = '-1' arguments.OutDataTypeStr (1,1) string = 'Inherit: auto' arguments.SignalType (1,1) string = 'auto' arguments.SampleTime (1,1) string = '-1' arguments.Label (1,1) string = name arguments.TexMode (1,1) string {mustBeMember(arguments.TexMode,["on";"off"])} = 'off' end %% append mask display obj.MaskDisplayString = sprintf('%s\n%s',obj.MaskDisplayString,... "port_label('input',"+obj.Inport+",'"+arguments.Label+... "','texmode','"+arguments.TexMode+"');"); %% replace ground/constant block with inport block when needed block = obj.BlockPath+"/"+name; if ~strcmp(get_param(block,"BlockType"),'Inport') slInternal('replace_block',block,'built-in/Inport'); end arguments.Port = num2str(obj.Inport); arguments = rmfield(arguments,["Label";"TexMode"]); obj.safeSetParam(block,arguments); %% increase optional port number, return block handle and update mask display obj.Inport = obj.Inport + 1; h = get_param(block,'Handle'); updateMaskDisplay(obj); end function h = changeToGround(obj, name) %CHANGETOGROUND Change a block to a ground % H = CHANGETOGROUND(OBJ, NAME) changes the specified block to a % ground block and returns its handle. % % See also OPTIONALPORTMANAGER arguments obj (1,1) slcontrollib.internal.maskutils.OptionalPortManager name (1,1) string end %% replace inport block with ground block only when needed block = obj.BlockPath+"/"+name; if ~strcmp(get_param(block,"BlockType"),'Ground') slInternal('replace_block',block,'built-in/Ground'); end %% return block handle and update mask display h = get_param(block,'Handle'); updateMaskDisplay(obj); end function h = changeToConstant(obj, name, arguments) %CHANGETOCONSTANT Change a block to a constant % H = CHANGETOCONSTANT(OBJ, NAME, ARGUMENTS) changes the specified % block to a constant block and returns its handle. % % Name-Value pair arguments: % 'Value' - Constant value (default: '1') % 'SampleTime' - Sample time (default: 'inf') % 'VectorParams1D' - 1-D vector parameters (default: 'on') % 'OutDataTypeStr' - Output data type (default: "Inherit: Inherit from 'Constant value'") % % See also OPTIONALPORTMANAGER arguments obj (1,1) slcontrollib.internal.maskutils.OptionalPortManager name (1,1) string arguments.Value (1,1) string = '1' arguments.SampleTime (1,1) string = 'inf' arguments.VectorParams1D (1,1) string = 'on' arguments.OutDataTypeStr (1,1) string = "Inherit: Inherit from 'Constant value'" end %% replace inport block with constant block only when needed block = obj.BlockPath+"/"+name; if ~strcmp(get_param(block,"BlockType"),'Constant') slInternal('replace_block',block,'built-in/Constant'); end obj.safeSetParam(block,arguments); %% return block handle and update mask display h = get_param(block,'Handle'); updateMaskDisplay(obj); end function h = changeToOutport(obj, name, arguments) %CHANGETOOUTPORT Change a block to an outport % H = CHANGETOOUTPORT(OBJ, NAME, ARGUMENTS) changes the specified % block to an outport and returns its handle. % % Name-Value pair arguments: % 'PortDimensions' - Dimensions of the port (default: '-1') % 'OutDataTypeStr' - Output data type (default: 'Inherit: auto') % 'SignalType' - Signal type (default: 'auto') % 'SampleTime' - Sample time (default: '-1') % 'Label' - Port label (default: '') % 'TexMode' - TeX mode for label (default: 'off') % % See also OPTIONALPORTMANAGER arguments obj (1,1) slcontrollib.internal.maskutils.OptionalPortManager name (1,1) string arguments.PortDimensions (1,1) string = '-1' arguments.OutDataTypeStr (1,1) string = 'Inherit: auto' arguments.SignalType (1,1) string = 'auto' arguments.SampleTime (1,1) string = '-1' arguments.Label (1,1) string = name arguments.TexMode (1,1) string {mustBeMember(arguments.TexMode,["on";"off"])} = 'off' end %% append mask display obj.MaskDisplayString = sprintf('%s\n%s',obj.MaskDisplayString,... "port_label('output',"+obj.Outport+",'"+arguments.Label+... "','texmode','"+arguments.TexMode+"');"); %% replace terminator block with inport block only when needed block = obj.BlockPath+"/"+name; if ~strcmp(get_param(block,"BlockType"),'Outport') slInternal('replace_block',block,'built-in/Outport'); end arguments.Port = num2str(obj.Outport); arguments = rmfield(arguments,["Label";"TexMode"]); obj.safeSetParam(block,arguments); %% increase optional port number, return block handle and update mask display obj.Outport = obj.Outport + 1; h = get_param(block,'Handle'); updateMaskDisplay(obj); end function h = changeToTerminator(obj, name) %CHANGETOTERMINATOR Change a block to a terminator % H = CHANGETOTERMINATOR(OBJ, NAME) changes the specified block to a % terminator block and returns its handle. % % See also OPTIONALPORTMANAGER arguments obj (1,1) slcontrollib.internal.maskutils.OptionalPortManager name (1,1) string end %% replace outport block with terminator block only when needed block = obj.BlockPath+"/"+name; if ~strcmp(get_param(block,"BlockType"),'Terminator') slInternal('replace_block',block,'built-in/Terminator'); end %% return block handle and update mask display h = get_param(block,'Handle'); updateMaskDisplay(obj); end end %% Private methods methods (Access = private) function updateMaskDisplay(obj) %% set mask display with custom mask icon and port labels maskObj = get_param(obj.BlockPath,'MaskObject'); if obj.UseMaskDisplay maskObj.Display = sprintf('%s',obj.MaskDisplayString); else maskObj.Display = ""; end end end %% Static private methods methods (Access=private,Static) function safeSetParam(block,paramStruct) %% set parameters without erroring paramStruct = namedargs2cell(paramStruct); try %#ok<TRYNC> set_param(block,paramStruct{:}); end end end end

Catégories

Produits

Version

R2024b

Question posée :

le 24 Juin 2026 à 12:11

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by