INET Framework for OMNeT++/OMNEST
inet::ScenarioManager Class Reference

Scenario Manager (experimental) which executes a script specified in XML. More...

#include <ScenarioManager.h>

Inheritance diagram for inet::ScenarioManager:

Public Member Functions

 ScenarioManager ()
 

Protected Member Functions

const char * getRequiredAttribute (cXMLElement *node, const char *attr)
 
virtual cModule * getRequiredModule (cXMLElement *node, const char *attr)
 
virtual cGate * getRequiredGate (cXMLElement *node, const char *modattr, const char *gateattr)
 
void createConnection (cXMLElementList &paramList, cChannelType *channelType, cGate *srcGate, cGate *destGate)
 
virtual void processCommand (cXMLElement *node)
 
virtual void processAtCommand (cXMLElement *node)
 
virtual void processSetParamCommand (cXMLElement *node)
 
virtual void processSetChannelAttrCommand (cXMLElement *node)
 
virtual void processCreateModuleCommand (cXMLElement *node)
 
virtual void processDeleteModuleCommand (cXMLElement *node)
 
virtual void processConnectCommand (cXMLElement *node)
 
virtual void processDisconnectCommand (cXMLElement *node)
 
virtual void processModuleSpecificCommand (cXMLElement *node)
 
virtual void initialize () override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void refreshDisplay () const override
 

Protected Attributes

int numChanges = 0
 
int numDone = 0
 

Detailed Description

Scenario Manager (experimental) which executes a script specified in XML.

ScenarioManager has a few built-in commands such as <set-param>, <set-channel-attr>, etc, and can pass commands to modules that implement the IScriptable interface. The <at> built-in command can be used to group commands to be carried out at the same simulation time.

See NED file for details.

See also
IScriptable
Author
Andras Varga

Constructor & Destructor Documentation

inet::ScenarioManager::ScenarioManager ( )
inline
68 {}

Member Function Documentation

void inet::ScenarioManager::createConnection ( cXMLElementList &  paramList,
cChannelType *  channelType,
cGate *  srcGate,
cGate *  destGate 
)
protected

Referenced by processConnectCommand().

221 {
222  if (!channelType)
223  srcGate->connectTo(destGate);
224  else {
225  cChannel *channel = channelType->create("channel");
226 
227  // set parameters:
228  for (auto child : paramList) {
229 
230  const char *name = getRequiredAttribute(child, "name");
231  const char *value = getRequiredAttribute(child, "value");
232  channel->par(name).parse(value);
233  }
234 
235  // connect:
236  srcGate->connectTo(destGate, channel);
237  }
238 }
const char * getRequiredAttribute(cXMLElement *node, const char *attr)
Definition: ScenarioManager.cc:98
const char * inet::ScenarioManager::getRequiredAttribute ( cXMLElement *  node,
const char *  attr 
)
protected

Referenced by createConnection(), getRequiredGate(), getRequiredModule(), processConnectCommand(), processCreateModuleCommand(), processDeleteModuleCommand(), processDisconnectCommand(), processSetChannelAttrCommand(), and processSetParamCommand().

99 {
100  const char *s = node->getAttribute(attr);
101  if (!s)
102  throw cRuntimeError("required attribute %s of <%s> missing at %s",
103  attr, node->getTagName(), node->getSourceLocation());
104  return s;
105 }
value< double, units::s > s
Definition: Units.h:1049
cGate * inet::ScenarioManager::getRequiredGate ( cXMLElement *  node,
const char *  modattr,
const char *  gateattr 
)
protectedvirtual

Referenced by processSetChannelAttrCommand().

