%% $Revision.1 $
%% 
%%
%% Copyright 1994-2004 The MathWorks, Inc.
%%
%% Abstract:
%%   Subsystem block target file.
%%

%implements SubSystem "C"

%include "subsystemlib.tlc"

%% Function: BlockInstanceSetup ================================================
%% Abstract:
%%      Create any files that were user specified.
%%      Rename the functions for this system to what the user specifies if
%%      they are unique.
%%
%function BlockInstanceSetup(block, system) void
  %<LibBlockSetIsExpressionCompliant(block)>
  %assign ss = System[CallSiteInfo.SystemIdx]
  %if ss.Type == "function-call"
    %% Check for unconnected function-call inputs, warn or error out.
    %assign allGround = 1
    %foreach idx = ControlInputPort.Width
      %if ControlInputPort.SignalSrc[idx] != "G0"
        %assign allGround = 0
        %break
      %endif
    %endforeach
    %if allGround
      %if CodeFormat == "Embedded-C" && !GenerateGRTWrapper 
        %openfile errTxt
Real-Time Workshop does not guarantee proper execution of models containing \
unconnected function-call inputs.
Try using the Simulink Function-Call Generator block for this subsystem.
        %closefile errTxt
        %<LibBlockReportError(block, errTxt)>
      %else
        %openfile errTxt
Real-Time Workshop does not guarantee proper execution of models containing \
unconnected function-call inputs.
Try using the Simulink Function-Call Generator block for subsystem
%<LibGetFormattedBlockPath(block)>.
        %closefile errTxt
        %selectfile STDOUT

NOTE: %<errTxt>
        %selectfile NULL_FILE
      %endif
    %endif %% if allGround
  %endif
%endfunction %% BlockInstanceSetup


%% Function: BlockInstanceData =================================================
%% Abstract:
%%      Exercise each blocks BlockInstanceData function.  Note that this is
%%      recursive for subsystem blocks.
%%
%function BlockInstanceData(ssBlock, parentSystem) Output
  %assign childSystem = CompiledModel.System[CallSiteInfo.SystemIdx]
  %openfile bufferSS
  %foreach blkIdx = childSystem.NumBlocks
    %openfile buffer

    %<GENERATE(childSystem.Block[blkIdx], "BlockInstanceData", childSystem)>

    %closefile buffer
    %if WHITE_SPACE(buffer) == 0
      {
      \
      %<buffer>\
      }
    %endif
  %endforeach
  %closefile bufferSS
  %if WHITE_SPACE(bufferSS) == 0
    /* Blocks in %<childSystem.Type> subsystem: %<ssBlock.Name> */ \
    %<bufferSS>\
  %endif
%endfunction %% BlockInstanceData


%% Function: Start ============================================================
%% Abstract:
%%      All systems need to generate their virtual start code.
%%
%function Start(ssBlock, parentSystem) Output
  %assign ssType = CompiledModel.System[CallSiteInfo.SystemIdx].Type
  %%
  %% The start function of a function-call subsystem will be generated by
  %% the calling s-function block.
  %%
  %if ssType != "function-call"    
    %assign childSystem = CompiledModel.System[CallSiteInfo.SystemIdx]
    %<LibGenCachedSystemFcnCall(childSystem, "Start", ssBlock.CallSiteIdx)>
  %endif
%endfunction %% Start


%% Function: PrevZCStateSignalDataType =========================================
%% Abstract:
%%   Returns the data type id for the signal related to the previous zero
%%   crossing state.
%function PrevZCStateSignalDataType(block,system) void
  %return LibBlockInputSignalDataTypeId("trigger")
%endfunction


