1classdef Activity < LayeredNetworkElement
2 % A stage of service in a Task of a LayeredNetwork.
4 % Copyright (c) 2012-2026, Imperial College London
9 hostDemandMean; %
double
10 hostDemandSCV; %
double
14 callOrder; %string \in {
'STOCHASTIC',
'DETERMINISTIC'}
15 syncCallDests = cell(0); %
string array
16 syncCallMeans = []; %integer array
17 asyncCallDests = cell(0); %
string array
18 asyncCallMeans = []; %integer array
20 thinkTime; %Distribution
object
21 thinkTimeMean; %
double
26 %
public methods, including constructor
29 function obj = Activity(model, name, hostDemand, boundToEntry, callOrder)
30 % OBJ = ACTIVITY(MODEL, NAME, HOSTDEMAND, BOUNDTOENTRY, CALLORDER)
32 if nargin<2 %~exist(
'name',
'var')
33 line_error(mfilename,'Constructor requires to specify at least a name.');
35 obj@LayeredNetworkElement(name);
37 if nargin<3 %~exist('hostDemand','var')
38 hostDemand = GlobalConstants.FineTol;
39 elseif isnumeric(hostDemand) && hostDemand == 0
40 hostDemand = GlobalConstants.FineTol;
42 if nargin<4 %~exist('boundToEntry','var')
45 if nargin<5 %~exist('callOrder','var')
46 callOrder = 'STOCHASTIC';
49 obj.setHostDemand(hostDemand);
50 obj.boundToEntry = boundToEntry;
51 obj.setCallOrder(callOrder);
53 % Initialize default think time
54 obj.thinkTime = Immediate.getInstance();
55 obj.thinkTimeMean = GlobalConstants.FineTol;
56 obj.thinkTimeSCV = GlobalConstants.FineTol;
58 if isa(model,'LayeredNetwork')
59 model.activities{end+1} = obj;
61 elseif isa(model,
'JLayeredNetwork')
62 % JLayeredNetwork support would go here
if it exists
63 obj.obj = jline.lang.layered.Activity(model.obj, name, hostDemand, boundToEntry, callOrder);
64 model.addActivity(obj);
68 function obj = setParent(obj, parent)
69 % OBJ = SETPARENT(OBJ, PARENT)
71 if isa(parent,
'Entry') || isa(parent,
'Task')
72 obj.parentName = parent.name;
75 obj.parentName = parent;
80 function self = on(self, parent)
81 % OBJ = ON(OBJ, PARENT)
82 if ~isa(parent,'Task')
83 line_error(mfilename,'Invalid .on() argument: expected a task.')
85 if isempty(self.parent)
86 parent.addActivity(self);
89 line_error(mfilename,'Parent task already defined.')
93 function obj = setHostDemand(obj, hostDemand)
94 % OBJ = SETHOSTDEMAND(OBJ, HOSTDEMAND)
96 if isnumeric(hostDemand)
97 if hostDemand <= GlobalConstants.FineTol
98 obj.hostDemand = Immediate.getInstance();
99 obj.hostDemandMean = GlobalConstants.FineTol;
100 obj.hostDemandSCV = GlobalConstants.FineTol;
102 obj.hostDemand = Exp(1/hostDemand);
103 obj.hostDemandMean = hostDemand;
104 obj.hostDemandSCV = 1.0;
106 elseif isa(hostDemand,'Distribution')
107 obj.hostDemand = hostDemand;
108 obj.hostDemandMean = hostDemand.getMean();
109 obj.hostDemandSCV = hostDemand.getSCV();
113 function obj = repliesTo(obj, entry)
114 % OBJ = REPLIESTO(OBJ, ENTRY)
116 if ~isempty(obj.parent)
117 switch SchedStrategy.fromText(obj.parent.scheduling)
118 case SchedStrategy.REF
119 line_error(mfilename,'Activities in reference tasks cannot reply.');
121 entry.replyActivity{end+1} = obj.name;
124 entry.replyActivity{end+1} = obj.name;
128 function obj = boundTo(obj, entry)
129 % OBJ = BOUNDTO(OBJ, ENTRY)
131 if isa(entry,
'Entry')
132 obj.boundToEntry = entry.name;
134 obj.boundToEntry = entry;
136 line_error(mfilename,'Wrong entry parameter for boundTo method.');
140 function obj = setCallOrder(obj, callOrder)
141 % OBJ = SETCALLORDER(OBJ, CALLORDER)
143 if strcmpi(callOrder,'STOCHASTIC') || strcmpi(callOrder,'DETERMINISTIC')
144 obj.callOrder = upper(callOrder);
146 obj.callOrder = 'STOCHASTIC';
150 function obj = setThinkTime(obj, thinkTime)
151 % OBJ = SETTHINKTIME(OBJ, THINKTIME)
153 if isnumeric(thinkTime)
154 if thinkTime <= GlobalConstants.FineTol
155 obj.thinkTime = Immediate.getInstance();
156 obj.thinkTimeMean = GlobalConstants.FineTol;
157 obj.thinkTimeSCV = GlobalConstants.FineTol;
159 obj.thinkTime = Exp(1/thinkTime);
160 obj.thinkTimeMean = thinkTime;
161 obj.thinkTimeSCV = 1.0;
163 elseif isa(thinkTime,'Distribution')
164 obj.thinkTime = thinkTime;
165 obj.thinkTimeMean = thinkTime.getMean();
166 obj.thinkTimeSCV = thinkTime.getSCV();
172 function obj = synchCall(obj, synchCallDest, synchCallMean)
173 % OBJ = SYNCHCALL(OBJ, SYNCHCALLDEST, SYNCHCALLMEAN)
175 if nargin<3 %~exist('synchCallMean','var')
179 % Get the destination entry name
180 if ischar(synchCallDest)
181 destName = synchCallDest;
183 destName = synchCallDest.name;
186 % Check if this entry
is already in the synchronous call destinations
187 if ~isempty(obj.syncCallDests)
188 for i = 1:length(obj.syncCallDests)
189 if strcmp(obj.syncCallDests{i}, destName)
190 error_msg = sprintf(
'Activity "%s" already has a synchronous call to entry "%s". ', ...
192 error_msg = [error_msg,
'If you intend multiple calls, change the mean number of calls using synchCall(entry, mean_calls) or define an activity graph with explicit precedences.'];
193 line_error(mfilename, error_msg);
198 % Add the
new call destination
199 obj.syncCallDests{length(obj.syncCallDests)+1} = destName;
200 obj.syncCallMeans = [obj.syncCallMeans; synchCallMean];
204 function obj = asynchCall(obj, asynchCallDest, asynchCallMean)
205 % OBJ = ASYNCHCALL(OBJ, ASYNCHCALLDEST, ASYNCHCALLMEAN)
207 if nargin<3 %~exist(
'asynchCallMean',
'var')
208 asynchCallMean = 1.0;
211 % Get the destination entry name
212 if ischar(asynchCallDest)
213 destName = asynchCallDest;
215 destName = asynchCallDest.name;
218 % Check if this entry
is already in the asynchronous call destinations
219 if ~isempty(obj.asyncCallDests)
220 for i = 1:length(obj.asyncCallDests)
221 if strcmp(obj.asyncCallDests{i}, destName)
222 error_msg = sprintf(
'Activity "%s" already has an asynchronous call to entry "%s". ', ...
224 error_msg = [error_msg,
'If you intend multiple calls, change the mean number of calls using asynchCall(entry, mean_calls) or define an activity graph with explicit precedences.'];
225 line_error(mfilename, error_msg);
230 % Add the
new call destination
231 obj.asyncCallDests{length(obj.asyncCallDests)+1} = destName;
232 obj.asyncCallMeans = [obj.asyncCallMeans; asynchCallMean];