117 {
118  cModule *mod = getRequiredModule(node, modAttr);
119  const char *gateStr = getRequiredAttribute(node, gateAttr);
120  std::string gname;
121  int gindex;
122  parseIndexedName(gateStr, gname, gindex);
123  cGate *g = mod->gate(gname.c_str(), gindex);
124  if (!g)
125  throw cRuntimeError("module '%s' has no gate '%s' at %s", mod->getFullPath().c_str(), gateStr, node->getSourceLocation());
126  return g;
127 }
double mod(double dividend, double divisor)
Returns the rest of a whole-numbered division.
Definition: INETMath.h:108
const char * getRequiredAttribute(cXMLElement *node, const char *attr)
Definition: ScenarioManager.cc:98
virtual cModule * getRequiredModule(cXMLElement *node, const char *attr)
Definition: ScenarioManager.cc:107
milli< kg >::type g
Definition: Units.h:900
cModule * inet::ScenarioManager::getRequiredModule ( cXMLElement *  node,
const char *  attr 
)
protectedvirtual

Referenced by getRequiredGate(), processConnectCommand(), processDisconnectCommand(), processModuleSpecificCommand(), and processSetParamCommand().

108 {
109  const char *moduleAttr = getRequiredAttribute(node, attr);
110  cModule *mod = getModuleByPath(moduleAttr);
111  if (!mod)
112  throw cRuntimeError("module '%s' not found at %s", moduleAttr, node->getSourceLocation());
113  return mod;
114 }
double mod(double dividend, double divisor)
Returns the rest of a whole-numbered division.
Definition: INETMath.h:108
const char * getRequiredAttribute(cXMLElement *node, const char *attr)
Definition: ScenarioManager.cc:98
void inet::ScenarioManager::handleMessage ( cMessage *  msg)
overrideprotectedvirtual
50 {
51  cXMLElement *node = (cXMLElement *)msg->getContextPointer();
52  delete msg;
53 
54  processCommand(node);
55 
56  numDone++;
57 }
virtual void processCommand(cXMLElement *node)
Definition: ScenarioManager.cc:59
int numDone
Definition: ScenarioManager.h:44
void inet::ScenarioManager::initialize ( )
overrideprotectedvirtual
25 {
26  cXMLElement *script = par("script");
27 
28  numChanges = numDone = 0;
29  WATCH(numChanges);
30  WATCH(numDone);
31 
32  for (cXMLElement *node = script->getFirstChild(); node; node = node->getNextSibling()) {
33  // check attr t is present
34  const char *tAttr = node->getAttribute("t");
35  if (!tAttr)
36  throw cRuntimeError("attribute 't' missing at %s", node->getSourceLocation());
37 
38  // schedule self-message
39  simtime_t t = SimTime::parse(tAttr);
40  cMessage *msg = new cMessage("scenario-event");
41  msg->setContextPointer(node);
42  scheduleAt(t, msg);
43 
44  // count it
45  numChanges++;
46  }
47 }
int numChanges
Definition: ScenarioManager.h:43
int numDone
Definition: ScenarioManager.h:44
void inet::ScenarioManager::processAtCommand ( cXMLElement *  node)
protectedvirtual

Referenced by processCommand().

130 {
131  for (cXMLElement *child = node->getFirstChild(); child; child = child->getNextSibling())
132  processCommand(child);
133 }
virtual void processCommand(cXMLElement *node)
Definition: ScenarioManager.cc:59
void inet::ScenarioManager::processCommand ( cXMLElement *  node)
protectedvirtual

Referenced by handleMessage(), and processAtCommand().

60 {
61  const char *tag = node->getTagName();
62  EV << "processing <" << tag << "> command...\n";
63 
64  if (!strcmp(tag, "at"))
65  processAtCommand(node);
66  else if (!strcmp(tag, "set-param"))
68  else if (!strcmp(tag, "set-channel-attr"))
70  else if (!strcmp(tag, "create-module"))
72  else if (!strcmp(tag, "delete-module"))
74  else if (!strcmp(tag, "connect"))
76  else if (!strcmp(tag, "disconnect"))
78  else
80 }
virtual void processSetChannelAttrCommand(cXMLElement *node)
Definition: ScenarioManager.cc:166
virtual void processConnectCommand(cXMLElement *node)
Definition: ScenarioManager.cc:240
virtual void processModuleSpecificCommand(cXMLElement *node)
Definition: ScenarioManager.cc:135
virtual void processSetParamCommand(cXMLElement *node)
Definition: ScenarioManager.cc:151
virtual void processDisconnectCommand(cXMLElement *node)
Definition: ScenarioManager.cc:287
virtual void processCreateModuleCommand(cXMLElement *node)
Definition: ScenarioManager.cc:191
virtual void processAtCommand(cXMLElement *node)
Definition: ScenarioManager.cc:129
virtual void processDeleteModuleCommand(cXMLElement *node)
Definition: ScenarioManager.cc:210
void inet::ScenarioManager::processConnectCommand ( cXMLElement *  node)
protectedvirtual

