|
INET Framework for OMNeT++/OMNEST
|
Scenario Manager (experimental) which executes a script specified in XML.
More...
#include <ScenarioManager.h>
|
| typedef std::pair< cGate *, cGate * > | GatePair |
| |
Scenario Manager (experimental) which executes a script specified in XML.
ScenarioManager has a few built-in commands such as <set-param>, <set-channel-param>, 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
◆ GatePair
◆ ScenarioManager()
| inet::ScenarioManager::ScenarioManager |
( |
| ) |
|
|
inline |
◆ createConnection()
| void inet::ScenarioManager::createConnection |
( |
const cXMLElementList & |
paramList, |
|
|
cChannelType * |
channelType, |
|
|
cGate * |
srcGate, |
|
|
cGate * |
destGate |
|
) |
| |
|
protected |
348 srcGate->connectTo(destGate);
350 cChannel *channel = channelType->create(
"channel");
353 for (
auto child : paramList) {
356 channel->par(name).parse(value);
360 srcGate->connectTo(destGate, channel);
Referenced by processConnectCommand().
◆ disconnect()
| void inet::ScenarioManager::disconnect |
( |
cGate * |
srcGate | ) |
|
|
protected |
◆ findMandatorySingleGateTowards()
| cGate * inet::ScenarioManager::findMandatorySingleGateTowards |
( |
cModule * |
srcModule, |
|
|
cModule * |
destModule |
|
) |
| |
|
protected |
151 cGate *resultGate =
nullptr;
152 for (cModule::GateIterator it(srcModule); !it.end(); ++it) {
154 if (gate->getType() == cGate::OUTPUT && gate->getNextGate() !=
nullptr && gate->getNextGate()->getOwnerModule() == destModule) {
156 throw cRuntimeError(
"Ambiguous gate: there is more than one connection between the source and destination modules");
161 throw cRuntimeError(
"No such gate: there is no connection between the source and destination modules");
Referenced by getConnection().
◆ getConnection()
174 if (node->getAttribute(ATTR_SRC_GATE)) {
179 parseIndexedName(srcGateSpec, name, index);
180 if (srcModule->gateType(name.c_str()) == cGate::OUTPUT) {
181 return GatePair(srcModule->gate(name.c_str(), index),
nullptr);
183 else if (srcModule->gateType(name.c_str()) == cGate::INOUT) {
184 cGate *outputHalf = srcModule->gateHalf(name.c_str(), cGate::OUTPUT, index);
185 cGate *inputHalf = srcModule->gateHalf(name.c_str(), cGate::INPUT, index);
186 if (outputHalf->getNextGate() ==
nullptr || inputHalf->getPreviousGate() ==
nullptr)
187 throw cRuntimeError(
"The specified gate (or the input or output half of it) is not connected");
188 if (outputHalf->getNextGate()->getOwnerModule() != inputHalf->getPreviousGate()->getOwnerModule())
189 throw cRuntimeError(
"The specified gate (or the input or output half of it) is connected to a node on another level");
190 return GatePair(outputHalf, inputHalf->getPreviousGate());
193 throw cRuntimeError(
"'src-gate' must be an inout or output gate");
196 else if (node->getAttribute(ATTR_DEST_MODULE)) {
199 if (srcModule->getParentModule() != destModule->getParentModule())
200 throw cRuntimeError(
"Source and destination modules must be under the same parent");
202 bool bidir = strlen(srcGate->getNameSuffix()) > 0;
207 cGate *otherHalf = srcModule->gateHalf(srcGate->getBaseName(), cGate::INPUT, srcGate->isVector() ? srcGate->getIndex() : -1);
208 cGate *otherSrcGate = otherHalf->getPreviousGate();
209 if (otherSrcGate ==
nullptr)
210 throw cRuntimeError(
"Broken bidirectional connection: the corresponding input gate is not connected");
211 if (otherSrcGate->getOwnerModule() != destModule)
212 throw cRuntimeError(
"Broken bidirectional connection: the input and output gates are connected to two different modules");
213 return GatePair(srcGate, otherSrcGate);
217 throw cRuntimeError(
"Missing attribute: Either 'src-gate' or 'dest-module' must be present");
Referenced by processDisconnectCommand(), and processSetChannelParamCommand().
◆ getRequiredModule() [1/2]
| cModule * inet::ScenarioManager::getRequiredModule |
( |
const char * |
path | ) |
|
|
protected |
◆ getRequiredModule() [2/2]
| cModule * inet::ScenarioManager::getRequiredModule |
( |
const cXMLElement * |
node, |
|
|
const char * |
attr |
|
) |
| |
|
protected |
◆ handleMessage()
| void inet::ScenarioManager::handleMessage |
( |
cMessage * |
msg | ) |
|
|
overrideprotectedvirtual |
81 auto node = check_and_cast<ScenarioTimer *>(msg)->getXmlNode();
◆ initialize()
| void inet::ScenarioManager::initialize |
( |
| ) |
|
|
overrideprotectedvirtual |
56 cXMLElement *script = par(
"script");
62 for (cXMLElement *node = script->getFirstChild(); node; node = node->getNextSibling()) {
64 const char *tAttr = node->getAttribute(ATTR_T);
66 throw cRuntimeError(
"Attribute 't' missing at %s", node->getSourceLocation());
69 simtime_t t = SimTime::parse(tAttr);
70 auto msg =
new ScenarioTimer(
"scenario-event");
71 msg->setXmlNode(node);
◆ processAtCommand()
| void inet::ScenarioManager::processAtCommand |
( |
const cXMLElement * |
node | ) |
|
|
protectedvirtual |
223 for (
const cXMLElement *child = node->getFirstChild(); child; child = child->getNextSibling())
Referenced by processCommand().
◆ processCommand()
| void inet::ScenarioManager::processCommand |
( |
const cXMLElement * |
node | ) |
|
|
protectedvirtual |
92 std::string tag = node->getTagName();
93 EV <<
"processing <" << tag <<
"> command...\n";
97 else if (tag == CMD_SET_PARAM)
99 else if (tag == CMD_SET_CHANNEL_PARAM)
101 else if (tag == CMD_CREATE_MODULE)
103 else if (tag == CMD_DELETE_MODULE)
105 else if (tag == CMD_CONNECT)
107 else if (tag == CMD_DISCONNECT)
109 else if (tag == CMD_INITIATE || tag == OP_START || tag == OP_STARTUP || tag == OP_STOP
110 || tag == OP_SHUTDOWN || tag == OP_CRASH || tag == OP_SUSPEND || tag == OP_RESUME)
115 catch (std::exception&
e) {
116 throw cRuntimeError(
"%s, in command <%s> at %s",
e.what(), node->getTagName(), node->getSourceLocation());
Referenced by handleMessage(), and processAtCommand().
◆ processConnectCommand()
| void inet::ScenarioManager::processConnectCommand |
( |
const cXMLElement * |
node | ) |
|
|
protectedvirtual |
369 std::string srcGateName;
371 parseIndexedName(srcGateStr, srcGateName, srcGateIndex);
372 bool isSrcGateInOut = (srcMod->gateType(srcGateName.c_str()) == cGate::INOUT);
377 std::string destGateName;
379 parseIndexedName(destGateStr, destGateName, destGateIndex);
380 bool isDestGateInOut = (destMod->gateType(destGateName.c_str()) == cGate::INOUT);
382 if (srcMod->getParentModule() != destMod->getParentModule())
383 throw cRuntimeError(
"'src-module' and 'dest-module' must have the same parent module");
386 const char *channelTypeName = node->getAttribute(ATTR_CHANNEL_TYPE);
387 cChannelType *channelType = channelTypeName ? cChannelType::get(channelTypeName) : nullptr;
388 cXMLElementList paramList;
391 paramList = node->getChildrenByTagName(TAG_PARAM);
393 srcGate = isSrcGateInOut ?
394 srcMod->gateHalf(srcGateName.c_str(), cGate::OUTPUT, srcGateIndex) :
395 srcMod->gate(srcGateName.c_str(), srcGateIndex);
396 destGate = isDestGateInOut ?
397 destMod->gateHalf(destGateName.c_str(), cGate::INPUT, destGateIndex) :
398 destMod->gate(destGateName.c_str(), destGateIndex);
402 if (isSrcGateInOut && isDestGateInOut) {
403 destGate = srcMod->gateHalf(srcGateName.c_str(), cGate::INPUT, srcGateIndex);
404 srcGate = destMod->gateHalf(destGateName.c_str(), cGate::OUTPUT, destGateIndex);
Referenced by processCommand().
◆ processCreateModuleCommand()
| void inet::ScenarioManager::processCreateModuleCommand |
( |
const cXMLElement * |
node | ) |
|
|
protectedvirtual |
296 cModuleType *moduleType = cModuleType::get(moduleTypeName);
297 cModule *parentModule = getSimulation()->getSystemModule()->getModuleByPath(parentModulePath);
298 if (parentModule ==
nullptr)
299 throw cRuntimeError(
"Parent module '%s' is not found", parentModulePath);
302 int submoduleVectorSize = 0;
303 for (SubmoduleIterator it(parentModule); !it.end(); ++it) {
304 cModule *submodule = *it;
305 if (submodule->isVector() && submodule->isName(submoduleName)) {
306 if (submoduleVectorSize < submodule->getVectorSize())
307 submoduleVectorSize = submodule->getVectorSize();
312 cModule *module =
nullptr;
314 if (!parentModule->hasSubmoduleVector(submoduleName)) {
315 parentModule->addSubmoduleVector(submoduleName, submoduleVectorSize + 1);
318 parentModule->setSubmoduleVectorSize(submoduleName, submoduleVectorSize + 1);
319 module = moduleType->create(submoduleName, parentModule, submoduleVectorSize);
322 module = moduleType->create(submoduleName, parentModule);
324 module->finalizeParameters();
325 module->buildInside();
326 cPreModuleInitNotification pre;
328 emit(POST_MODEL_CHANGE, &pre);
329 module->callInitialize();
330 cPostModuleInitNotification post;
331 post.module = module;
332 emit(POST_MODEL_CHANGE, &post);
Referenced by processCommand().
◆ processDeleteModuleCommand()
| void inet::ScenarioManager::processDeleteModuleCommand |
( |
const cXMLElement * |
node | ) |
|
|
protectedvirtual |
338 cModule *module = getSimulation()->getSystemModule()->getModuleByPath(modulePath);
339 if (module ==
nullptr)
340 throw cRuntimeError(
"Module '%s' not found", modulePath);
341 module->callFinish();
342 module->deleteModule();
Referenced by processCommand().
◆ processDisconnectCommand()
| void inet::ScenarioManager::processDisconnectCommand |
( |
const cXMLElement * |
node | ) |
|
|
protectedvirtual |
420 EV <<
"Disconnecting " << pair.first->getFullPath() <<
" --> " << pair.first->getNextGate()->getFullPath()
421 << (pair.second ?
" and its reverse connection" :
"") <<
"\n";
Referenced by processCommand().
◆ processLifecycleCommand()
| void inet::ScenarioManager::processLifecycleCommand |
( |
const cXMLElement * |
node | ) |
|
|
protectedvirtual |
431 const char *target = node->getAttribute(ATTR_MODULE);
432 cModule *module = getModuleByPath(target);
434 throw cRuntimeError(
"Module '%s' not found", target);
437 std::string tag = node->getTagName();
438 std::string operationName = (tag == CMD_INITIATE) ? node->getAttribute(ATTR_OPERATION) : tag;
439 LifecycleOperation *operation;
440 if (operationName == OP_START || operationName == OP_STARTUP)
441 operation =
new ModuleStartOperation;
442 else if (operationName == OP_STOP || operationName == OP_SHUTDOWN)
443 operation =
new ModuleStopOperation;
444 else if (operationName == OP_CRASH)
445 operation =
new ModuleCrashOperation;
449 auto paramsCopy = node->getAttributes();
450 paramsCopy.erase(ATTR_MODULE);
451 paramsCopy.erase(ATTR_T);
452 paramsCopy.erase(ATTR_OPERATION);
453 operation->initialize(module, paramsCopy);
454 if (!paramsCopy.empty())
455 throw cRuntimeError(
"Unknown parameter '%s' for operation %s", paramsCopy.begin()->first.c_str(), operationName.c_str());
Referenced by processCommand().
◆ processModuleSpecificCommand()
| void inet::ScenarioManager::processModuleSpecificCommand |
( |
const cXMLElement * |
node | ) |
|
|
protectedvirtual |
233 IScriptable *scriptable =
dynamic_cast<IScriptable *
>(
mod);
235 throw cRuntimeError(
"<%s> not understood: it is not a built-in command of %s, and module class %s "
236 "is not scriptable (does not subclass from IScriptable)",
237 node->getTagName(), getClassName(),
mod->getClassName());
240 scriptable->processCommand(*node);
Referenced by processCommand().
◆ processSetChannelParamCommand()
| void inet::ScenarioManager::processSetChannelParamCommand |
( |
const cXMLElement * |
node | ) |
|
|
protectedvirtual |
281 EV <<
"Setting channel parameter: " << parAttr <<
" = " << valueAttr
282 <<
" on connection " << pair.first->getFullPath() <<
" --> " << pair.first->getNextGate()->getFullPath()
283 << (pair.second ?
" and its reverse connection" :
"") <<
"\n";
284 bubble((std::string(
"setting channel parameter: ") + parAttr +
" = " + valueAttr).c_str());
Referenced by processCommand().
◆ processSetParamCommand()
| void inet::ScenarioManager::processSetParamCommand |
( |
const cXMLElement * |
node | ) |
|
|
protectedvirtual |
250 EV <<
"Setting " <<
mod->getFullPath() <<
"." << parAttr <<
" = " << valueAttr <<
"\n";
251 bubble((std::string(
"setting: ") +
mod->getFullPath() +
"." + parAttr +
" = " + valueAttr).c_str());
254 cPar& param =
mod->par(parAttr);
255 param.parse(valueAttr);
Referenced by processCommand().
◆ refreshDisplay()
| void inet::ScenarioManager::refreshDisplay |
( |
| ) |
const |
|
overrideprotectedvirtual |
465 getDisplayString().setTagArg(ATTR_T, 0, buf);
◆ setChannelParam()
| void inet::ScenarioManager::setChannelParam |
( |
cGate * |
srcGate, |
|
|
const char * |
name, |
|
|
const char * |
value |
|
) |
| |
|
protected |
261 if (!srcGate->getNextGate())
262 throw cRuntimeError(
"Gate '%s' is not connected", srcGate->getFullPath().c_str());
265 cChannel *chan = srcGate->getChannel();
267 throw cRuntimeError(
"Connection starting at gate '%s' has no channel object", srcGate->getFullPath().c_str());
270 cPar& param = chan->par(name);
Referenced by processSetChannelParamCommand().
◆ numChanges
| int inet::ScenarioManager::numChanges = 0 |
|
protected |
◆ numDone
| int inet::ScenarioManager::numDone = 0 |
|
protected |
The documentation for this class was generated from the following files:
double mod(double dividend, double divisor)
Returns the rest of a whole-numbered division.
Definition: INETMath.h:96
void createConnection(const cXMLElementList ¶mList, cChannelType *channelType, cGate *srcGate, cGate *destGate)
Definition: ScenarioManager.cc:345
virtual void processModuleSpecificCommand(const cXMLElement *node)
Definition: ScenarioManager.cc:227
const value< double, units::C > e(1.602176487e-19)
std::pair< cGate *, cGate * > GatePair
Definition: ScenarioManager.h:50
virtual void processLifecycleCommand(const cXMLElement *node)
Definition: ScenarioManager.cc:428
const char * getMandatoryAttribute(const cXMLElement &node, const char *attr)
Definition: XMLUtils.cc:151
cObject * createOne(const char *className, const char *defaultNamespace)
Like cObjectFactory::createOne(), except it starts searching for the class in the given namespace.
Definition: INETUtils.cc:147
virtual void processCreateModuleCommand(const cXMLElement *node)
Definition: ScenarioManager.cc:291
virtual void processSetParamCommand(const cXMLElement *node)
Definition: ScenarioManager.cc:243
cModule * getRequiredModule(const char *path)
Definition: ScenarioManager.cc:136
bool getAttributeBoolValue(const cXMLElement *node, const char *attrName, bool defVal)
Definition: XMLUtils.cc:169
virtual void processDisconnectCommand(const cXMLElement *node)
Definition: ScenarioManager.cc:415
void setChannelParam(cGate *srcGate, const char *name, const char *value)
Definition: ScenarioManager.cc:258
virtual void processSetChannelParamCommand(const cXMLElement *node)
Definition: ScenarioManager.cc:274
void disconnect(cGate *srcGate)
Definition: ScenarioManager.cc:410
GatePair getConnection(const cXMLElement *node)
Definition: ScenarioManager.cc:165
virtual bool initiateOperation(LifecycleOperation *operation, IDoneCallback *completionCallback=nullptr)
Initiate an operation.
Definition: LifecycleController.cc:46
virtual void processDeleteModuleCommand(const cXMLElement *node)
Definition: ScenarioManager.cc:335
int numDone
Definition: ScenarioManager.h:46
cGate * findMandatorySingleGateTowards(cModule *srcModule, cModule *destModule)
Definition: ScenarioManager.cc:149
virtual void processConnectCommand(const cXMLElement *node)
Definition: ScenarioManager.cc:364
virtual void processCommand(const cXMLElement *node)
Definition: ScenarioManager.cc:89
int numChanges
Definition: ScenarioManager.h:45
virtual void processAtCommand(const cXMLElement *node)
Definition: ScenarioManager.cc:221
const char * getMandatoryFilledAttribute(const cXMLElement &node, const char *attr)
Definition: XMLUtils.cc:160