classdef InvalidateFunctionInfo < rtw.pil.QueuedIOFunctionInfo
%InvalidateFunctionInfo: representation for Autosar Signal Invalidation interface

% Copyright 2020 The MathWorks, Inc.

properties (SetAccess = 'immutable', GetAccess = 'private')
SlFcnName;
end

methods (Access = {?rtw.pil.CSFunctionInfoFactory})
% Only allow object construction by the factory class
function this = InvalidateFunctionInfo(fcnName, rtmTypeIdentifier, argType, timing, variantInfo,...
tid,...
fcnId,...
isDefined,...
isAUTOSAR, ...
portNumber, ...
mf0ModelInstance, invalidateSLFcnName)

% call superclass constructor
this@rtw.pil.QueuedIOFunctionInfo(fcnName, rtmTypeIdentifier, argType, timing, variantInfo,...
tid,...
fcnId,...
isDefined,...
isAUTOSAR, ...
portNumber, ...
'flag', ...
'INPUT', ...
mf0ModelInstance);

this.SlFcnName = invalidateSLFcnName;
end
end

methods
% Write S-Function Send Api call
function writeCallToFunction(this, writer, simStructArg, argsVarName, ~)

writer.wBlockStart('');
writer.wLine('_ssFcnCallExecArgInfo fcnArgs;')
writer.wLine('fcnArgs.dataPtr = %s;',argsVarName);

writer.wLine('slcsInvokeSimulinkFunction(%s"%s", &fcnArgs);', simStructArg,this.SlFcnName);
writer.wBlockEnd();
end

% Define any arguments needed for the S-Function message send
% call. Need the transferred message data and a return status to
% send back to the target.
function argPointerAccessString = defineArgsForSLCall(this, writer, argVarName) %#ok<INUSL>

argPointerAccessString = ''; %Not Used

writer.writeLine('void* %s;', argVarName);
writer.writeLine('uint_T returnArg = 0;'); %Initialize return value. Set to OK by default
end

% Correctly process the message payload, so it can be passed to the
% Simulink engine via the Message S-function API.
function writeSfunctionDataAssignmentForSLCall(this, sfunObj, writer, argVarName)
writer.wBlockStart('if (ssGetPWork(S) != NULL)');

args = this.getAllCodeInfoArgs;
for codeInfoArgIdx = 1:length(args)

arg = args(codeInfoArgIdx);
if ~strcmp(arg.IOType, 'INPUT')
continue;
end
codeArgPosition = this.getCodeArgPosition(arg);
argDataInterface = this.getDataInterfacesForArgs(codeArgPosition);
writer.wBlockStart(''); % scope around each argument
argPtr = sprintf('%s', argVarName);
pWorkIdx = sfunObj.getCallerFunctionArgumentPWorkIdx(this, argDataInterface);
sfunObj.getPWorkValue('void', argPtr , pWorkIdx, false);

writer.wBlockEnd; % scope around each argument
end
writer.wBlockEnd; %if (ssGetPWork(S) != NULL)
end
end
end