Referenced by processCommand().

241 {
242  cGate *srcGate;
243  cModule *srcMod = getRequiredModule(node, "src-module");
244  const char *srcGateStr = getRequiredAttribute(node, "src-gate");
245  std::string srcGateName;
246  int srcGateIndex;
247  parseIndexedName(srcGateStr, srcGateName, srcGateIndex);
248  bool isSrcGateInOut = (srcMod->gateType(srcGateName.c_str()) == cGate::INOUT);
249 
250  cGate *destGate;
251  cModule *destMod = getRequiredModule(node, "dest-module");
252  const char *destGateStr = getRequiredAttribute(node, "dest-gate");
253  std::string destGateName;
254  int destGateIndex;
255  parseIndexedName(destGateStr, destGateName, destGateIndex);
256  bool isDestGateInOut = (destMod->gateType(destGateName.c_str()) == cGate::INOUT);
257 
258  if (srcMod->getParentModule() != destMod->getParentModule())
259  throw cRuntimeError("The parent modules of src-module and dest-module are differ at %s",
260  node->getSourceLocation());
261 
262  // process <connect-channel> command
263  const char *channelTypeName = node->getAttribute("channel-type");
264  cChannelType *channelType = channelTypeName ? cChannelType::get(channelTypeName) : nullptr;
265  cXMLElementList paramList;
266 
267  if (channelTypeName)
268  paramList = node->getChildrenByTagName("param");
269 
270  srcGate = isSrcGateInOut ?
271  srcMod->gateHalf(srcGateName.c_str(), cGate::OUTPUT, srcGateIndex) :
272  srcMod->gate(srcGateName.c_str(), srcGateIndex);
273  destGate = isDestGateInOut ?
274  destMod->gateHalf(destGateName.c_str(), cGate::INPUT, destGateIndex) :
275  destMod->gate(destGateName.c_str(), destGateIndex);
276 
277  createConnection(paramList, channelType, srcGate, destGate);
278 
279  if (isSrcGateInOut && isDestGateInOut) {
280  destGate = srcMod->gateHalf(srcGateName.c_str(), cGate::INPUT, srcGateIndex);
281  srcGate = destMod->gateHalf(destGateName.c_str(), cGate::OUTPUT, destGateIndex);
282 
283  createConnection(paramList, channelType, srcGate, destGate);
284  }
285 }
const char * getRequiredAttribute(cXMLElement *node, const char *attr)
Definition: ScenarioManager.cc:98
virtual cModule * getRequiredModule(cXMLElement *node, const char *attr)
Definition: ScenarioManager.cc:107
void createConnection(cXMLElementList &paramList, cChannelType *channelType, cGate *srcGate, cGate *destGate)
Definition: ScenarioManager.cc:220
void inet::ScenarioManager::processCreateModuleCommand ( cXMLElement *  node)
protectedvirtual

Referenced by processCommand().

