00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "ScenarioManager.h"
00019
00020 Define_Module(ScenarioManager);
00021
00022
00023 void ScenarioManager::initialize()
00024 {
00025 cXMLElement *script = par("script");
00026
00027 numChanges = numDone = 0;
00028 WATCH(numChanges);
00029 WATCH(numDone);
00030
00031 for (cXMLElement *node=script->getFirstChild(); node; node = node->getNextSibling())
00032 {
00033
00034 const char *tAttr = node->getAttribute("t");
00035 if (!tAttr)
00036 error("attribute 't' missing at %s", node->getSourceLocation());
00037
00038
00039 simtime_t t = STR_SIMTIME(tAttr);
00040 cMessage *msg = new cMessage("scenario-event");
00041 msg->setContextPointer(node);
00042 scheduleAt(t, msg);
00043
00044
00045 numChanges++;
00046 }
00047
00048 updateDisplayString();
00049 }
00050
00051 void ScenarioManager::handleMessage(cMessage *msg)
00052 {
00053 cXMLElement *node = (cXMLElement *) msg->getContextPointer();
00054 delete msg;
00055
00056 processCommand(node);
00057
00058 numDone++;
00059 updateDisplayString();
00060 }
00061
00062 void ScenarioManager::processCommand(cXMLElement *node)
00063 {
00064 const char *tag = node->getTagName();
00065 EV << "processing <" << tag << "> command...\n";
00066
00067 if (!strcmp(tag,"at"))
00068 processAtCommand(node);
00069 else if (!strcmp(tag,"set-param"))
00070 processSetParamCommand(node);
00071 else if (!strcmp(tag,"set-channel-attr"))
00072 processSetChannelAttrCommand(node);
00073
00074
00075
00076
00077 else
00078 processModuleSpecificCommand(node);
00079 }
00080
00081
00082 static bool parseIndexedName(const char *s, std::string& name, int& index)
00083 {
00084 const char *b;
00085 if ((b=strchr(s,'['))==NULL || s[strlen(s)-1]!=']')
00086 {
00087 name = s;
00088 index = -1;
00089 return false;
00090 }
00091 else
00092 {
00093 name.assign(s, b-s);
00094 index = atoi(b+1);
00095 return true;
00096 }
00097 }
00098
00099 const char *ScenarioManager::getRequiredAttribute(cXMLElement *node, const char *attr)
00100 {
00101 const char *s = node->getAttribute(attr);
00102 if (!s)
00103 error("required attribute %s of <%s> missing at %s",
00104 attr, node->getTagName(), node->getSourceLocation());
00105 return s;
00106 }
00107
00108 cModule *ScenarioManager::getRequiredModule(cXMLElement *node, const char *attr)
00109 {
00110 const char *moduleAttr = getRequiredAttribute(node, attr);
00111 cModule *mod = simulation.getModuleByPath(moduleAttr);
00112 if (!mod)
00113 error("module '%s' not found at %s", moduleAttr, node->getSourceLocation());
00114 return mod;
00115 }
00116
00117 cGate *ScenarioManager::getRequiredGate(cXMLElement *node, const char *modAttr, const char *gateAttr)
00118 {
00119 cModule *mod = getRequiredModule(node, modAttr);
00120 const char *gateStr = getRequiredAttribute(node, gateAttr);
00121 std::string gname;
00122 int gindex;
00123 cGate *g = parseIndexedName(gateStr, gname, gindex) ? mod->gate(gname.c_str(), gindex) : mod->gate(gname.c_str());
00124 if (!g)
00125 error("module '%s' has no gate '%s' at %s", mod->getFullPath().c_str(), gateStr, node->getSourceLocation());
00126 return g;
00127 }
00128
00129 void ScenarioManager::processAtCommand(cXMLElement *node)
00130 {
00131 for (cXMLElement *child=node->getFirstChild(); child; child=child->getNextSibling())
00132 processCommand(child);
00133 }
00134
00135 void ScenarioManager::processModuleSpecificCommand(cXMLElement *node)
00136 {
00137
00138 cModule *mod = getRequiredModule(node, "module");
00139
00140
00141 IScriptable *scriptable = dynamic_cast<IScriptable *>(mod);
00142 if (!scriptable)
00143 error("<%s> not understood: it is not a built-in command of %s, and module class %s "
00144 "is not scriptable (does not subclass from IScriptable) at %s",
00145 node->getTagName(), getClassName(), mod->getClassName(), node->getSourceLocation());
00146
00147
00148 scriptable->processCommand(*node);
00149 }
00150
00151 void ScenarioManager::processSetParamCommand(cXMLElement *node)
00152 {
00153
00154 cModule *mod = getRequiredModule(node, "module");
00155 const char *parAttr = getRequiredAttribute(node, "par");
00156 const char *valueAttr = getRequiredAttribute(node, "value");
00157
00158 EV << "Setting " << mod->getFullPath() << "." << parAttr << " = " << valueAttr << "\n";
00159 bubble((std::string("setting: ")+mod->getFullPath()+"."+parAttr+" = "+valueAttr).c_str());
00160
00161
00162 cPar& param = mod->par(parAttr);
00163 param.parse(valueAttr);
00164 }
00165
00166 void ScenarioManager::processSetChannelAttrCommand(cXMLElement *node)
00167 {
00168
00169 cGate *g = getRequiredGate(node, "src-module", "src-gate");
00170 const char *attrAttr = getRequiredAttribute(node, "attr");
00171 const char *valueAttr = getRequiredAttribute(node, "value");
00172
00173 EV << "Setting channel attribute: " << attrAttr << " = " << valueAttr
00174 << " of gate " << g->getFullPath() << "\n";
00175 bubble((std::string("setting channel attr: ")+attrAttr+" = "+valueAttr).c_str());
00176
00177
00178 if (!g->getNextGate())
00179 error("gate '%s' is not connected at %s", g->getFullPath().c_str(), node->getSourceLocation());
00180
00181
00182 cChannel *chan = g->getChannel();
00183 if (!chan)
00184 error("connection starting at gate '%s' has no attributes at %s", g->getFullPath().c_str(), node->getSourceLocation());
00185
00186
00187 if (!chan->hasPar(attrAttr))
00188 ;
00189 cPar& param = chan->par(attrAttr);
00190 param.parse(valueAttr);
00191 }
00192
00193 void ScenarioManager::processCreateModuleCommand(cXMLElement *node)
00194 {
00195
00196 }
00197
00198 void ScenarioManager::processDeleteModuleCommand(cXMLElement *node)
00199 {
00200
00201 }
00202
00203 void ScenarioManager::processConnectCommand(cXMLElement *node)
00204 {
00205
00206 }
00207
00208 void ScenarioManager::processDisconnectCommand(cXMLElement *node)
00209 {
00210
00211 }
00212
00213 void ScenarioManager::updateDisplayString()
00214 {
00215 char buf[80];
00216 sprintf(buf, "total %d changes, %d left", numChanges, numChanges-numDone);
00217 getDisplayString().setTagArg("t", 0, buf);
00218 }
00219