%% Function: InitializeConditions ==============================================
%% Abstract:
%%      Recurses on subsystems that aren't enabled, action, iterator or fcn-call
%%
%function InitializeConditions(ssBlock, parentSystem) Output
  %assign ss = CompiledModel.System[CallSiteInfo.SystemIdx]
  %if ss.Type != "enable" && ss.Type != "enable_with_trigger" ...
    && ss.Type != "action" && ss.Type != "iterator" ...
    && ss.Type != "function-call"
    %if (!LibSystemFcnIsEmpty(ss, "Initialize"))
      %<LibGenSystemFcnCall(ss, "Initialize", ssBlock.CallSiteIdx)>
    %endif
  %endif
%endfunction %% InitializeConditions


%% Function: Update ============================================================
%% Abstract:
%%
%%      Triggered and enable with trigger subsystems are updated as part
%%      of the subsystem's outputs.  Function-call subsystems are called
%%      directly from S-Function block.  These systems therefore do not
%%      require code generation.
%%
%%      Enabled subsystems must generate calls to their subsystem update
%%      method.
%%
%function Update(ssBlock, parentSystem) Output
  %assign ess = CompiledModel.System[CallSiteInfo.SystemIdx]
  %% If this subsystem needs to use TID, then tell it's parent to pass it in.
  %if LibSystemFcnNeedsTID(ess,"Update")
    %<LibNeedTID()>\
  %endif
  %if ess.Type == "enable" || ess.Type == "atomic" || ...
     ((ess.Type == "enable_with_trigger" || ...
      ess.Type == "trigger") && CompiledModel.TrigSSSplitOutUpd)
    %if ISFIELD(ess, "UpdateFcn")
      %%Compute required outputs that are in artificial algebraic loops first
      %if ess.Type == "atomic" && ess.OutputCalledInUpdate == "yes"
        %<FcnAtomicOutput(ssBlock,parentSystem)>
      %endif
      %if !LibSystemFcnIsEmpty(ess,"Update")
        /* %<ess.Type> %<Type> Block: %<Name> */
	%assign tidGuard = ...
	SLibIsRateGrouping() ? "" : FcnUpdateTidGuard(ssBlock, parentSystem)
	%if ess.Type != "atomic" || tidGuard == "" || tidGuard == "1"
	  %<LibGenSystemFcnCall(ess, "Update", ssBlock.CallSiteIdx)>
	%else
	  if (%<tidGuard>) {
	  %<LibGenSystemFcnCall(ess, "Update", ssBlock.CallSiteIdx)>
	  }
	%endif
      %endif %% Non-empty update
    %endif %% has update fcn
  %endif %% enable or atomic subsystem
%endfunction %% Update


%% Function: UpdateForTID ===================================================
%% Abstract:
%%      Same as Update fcn, but only for specific TID
%%      Triggered and enable with trigger subsystems are updated as part
%%      of the subsystem's outputs.  Function-call subsystems are called
%%      directly from S-Function block.  These systems therefore do not
%%      require code generation.
%%
%%      Enabled subsystems must generate calls to their subsystem update
%%      method.
%%
%function UpdateForTID(ssBlock, parentSystem, tid) Output
  %assign ess = CompiledModel.System[CallSiteInfo.SystemIdx]
  %% If this subsystem needs to use TID, then tell it's parent to pass it in.
  %if LibSystemFcnNeedsTID(ess,"Update")
    %<LibNeedTID()>\
  %endif
  %if ess.Type == "enable" || ess.Type == "atomic" || ...
    ((ess.Type == "enable_with_trigger" || ...
      ess.Type == "trigger") && CompiledModel.TrigSSSplitOutUpd)
    %if ISFIELD(ess, "UpdateFcn")
      %%Compute required outputs that are in artificial algebraic loops first
      %if ess.Type == "atomic" && ess.OutputCalledInUpdate == "yes"
        %<FcnAtomicOutputForTID(ssBlock,parentSystem,tid)>
      %endif
      %assign ess.CurrentTID = tid
      %if !LibSystemFcnIsEmptyForTID(ess,"Update")
        /* %<ess.Type> %<Type> Block: %<Name> */
	%<LibGenSystemFcnCall(ess, "Update", ssBlock.CallSiteIdx)>
      %endif %% Non-empty update
      %assign ess.CurrentTID = -1
    %endif %% has update fcn
  %endif %% enable or atomic subsystem