192 {
193  const char *moduleTypeName = getRequiredAttribute(node, "type");
194  const char *submoduleName = getRequiredAttribute(node, "submodule");
195  const char *parentModulePath = getRequiredAttribute(node, "parent");
196  cModuleType *moduleType = cModuleType::get(moduleTypeName);
197  if (moduleType == nullptr)
198  throw cRuntimeError("module type '%s' is not found", moduleType);
199  cModule *parentModule = getSimulation()->getSystemModule()->getModuleByPath(parentModulePath);
200  if (parentModule == nullptr)
201  throw cRuntimeError("parent module '%s' is not found", parentModulePath);
202  cModule *submodule = parentModule->getSubmodule(submoduleName, 0);
203  int submoduleIndex = submodule == nullptr ? 0 : submodule->getVectorSize();
204  cModule *module = moduleType->create(submoduleName, parentModule, submoduleIndex + 1, submoduleIndex);
205  module->finalizeParameters();
206  module->buildInside();
207  module->callInitialize();
208 }
const char * getRequiredAttribute(cXMLElement *node, const char *attr)
Definition: ScenarioManager.cc:98
void inet::ScenarioManager::processDeleteModuleCommand ( cXMLElement *  node)
protectedvirtual

Referenced by processCommand().

211 {
212  const char *modulePath = getRequiredAttribute(node, "module");
213  cModule *module = getSimulation()->getSystemModule()->getModuleByPath(modulePath);
214  if (module == nullptr)
215  throw cRuntimeError("module '%s' is not found", modulePath);
216  module->callFinish();
217  module->deleteModule();
218 }
const char * getRequiredAttribute(cXMLElement *node, const char *attr)
Definition: ScenarioManager.cc:98
void inet::ScenarioManager::processDisconnectCommand ( cXMLElement *  node)
protectedvirtual

Referenced by processCommand().

288 {
289  // process <disconnect> command
290  cModule *srcMod = getRequiredModule(node, "src-module");
291  cModule *parentMod = srcMod->getParentModule();
292  const char *srcGateStr = getRequiredAttribute(node, "src-gate");
293  std::string srcGateName;
294  int srcGateIndex;
295  parseIndexedName(srcGateStr, srcGateName, srcGateIndex);
296  cGate::Type srcGateType = srcMod->gateType(srcGateName.c_str());
297 
298  cGate *srcGate;
299 
300  if (srcGateType == cGate::INPUT)
301  throw cRuntimeError("The src-gate must be inout or output gate at %s", node->getSourceLocation());
302 
303  if (srcGateType == cGate::INOUT) {
304  cGate *g;
305 
306  srcGate = srcMod->gateHalf(srcGateName.c_str(), cGate::OUTPUT, srcGateIndex);
307  g = srcGate->getNextGate();
308  if (!g)
309  return; // not connected
310 
311  if (g->getOwnerModule()->getParentModule() != parentMod)
312  throw cRuntimeError("The src-gate connected to a node on another level at %s", node->getSourceLocation());
313 
314  srcGate->disconnect();
315 
316  srcGate = srcMod->gateHalf(srcGateName.c_str(), cGate::INPUT, srcGateIndex);
317  g = srcGate->getPreviousGate();
318  if (!g)
319  return; // not connected
320 
321  if (g->getOwnerModule()->getParentModule() != parentMod)
322  throw cRuntimeError("The src-gate connected to a node on another level at %s", node->getSourceLocation());
323 
324  g->disconnect();
325  }
326  else {
327  srcGate = srcMod->gate(srcGateName.c_str(), srcGateIndex);
328  cGate *g = srcGate->getNextGate();
329  if (g && g->getOwnerModule()->getParentModule() == parentMod)
330  srcGate->disconnect();
331  }
332 }
const char * getRequiredAttribute(cXMLElement *node, const char *attr)
Definition: ScenarioManager.cc:98
virtual cModule * getRequiredModule(cXMLElement *node, const char *attr)
Definition: ScenarioManager.cc:107
milli< kg >::type g
Definition: Units.h:900
void inet::ScenarioManager::processModuleSpecificCommand ( cXMLElement *  node)
protectedvirtual

Referenced by processCommand().

