classdef SlFunctionInfo < rtw.pil.SlFunctionInfoBase
    % SLFUNCTIONINFO
    %   Container object with information about a Simulink Function needed
    %   for SIL/PIL, obtained from Model Reference MF0.

    % Copyright 2018 The MathWorks, Inc.

    methods
        function obj = SlFunctionInfo(mf0CompFunction, lComponentName)
            % SLFunctionInfo
            
            % Might be "Scoped Export" or "Scoped Local".
            %
            % "Scoped Local" means that it will not need to be pushed up
            % out of the SIL/PIL component.
            %
            % "Scoped Export" means that it will still need to be pushed up
            % since it's exported.
            obj.IsScoped = contains(mf0CompFunction.visibility, 'Scoped Local');
            
            % functionName is always the "non-scoped" (graphical) name
            obj.SlFunctionName = mf0CompFunction.functionName;
            
            % fullPathToFunction combines with functionName to get a unique
            % identifier
            obj.FullPathToSimulinkFunction = mf0CompFunction.fullPathToFunction;
            
            if mf0CompFunction.refBlockPaths.Size > 0
                obj.RefBlockPaths = mf0CompFunction.refBlockPaths.toArray;
            else
                obj.RefBlockPaths = {};
            end
            
            % Get the name of the submodels containing the caller function
            % from the "root" of the block paths, e.g.
            %   deeperCaller/Function Caller
            %   deepCaller/Model
            obj.CalledInModels = unique(strtok(obj.RefBlockPaths, '/'), 'stable');    % strtok works elementwise on cell arrays
            
            obj.IsCalled = mf0CompFunction.callerBlocks.Size > 0;
            
            obj.IsDefined = ~isempty(mf0CompFunction.functionBlock) && ~mf0CompFunction.isDeclarationOnly;
            
            obj.IsOnlyCalledInChildModel = obj.IsCalled && ~obj.IsDefined && ...
                ~ismember(lComponentName, obj.CalledInModels);
            
            % Child callers - wrap in struct for compatibility with
            % down-stream code.
            lChildCallers = mf0CompFunction.childCallers.toArray;
            obj.ChildCallers = {lChildCallers.functionName};
        end
    end
end