%endfunction %% UpdateForTID



%% Function: Derivatives =======================================================
%% Abstract:
%%      Derivatives only pertain to purely enabled subsystems.
%%
%function Derivatives(ssBlock, parentSystem) Output
  %assign ssType = CompiledModel.System[CallSiteInfo.SystemIdx].Type
  %if ssType == "enable" || ssType == "atomic"
    %assign ess = CompiledModel.System[CallSiteInfo.SystemIdx]
    %assign ncStates = ParamSettings.SystemContStates[0]
    %%Compute required outputs that are in artificial algebraic loops first
    %if ISFIELD(ess, "DerivativeFcn") && ...
      ess.Type == "atomic" && ess.OutputCalledInUpdate == "yes"
	 %<FcnAtomicOutput(ssBlock,parentSystem)>
    %endif
    %if ISFIELD(ess, "DerivativeFcn") && ncStates > 0 && ...
      !LibSystemFcnIsEmpty(ess,"Derivative")
      
      /* %<ssType> %<Type> Block: %<Name> */
      %%
      %% Subsystem block may not have a mode
      %%
      /* compute derivatives */
      %<LibGenSystemFcnCall(ess, "Derivative", ssBlock.CallSiteIdx)>
    %endif
  %endif
%endfunction %% Derivatives


%% Function: Projection =======================================================
%% Abstract:
%%      Projection only pertains to purely enabled subsystems.
%%
%function Projection(ssBlock, parentSystem) Output
  %assign ssType = CompiledModel.System[CallSiteInfo.SystemIdx].Type
  %if ssType == "enable" || ssType == "atomic"
    %assign ess = CompiledModel.System[CallSiteInfo.SystemIdx]
    %assign ncStates = ParamSettings.SystemContStates[0]
    %if ISFIELD(ess, "ProjectionFcn") && ncStates > 0 && ...
      !LibSystemFcnIsEmpty(ess,"Projection")
      /* %<ssType> %<Type> Block: %<Name> */
      %%
      %% Subsystem block may not have a mode
      %%
      /* compute projection */
      %<LibGenSystemFcnCall(ess, "Projection", ssBlock.CallSiteIdx)>
    %endif
  %endif
%endfunction %% Projection


%% Function: ZeroCrossings =====================================================
%% Abstract:
%%      ZeroCrossings only pertain to variable-step solvers.
%%
%function ZeroCrossings(block, parentSystem) Output
  %assign ss = CompiledModel.System[CallSiteInfo.SystemIdx]
  %% Action systems are generated from if/case block, and
  %% they can not be involved in minimizing algebraic loops
  %if ss.Type == "action"
    %return ""
  %endif
  %%Compute required outputs that are in artificial algebraic loops first
  %if ISFIELD(ss, "ZeroCrossingFcn") && ...
    ss.Type == "atomic" && ss.OutputCalledInUpdate == "yes"
      %<FcnAtomicOutput(block,parentSystem)>
  %endif
  %if NumNonsampledZCs > 0  || (ISFIELD(ss, "ZeroCrossingFcn") && ...
    !LibSystemFcnIsEmpty(ss,"ZeroCrossing"))
    %%If enabled or atomic, run the internal blocks that have zero crossing code
    %if ISFIELD(ss, "ZeroCrossingFcn")
      /* %<Type> Block: %<Name> */
      %if LibSystemFcnIsEmpty(ss,"ZeroCrossing")
        %assign errTxt = "Empty ZeroCrossing function but ZCFcn expected."
        %<LibBlockReportFatalError(block, errTxt)>
      %endif
      %if ss.Type == "enable"         %% enable_with_trigger cannot occur
          %<LibGenSystemFcnCall(ss, "ZeroCrossing", block.CallSiteIdx)>
      %else  %% Atomic Subsystem
        /* compute zero crossings */
        %<LibGenSystemFcnCall(ss, "ZeroCrossing", block.CallSiteIdx)>
      %endif
    %endif
  %endif
%endfunction %% ZeroCrossings

%% Function: FcnAtomicOutput ===================================================
%% Abstract:
%%      Generate call to an "atomic" subsystem (i.e. a system which always
%%      runs. The same task id scoping rules for an enabled subsystem apply
%%      here.
%%
%%   Call Trace: Outputs -> FcnAtomicOutput
%%
%function FcnAtomicOutput(ssBlock, parentSystem) void
  %assign ss = CompiledModel.System[CallSiteInfo.SystemIdx]
  %openfile outputCodeBuffer
  %%
  %assign tidGuard = ...
    SLibIsRateGrouping() ? "" :  FcnUpdateTidGuard(ssBlock, parentSystem)
  %%
  %if tidGuard == "" || tidGuard == "1"
    %if LibSystemIsInlined(ss)
      %assign openCode  = "{"
      %assign closeCode = "}"
    %else
      %assign openCode  = ""
      %assign closeCode = ""
    %endif
  %else
    %assign openCode  = "if (%<tidGuard>) {"
    %assign closeCode = "}"
  %endif

  %<openCode>
  %<LibGenSystemFcnCall(ss, "Output", ssBlock.CallSiteIdx)>
  %<closeCode>

  %closefile outputCodeBuffer
  %%
  %return outputCodeBuffer
%endfunction %% FcnAtomicOutput

%% Function: FcnAtomicOutputForTID =========================================
%% Abstract:
%%      Generate call to an "atomic" subsystem for specific TID.
%%      Only code matches the tid will be output. Since this code
%%      is used in rate grouping code, tidGard is not needed.
%%
%%   Call Trace: OutputsForTID -> FcnAtomicOutputForTID
%%
%function FcnAtomicOutputForTID(ssBlock, parentSystem,tid) void
  %assign ss = CompiledModel.System[CallSiteInfo.SystemIdx]
  %openfile outputCodeBuffer
  %%
  %assign ss.CurrentTID = tid
  %<LibGenSystemFcnCall(ss, "Output", ssBlock.CallSiteIdx)>
  %assign ss.CurrentTID = -1
  %%
  %closefile outputCodeBuffer
  %%
  %return outputCodeBuffer
%endfunction %% FcnAtomicOutput
  
%% Function: FcnIteratorOutput =================================================
%% Abstract:
%%   Generates the output code required to execute an iterator system
%%   which is either a for or while subsystem.
%%   Call Trace: Outputs -> FcnIteratorOutput
%%
%function FcnIteratorOutput(ssBlock, parentSystem) void
  %assign ss           = CompiledModel.System[CallSiteInfo.SystemIdx]
  %assign NeedTIDGuard = (ssBlock.ParamSettings.IteratorScope == "NeedTIDScope")
  %openfile outputCodeBuffer
  %%
  %if NeedTIDGuard
    %assert SIZE(SubsystemTID, 1) == 1
    %<FcnGenerateTidGuardOpenCode(SubsystemTID[0])>
  %endif
  %<LibGenSystemFcnCall(ss, "OutputUpdate", ssBlock.CallSiteIdx)>
  %if NeedTIDGuard
    %<FcnGenerateTidGuardCloseCode(SubsystemTID[0])> 
  %endif
  %%
  %closefile outputCodeBuffer
  %%
  %return outputCodeBuffer
%endfunction %% FcnIteratorOutput

%% Function: FcnGenTrigSysTidGuardOpen(ssBlock) 
%%
%%
%function FcnGenTrigSysTidGuardOpen(ssBlock) void
  %openfile retBuf
  %assign tid = ssBlock.SubsystemTID
  
  %if SLibIsRateGrouping() || LibTriggeredTID(tid) ...
    || ISEQUAL(tid,"constant")
    %% don't need tid guard
  %else
    %assign tidGuard = LibIsSampleHit(SubsystemTID)
    %if (tidGuard !="1") 
      if (%<tidGuard>) {
    %endif
  %endif
  %closefile retBuf
  
  %return retBuf
%endfunction %% FcnGenTrigSysTidGuardOpen(ssBlock)


%% Function: FcnGenTrigSysTidGuardClose(ssBlock)
%%
%%
%function FcnGenTrigSysTidGuardClose(ssBlock) void
  %openfile retBuf
  %assign tid = ssBlock.SubsystemTID
  
  %if SLibIsRateGrouping() || LibTriggeredTID(tid) ...
    || ISEQUAL(tid,"constant")
    %% don't need tid guard
  %else
    %assign tidGuard = LibIsSampleHit(SubsystemTID)
    %if (tidGuard !="1") 
      }
    %endif
  %endif
  %closefile retBuf
  
  %return retBuf
%endfunction %% FcnGenTrigSysTidGuardClose(ssBlock)


%% Function: Outputs ===========================================================
%% Abstract:
%%      Generate the call to the system function (providing the system
%%      function is non-empty).
%%
%function Outputs(ssBlock, parentSystem) void

  %assign ss = CompiledModel.System[CallSiteInfo.SystemIdx]

  %assign fcnStr = CompiledModel.TrigSSSplitOutUpd ? "Output" : "OutputUpdate"
  
  %%
  %% If this subsystem needs to use TID, then tell it's parent to pass it as
  %% an argument to the subsystem function. For function-call subsystems,
  %% if caller s-fcn is inlined, no need to propagate if value is used, for
  %% non-inlined, gensfun.tlc will set NeedTID.
  %%
  %if ss.Type != "function-call" && ...
    (LibSystemFcnNeedsTID(ss, "OutputUpdate") || ...
    LibSystemFcnNeedsTID(ss, "Output"))
    %<LibNeedTID()>\
  %endif

  %%
  %% Determine if system functions are empty
  %%
  %switch ss.Type
    %case "trigger"
       %assign fcnIsEmpty = ...
        (...
	LibSystemFcnIsEmpty(ss, fcnStr) && ...
	ss.TriggerBlkIdx == -1 ...
        ) ? 1 : 0    
      %break

    %case "enable"
      %assign fcnIsEmpty = ...
        (...
        LibSystemFcnIsEmpty(ss, "Output")...
        ) ? 1 : 0
      %break

    %case "enable_with_trigger"
      %assign fcnIsEmpty = ...
        (...
        LibSystemFcnIsEmpty(ss, fcnStr) && ...
	ss.TriggerBlkIdx == -1 ...
	) ? 1 : 0
      %break

    %case "atomic"
      %assign fcnIsEmpty = ...
        (...
        LibSystemFcnIsEmpty(ss, "Output") ...
        ) ? 1 : 0
      %break

    %% action subsystems are not handled here (the if or switch block
    %% takes care of them)
    %case "action"
      %return ""

    %% iterator subsystems are never empty
    %case "iterator"
      %assign fcnIsEmpty = ...
        (...
        LibSystemFcnIsEmpty(ss, "OutputUpdate") ...
        ) ? 1 : 0
      %break

    %case "function-call"
      %% function-calls subsystems not executed by Simulink
      %return ""

    %default
      %assign errTxt = "Unknown system type: %<ss.Type>"
      %<LibBlockReportFatalError(ssBlock, errTxt)>
  %endswitch

  %if fcnIsEmpty
    %% System functions are empty
    %return ""
  %else
    %% System functions are not empty
    %openfile tmpBuffer
    %assign sfTxt = ""
    %if EXISTS("ssBlock.MaskType")
      %if ssBlock.MaskType == "Stateflow"
        %assign sfTxt = "Stateflow"
      %endif
    %endif
    %switch ss.Type
      %case "trigger"
	%if sfTxt != ""
	  /* %<ss.Type> %<sfTxt> Block: %<Name> */
	%endif
	%<FcnGenTrigSysTidGuardOpen(ssBlock)>
	%<LibGenSystemFcnCall(ss, fcnStr, ssBlock.CallSiteIdx)>
	%<FcnGenTrigSysTidGuardClose(ssBlock)>
	%break
      %case "enable"
	%<LibGenSystemFcnCall(ss, "Output", ssBlock.CallSiteIdx)>
	%break
      %case "enable_with_trigger"
	%<FcnGenTrigSysTidGuardOpen(ssBlock)>
        %<LibGenSystemFcnCall(ss, fcnStr, ssBlock.CallSiteIdx)>
	%<FcnGenTrigSysTidGuardClose(ssBlock)>
        %break
      %case "iterator"
	%<FcnIteratorOutput(ssBlock, parentSystem)>
        %break
      %case "atomic"
	%if ss.CalledByBlock == "no" && ss.OutputCalledInUpdate == "no"
	  %<FcnAtomicOutput(ssBlock,parentSystem)>
	%endif
      %default
    %endswitch

    %closefile tmpBuffer
  %endif

  %return tmpBuffer
%endfunction %% Outputs


%% Function: OutputsForTID ===================================================
%% Abstract:
%%      Generate the call to the system function (providing the system
%%      function is non-empty) for specific TID.
%%
%function OutputsForTID(ssBlock, parentSystem,tid) void

  %assign ss            = CompiledModel.System[CallSiteInfo.SystemIdx]
  %assign ss.CurrentTID = tid
  %assign fcnStr        = CompiledModel.TrigSSSplitOutUpd ? ...
    "Output" : "OutputUpdate"
  
  %%
  %% If this subsystem needs to use TID, then tell it's parent to pass it as
  %% an argument to the subsystem function. For function-call subsystems,
  %% if caller s-fcn is inlined, no need to propagate if value is used, for
  %% non-inlined, gensfun.tlc will set NeedTID.
  %%
  %if ss.Type != "function-call" && ...
    (LibSystemFcnNeedsTID(ss, "OutputUpdate") || ...
    LibSystemFcnNeedsTID(ss, "Output"))
    %<LibNeedTID()>\
  %endif

  %%
  %% Determine if system functions are empty
  %%

  %switch ss.Type
    %case "trigger"
      %if LibAsynchronousTriggeredTID(tid) 
	%assign fcnIsEmpty = ...
	  (...
	  LibSystemFcnIsEmptyForTID(ss, fcnStr) ...
	  && ss.TriggerBlkIdx == -1 ...
	  ) ? 1 : 0
      %else
	%assign fcnIsEmpty = ...
	  (...
	  LibSystemFcnIsEmpty(ss, fcnStr) ...
	  && ss.TriggerBlkIdx == -1 ...
	  ) ? 1 : 0
      %endif
      %break

    %case "enable"
      %assign fcnIsEmpty = ...
        (...
        LibSystemFcnIsEmptyForTID(ss, "Output")...
        ) ? 1 : 0
      %break
      
    %case "enable_with_trigger"
      %assign fcnIsEmpty = ...
        (...
        LibSystemFcnIsEmptyForTID(ss, fcnStr) && ...
	ss.TriggerBlkIdx == -1 ...
	) ? 1 : 0
      %break

    %case "atomic"
      %assign fcnIsEmpty = ...
        (...
        LibSystemFcnIsEmptyForTID(ss, "Output") ...
        ) ? 1 : 0
      %break

    %% action subsystems are not handled here (the if or switch block
    %% takes care of them)
    %case "action"
      %return ""

    %% iterator subsystems are never empty
    %case "iterator"
      %assign fcnIsEmpty = ...
        (...
        LibSystemFcnIsEmptyForTID(ss, "OutputUpdate") ...
        ) ? 1 : 0
      %break

    %case "function-call"
      %% function-calls subsystems not executed by Simulink
      %return ""

    %default
      %assign errTxt = "Unknown system type: %<ss.Type>"
      %<LibBlockReportFatalError(ssBlock, errTxt)>
  %endswitch

  %if fcnIsEmpty
    %% System functions are empty
    %assign ss.CurrentTID = -1
    %return ""
  %else
    %% System functions are not empty
    %openfile tmpBuffer
    %assign sfTxt = ""
    %if EXISTS("ssBlock.MaskType")
      %if ssBlock.MaskType == "Stateflow"
        %assign sfTxt = "Stateflow"
      %endif
    %endif
    %switch ss.Type
      %case "trigger"
	%if sfTxt != ""
	  /* %<ss.Type> %<sfTxt> Block: %<Name> */
	%endif
	%<LibGenSystemFcnCall(ss, fcnStr, ssBlock.CallSiteIdx)>
	%break
      %case "enable"
	%<LibGenSystemFcnCall(ss, "Output", ssBlock.CallSiteIdx)>
        %break
      %case "enable_with_trigger"
	%<LibGenSystemFcnCall(ss, fcnStr, ssBlock.CallSiteIdx)>
        %break
      %case "iterator"
	%<FcnIteratorOutput(ssBlock, parentSystem)>
        %break
      %case "atomic"
	%if ss.CalledByBlock == "no" && ss.OutputCalledInUpdate == "no"
	  %<FcnAtomicOutputForTID(ssBlock,parentSystem,tid)>
	%endif
      %default
    %endswitch

    %closefile tmpBuffer
  %endif
  %assign ss.CurrentTID = -1
  %return tmpBuffer
%endfunction %% OutputsForTID



%% Function: Enable ============================================================
%% Abstract:
%%      If this is a triggered, function-call, or atomic subsystem, then
%%      there is no run-time disable and enable capability, thus we
%%      need to generate the enable code for an internal blocks that
%%      will be run when the system starts.
%%
%%      Essentially, blocks that live inside a non-virtual subsystem that
%%      don't have an enable function must enable themselves at startup.
%%      Otherwise, they would never run since the enable function that
%%      enables the block to run doesn't exist.  This function essentially is
%%      recursive in that it not only enables the blocks inside the
%%      subsystem, but the subsystem block is recursive.
%%
%function Enable(ssBlock, parentSystem) Output
  %assign ss = CompiledModel.System[CallSiteInfo.SystemIdx]
  %if ss.Type != "enable" && ...
    ss.Type != "enable_with_trigger" && ...
    ss.Type != "function-call" && ...
    ss.Type != "action" &&  ...
    ss.Type != "iterator"
    %if (!LibSystemFcnIsEmpty(ss, "Enable"))
      %<LibGenSystemFcnCall(ss, "Enable", ssBlock.CallSiteIdx)>
    %endif
  %endif
%endfunction %% Enable


%% Function: Disable ===========================================================
%% Abstract:
%%      Only enable and enable with trigger systems can become disabled
%%      during execution, thus we need to generate the disable code
%%      for the internal system blocks.
%%
%function Disable(ssBlock, parentSystem) Output
  %assign ss = CompiledModel.System[CallSiteInfo.SystemIdx]
  %if ss.Type == "enable" || ss.Type == "enable_with_trigger"
    %if ModeVector[0] != 0
      %<LibGenOptSystemFcnCall(ss, "Disable", ssBlock.CallSiteIdx)>
    %endif
  %elseif ss.Type != "function-call"
    %<LibGenOptSystemFcnCall(ss, "Disable", ssBlock.CallSiteIdx)>
  %endif
%endfunction %% Disable


%% Function: Terminate =========================================================
%% Abstract:
%%      Exercise each blocks Terminate function.
%%
%function Terminate(ssBlock, parentSystem) Output
  %assign childSystem = CompiledModel.System[CallSiteInfo.SystemIdx]
  %<LibGenCachedSystemFcnCall(childSystem, "Terminate", ssBlock.CallSiteIdx)>
%endfunction %% Terminate

%% [EOF] subsystm.tlc