136 {
137  // find which module we'll need to invoke
138  cModule *mod = getRequiredModule(node, "module");
139 
140  // see if it supports the IScriptable interface
141  IScriptable *scriptable = dynamic_cast<IScriptable *>(mod);
142  if (!scriptable)
143  throw cRuntimeError("<%s> not understood: it is not a built-in command of %s, and module class %s " //TODO be more specific
144  "is not scriptable (does not subclass from IScriptable) at %s",
145  node->getTagName(), getClassName(), mod->getClassName(), node->getSourceLocation());
146 
147  // ok, trust it to process this command
148  scriptable->processCommand(*node);
149 }
double mod(double dividend, double divisor)
Returns the rest of a whole-numbered division.
Definition: INETMath.h:108
virtual cModule * getRequiredModule(cXMLElement *node, const char *attr)
Definition: ScenarioManager.cc:107
void inet::ScenarioManager::processSetChannelAttrCommand ( cXMLElement *  node)
protectedvirtual

Referenced by processCommand().

167 {
168  // process <set-channel-attr> command
169  cGate *g = getRequiredGate(node, "src-module", "src-gate");
170  const char *attrAttr = getRequiredAttribute(node, "attr");
171  const char *valueAttr = getRequiredAttribute(node, "value");
172 
173  EV << "Setting channel attribute: " << attrAttr << " = " << valueAttr
174  << " of gate " << g->getFullPath() << "\n";
175  bubble((std::string("setting channel attr: ") + attrAttr + " = " + valueAttr).c_str());
176 
177  // make sure gate is connected at all
178  if (!g->getNextGate())
179  throw cRuntimeError("gate '%s' is not connected at %s", g->getFullPath().c_str(), node->getSourceLocation());
180 
181  // find channel (or add one?)
182  cChannel *chan = g->getChannel();
183  if (!chan)
184  throw cRuntimeError("connection starting at gate '%s' has no attributes at %s", g->getFullPath().c_str(), node->getSourceLocation());
185 
186  // set the parameter to the given value
187  cPar& param = chan->par(attrAttr);
188  param.parse(valueAttr);
189 }
const char * getRequiredAttribute(cXMLElement *node, const char *attr)
Definition: ScenarioManager.cc:98
virtual cGate * getRequiredGate(cXMLElement *node, const char *modattr, const char *gateattr)
Definition: ScenarioManager.cc:116
milli< kg >::type g
Definition: Units.h:900
void inet::ScenarioManager::processSetParamCommand ( cXMLElement *  node)
protectedvirtual

Referenced by processCommand().

152 {
153  // process <set-param> command
154  cModule *mod = getRequiredModule(node, "module");
155  const char *parAttr = getRequiredAttribute(node, "par");
156  const char *valueAttr = getRequiredAttribute(node, "value");
157 
158  EV << "Setting " << mod->getFullPath() << "." << parAttr << " = " << valueAttr << "\n";
159  bubble((std::string("setting: ") + mod->getFullPath() + "." + parAttr + " = " + valueAttr).c_str());
160 
161  // set the parameter to the given value
162  cPar& param = mod->par(parAttr);
163  param.parse(valueAttr);
164 }
double mod(double dividend, double divisor)
Returns the rest of a whole-numbered division.
Definition: INETMath.h:108
const char * getRequiredAttribute(cXMLElement *node, const char *attr)
Definition: ScenarioManager.cc:98
virtual cModule * getRequiredModule(cXMLElement *node, const char *attr)
Definition: ScenarioManager.cc:107
void inet::ScenarioManager::refreshDisplay ( ) const
overrideprotectedvirtual
335 {
336  char buf[80];
337  sprintf(buf, "total %d changes, %d left", numChanges, numChanges - numDone);
338  getDisplayString().setTagArg("t", 0, buf);
339 }
int numChanges
Definition: ScenarioManager.h:43
int numDone
Definition: ScenarioManager.h:44

Member Data Documentation

int inet::ScenarioManager::numChanges = 0
protected

Referenced by initialize(), and refreshDisplay().

int inet::ScenarioManager::numDone = 0
protected

The documentation for this class was generated from the following files: