00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00040 #include <plugins/symboliclog/PluginSymbolicLog.h>
00041
00042
00043 namespace beliefstate {
00044 namespace plugins {
00045 PLUGIN_CLASS::PLUGIN_CLASS() {
00046 this->addDependency("imagecapturer");
00047 this->setPluginVersion("0.93");
00048
00049 m_prLastFailure = make_pair("", (Node*)NULL);
00050
00051
00052 srand(time(NULL));
00053
00054 m_ndActive = NULL;
00055 }
00056
00057 PLUGIN_CLASS::~PLUGIN_CLASS() {
00058 for(Node* ndNode : m_lstNodes) {
00059 delete ndNode;
00060 }
00061
00062 m_lstNodes.clear();
00063 }
00064
00065 Result PLUGIN_CLASS::init(int argc, char** argv) {
00066 Result resInit = defaultResult();
00067
00068
00069 this->setSubscribedToEvent("begin-context", true);
00070 this->setSubscribedToEvent("end-context", true);
00071
00072
00073 this->setSubscribedToEvent("start-new-experiment", true);
00074
00075
00076 this->setSubscribedToEvent("add-designator", true);
00077 this->setSubscribedToEvent("add-object", true);
00078 this->setSubscribedToEvent("add-failure", true);
00079 this->setSubscribedToEvent("catch-failure", true);
00080 this->setSubscribedToEvent("rethrow-failure", true);
00081 this->setSubscribedToEvent("add-image-from-file", true);
00082 this->setSubscribedToEvent("equate-designators", true);
00083
00084
00085 this->setOffersService("symbolic-plan-tree", true);
00086 this->setOffersService("symbolic-plan-context", true);
00087
00088 return resInit;
00089 }
00090
00091 Result PLUGIN_CLASS::deinit() {
00092 return defaultResult();
00093 }
00094
00095 Result PLUGIN_CLASS::cycle() {
00096 Result resCycle = defaultResult();
00097
00098 m_mtxEventsStore.lock();
00099 resCycle.lstEvents = m_lstEvents;
00100 m_lstEvents.clear();
00101 m_mtxEventsStore.unlock();
00102
00103 return resCycle;
00104 }
00105
00106 Event PLUGIN_CLASS::consumeServiceEvent(ServiceEvent seServiceEvent) {
00107 Event evReturn = defaultEvent();
00108
00109 if(seServiceEvent.siServiceIdentifier == SI_REQUEST) {
00110 if(seServiceEvent.strServiceName == "symbolic-plan-tree") {
00111
00112 evReturn.lstNodes = m_lstNodes;
00113 evReturn.lstRootNodes = m_lstRootNodes;
00114
00115 evReturn.lstDesignatorIDs = m_lstDesignatorIDs;
00116 evReturn.lstEquations = m_lstDesignatorEquations;
00117 evReturn.lstEquationTimes = m_lstDesignatorEquationTimes;
00118 } else if(seServiceEvent.strServiceName == "symbolic-plan-context") {
00119
00120 Node* ndCurrent = this->activeNode();
00121
00122 while(ndCurrent) {
00123 evReturn.lstNodes.push_back(ndCurrent);
00124 evReturn.lstRootNodes = m_lstRootNodes;
00125
00126 ndCurrent = ndCurrent->parent();
00127 }
00128 }
00129 }
00130
00131 return evReturn;
00132 }
00133
00134 void PLUGIN_CLASS::consumeEvent(Event evEvent) {
00135 if(evEvent.strEventName == "begin-context") {
00136 std::string strName = evEvent.cdDesignator->stringValue("_name");
00137
00138 Node* ndFormerParent = this->relativeActiveNode(evEvent);
00139 Node* ndNew = this->addNode(strName, evEvent.nContextID, ndFormerParent);
00140 ndNew->setDescription(evEvent.cdDesignator->description());
00141
00142 std::string strTimeStart = this->getTimeStampStr();
00143 if(evEvent.cdDesignator->childForKey("_time-start")) {
00144 strTimeStart = this->str((int)evEvent.cdDesignator->floatValue("_time-start"));
00145 }
00146
00147 ndNew->metaInformation()->setValue(std::string("time-start"), strTimeStart);
00148
00149 if(evEvent.cdDesignator->childForKey("_class")) {
00150 ndNew->metaInformation()->setValue(std::string("class"), evEvent.cdDesignator->stringValue("_class"));
00151
00152 if(evEvent.cdDesignator->childForKey("_classnamespace")) {
00153 ndNew->metaInformation()->setValue(std::string("classnamespace"), evEvent.cdDesignator->stringValue("_classnamespace"));
00154 }
00155 }
00156
00157 int nDetailLevel = (int)evEvent.cdDesignator->floatValue("_detail-level");
00158 ndNew->metaInformation()->setValue(std::string("detail-level"), nDetailLevel);
00159
00160 Event evSymbolicBeginCtx = defaultEvent("symbolic-begin-context");
00161 evSymbolicBeginCtx.lstNodes.push_back(ndNew);
00162 this->deployEvent(evSymbolicBeginCtx);
00163
00164 Event evSymbolicSetSubcontext = defaultEvent("symbolic-set-subcontext");
00165 evSymbolicSetSubcontext.lstNodes.push_back(ndFormerParent);
00166 evSymbolicSetSubcontext.lstNodes.push_back(ndNew);
00167 this->deployEvent(evSymbolicSetSubcontext);
00168 } else if(evEvent.strEventName == "end-context") {
00169 int nID = (int)evEvent.cdDesignator->floatValue("_id");
00170
00171 int nSuccess = (int)evEvent.cdDesignator->floatValue("_success");
00172 Node* ndCurrent = this->relativeActiveNode(evEvent);
00173
00174 if(ndCurrent) {
00175 if(ndCurrent->id() == nID || evEvent.cdDesignator->childForKey("_relative_context_id")) {
00176 std::stringstream sts;
00177 sts << "Received stop context designator for ID " << nID << " (success: " << (nSuccess ? "yes" : "no") << ")";
00178 this->info(sts.str());
00179
00180
00181
00182 if(!ndCurrent->hasFailures()) {
00183
00184
00185
00186 ndCurrent->metaInformation()->setValue(std::string("success"), nSuccess);
00187 }
00188
00189 std::string strTimeEnd = this->getTimeStampStr();
00190 if(evEvent.cdDesignator->childForKey("_time-end")) {
00191 strTimeEnd = this->str((int)evEvent.cdDesignator->floatValue("_time-end"));
00192 }
00193 ndCurrent->metaInformation()->setValue(std::string("time-end"), strTimeEnd);
00194
00195 Node* ndParent = ndCurrent->parent();
00196 Node* ndParentLastValid = NULL;
00197 this->setNodeAsActive(ndParent);
00198
00199 while(ndParent) {
00200 ndParentLastValid = ndParent;
00201
00202 if(ndParent->prematurelyEnded()) {
00203 std::stringstream sts_id;
00204 sts_id << ndParent->id();
00205 this->info("Node ID " + sts_id.str() + " ended prematurely, removing from context stack.");
00206
00207
00208
00209 ndParent->metaInformation()->setValue(std::string("time-end"), strTimeEnd);
00210
00211
00212
00213 if(!ndParent->hasFailures()) {
00214 ndParent->metaInformation()->setValue(std::string("success"), nSuccess);
00215 }
00216
00217 Event evSymbolicEndCtx = defaultEvent("symbolic-end-context");
00218 evSymbolicEndCtx.lstNodes.push_back(ndParent);
00219 this->deployEvent(evSymbolicEndCtx);
00220
00221 ndParent = ndParent->parent();
00222 } else {
00223 break;
00224 }
00225
00226 this->setNodeAsActive(ndParent);
00227 }
00228
00229 if(ndParentLastValid) {
00230 ndParentLastValid->ensureProperty("time-end", strTimeEnd);
00231 }
00232
00233 Event evSymbolicEndCtx = defaultEvent("symbolic-end-context");
00234 evSymbolicEndCtx.lstNodes.push_back(ndCurrent);
00235 this->deployEvent(evSymbolicEndCtx);
00236 } else {
00237 std::stringstream sts;
00238 sts << "Received stop node designator for ID " << nID << " while ID " << ndCurrent->id() << " is active.";
00239 this->info(sts.str());
00240
00241 std::string strTimeEnd = this->getTimeStampStr();
00242 Node *ndEndedPrematurely = NULL;
00243 Node *ndSearchTemp = ndCurrent;
00244
00245 while(ndSearchTemp) {
00246 ndSearchTemp->ensureProperty("time-end", strTimeEnd);
00247
00248 if(ndSearchTemp->id() == nID) {
00249 ndEndedPrematurely = ndSearchTemp;
00250 ndSearchTemp = NULL;
00251 } else {
00252 ndSearchTemp = ndSearchTemp->parent();
00253 }
00254 }
00255
00256 if(ndEndedPrematurely) {
00257
00258 stringstream sts;
00259 sts << "Marking node " << nID << " as prematurely ended.";
00260 this->info(sts.str());
00261
00262 ndEndedPrematurely->setPrematurelyEnded(true);
00263 } else {
00264
00265 stringstream sts;
00266 sts << "The apparently prematurely ended node " << nID << " was not found.";
00267 this->warn(sts.str());
00268 }
00269 }
00270 } else {
00271 stringstream sts;
00272 sts << "Received stop node designator for ID " << nID << " while in top-level.";
00273 this->warn(sts.str());
00274 }
00275 } else if(evEvent.strEventName == "add-image-from-file") {
00276 if(evEvent.cdDesignator) {
00277 if(this->activeNode()) {
00278 string strFilepath = evEvent.cdDesignator->stringValue("filename");
00279 string strTopic = evEvent.cdDesignator->stringValue("origin");
00280
00281 if(strFilepath != "") {
00282 string strTimeImage = this->getTimeStampStr();
00283
00284 Node* ndSubject = this->relativeActiveNode(evEvent);
00285 if(ndSubject) {
00286 ndSubject->addImage(strTopic, strFilepath, strTimeImage);
00287
00288 this->info("Added image to active node (id " + this->str(ndSubject->id()) + "): '" + strFilepath + "'");
00289
00290 Event evSymbolicAddImage = defaultEvent("symbolic-add-image");
00291 evSymbolicAddImage.lstNodes.push_back(ndSubject);
00292 evSymbolicAddImage.cdDesignator = new CDesignator();
00293 evSymbolicAddImage.cdDesignator->setType(ACTION);
00294 evSymbolicAddImage.cdDesignator->setValue("origin", strTopic);
00295 evSymbolicAddImage.cdDesignator->setValue("filename", strFilepath);
00296 evSymbolicAddImage.cdDesignator->setValue("time-capture", strTimeImage);
00297 evSymbolicAddImage.nOpenRequestID = evEvent.nOpenRequestID;
00298 this->deployEvent(evSymbolicAddImage);
00299 } else {
00300 this->fail("Cannot add image: Given relative parent node (ID = " + this->str((int)evEvent.cdDesignator->floatValue("_relative_context_id")) + ") does not exist. This is a problem.");
00301 }
00302 } else {
00303 this->warn("No filename given. Will not add unnamed image to active node. The designator was:");
00304 evEvent.cdDesignator->printDesignator();
00305 }
00306 } else {
00307 this->warn("No node context available. Cannot add image from file while on top-level.");
00308 }
00309 }
00310 } else if(evEvent.strEventName == "add-failure") {
00311 if(evEvent.cdDesignator) {
00312 Node* ndSubject = this->relativeActiveNode(evEvent);
00313
00314 if(ndSubject) {
00315
00316 string strCondition = evEvent.cdDesignator->stringValue("condition");
00317 string strTimeFail = this->getTimeStampStr();
00318
00319 string strFailureID = ndSubject->addFailure(strCondition, strTimeFail);
00320 this->replaceStringInPlace(strFailureID, "-", "_");
00321
00322 m_prLastFailure = make_pair(strFailureID, ndSubject);
00323 ndSubject->setSuccess(false);
00324
00325 this->info("Added failure '" + m_prLastFailure.first + "' to active node (id " + this->str(ndSubject->id()) + "): '" + strCondition.c_str() + "'");
00326
00327 Event evSymbAddFailure = defaultEvent("symbolic-add-failure");
00328 evSymbAddFailure.lstNodes.push_back(ndSubject);
00329 evSymbAddFailure.cdDesignator = new CDesignator();
00330 evSymbAddFailure.cdDesignator->setType(ACTION);
00331 evSymbAddFailure.cdDesignator->setValue("condition", strCondition);
00332 evSymbAddFailure.cdDesignator->setValue("time-fail", strTimeFail);
00333 this->deployEvent(evSymbAddFailure);
00334 } else {
00335 this->warn("No node context available. Cannot add failure while on top-level (this can also mean that the targetted relative node ID does not exist).");
00336 }
00337 }
00338 } else if(evEvent.strEventName == "catch-failure") {
00339 if(evEvent.cdDesignator) {
00340 Node* ndSubject = this->relativeActiveNode(evEvent);
00341
00342 if(ndSubject) {
00343 if(m_prLastFailure.first != "") {
00344 string strID = evEvent.cdDesignator->stringValue("context-id");
00345
00346 if(strID != "") {
00347 int nID;
00348 sscanf(strID.c_str(), "%d", &nID);
00349
00350 Node* ndRelative = ndSubject->relativeWithID(nID);
00351 if(ndRelative) {
00352 ndRelative->catchFailure(m_prLastFailure.first, m_prLastFailure.second, this->getTimeStampStr());
00353
00354
00355 m_mapFailureCatchers[m_prLastFailure.first] = ndRelative;
00356
00357 this->info("Context (ID = " + strID + ") caught failure '" + m_prLastFailure.first + "'");
00358 } else {
00359 this->fail("Relative with ID " + strID + " not found up the chain while catching failure.");
00360 }
00361 } else {
00362 this->warn("Invalid context ID when catching failure: '" + strID + "'.");
00363 }
00364 } else {
00365 this->warn("Tried to catch failure without one being present.");
00366 }
00367 } else {
00368 this->fail("Cannot catch failures outside of context.");
00369 }
00370 }
00371 } else if(evEvent.strEventName == "rethrow-failure") {
00372 if(evEvent.cdDesignator) {
00373 if(m_prLastFailure.first != "") {
00374 if(m_mapFailureCatchers[m_prLastFailure.first]) {
00375 m_mapFailureCatchers[m_prLastFailure.first]->removeCaughtFailure(m_prLastFailure.first);
00376 m_mapFailureCatchers[m_prLastFailure.first] = NULL;
00377
00378 string strID = evEvent.cdDesignator->stringValue("context-id");
00379 this->info("Context (ID = " + strID + ") rethrew failure '" + m_prLastFailure.first + "'");
00380 } else {
00381 this->warn("Apparently caught failure '" + m_prLastFailure.first + "' is not in failure catchers map.");
00382 }
00383 } else {
00384 this->warn("Tried to rethrow failure without active failure. This is probably not what you wanted.");
00385 }
00386 }
00387 } else if(evEvent.strEventName == "add-designator") {
00388 if(evEvent.cdDesignator) {
00389 Node* ndSubject = this->relativeActiveNode(evEvent);
00390
00391 if(ndSubject) {
00392 string strType = evEvent.cdDesignator->stringValue("type");
00393 string strAnnotation = evEvent.cdDesignator->stringValue("annotation");
00394 string strMemAddr = evEvent.cdDesignator->stringValue("memory-address");
00395
00396 CKeyValuePair* ckvpDesc = evEvent.cdDesignator->childForKey("description");
00397
00398 list<CKeyValuePair*> lstDescription = ckvpDesc->children();
00399 this->ensureDesignatorPublished(lstDescription, strMemAddr, strType, strAnnotation, true, this->relativeActiveNode(evEvent));
00400 } else {
00401 this->warn("No node context available. Cannot add designator while on top-level.");
00402 }
00403 }
00404 } else if(evEvent.strEventName == "equate-designators") {
00405 if(evEvent.cdDesignator) {
00406 string strMemAddrChild = evEvent.cdDesignator->stringValue("memory-address-child");
00407 string strMemAddrParent = evEvent.cdDesignator->stringValue("memory-address-parent");
00408
00409 if(strMemAddrChild != "" && strMemAddrParent != "") {
00410 Node* ndSubject = this->relativeActiveNode(evEvent);
00411
00412 if(ndSubject) {
00413
00414 CKeyValuePair* ckvpDescChild = evEvent.cdDesignator->childForKey("description-child");
00415
00416 if(this->ensureDesignatorPublished(ckvpDescChild->children(), strMemAddrParent, evEvent.cdDesignator->stringValue("type-child"), "", false, this->relativeActiveNode(evEvent))) {
00417 this->info("Added non-existant child-designator during 'equate'");
00418 }
00419
00420
00421 CKeyValuePair* ckvpDescParent = evEvent.cdDesignator->childForKey("description-parent");
00422 if(this->ensureDesignatorPublished(ckvpDescParent->children(), strMemAddrParent, evEvent.cdDesignator->stringValue("type-parent"), "", false, this->relativeActiveNode(evEvent))) {
00423 this->warn("Added non-existant parent-designator during 'equate'");
00424 }
00425
00426 CDesignator* desigChild = this->makeDesignator(evEvent.cdDesignator->stringValue("type-child"), ckvpDescChild->children());
00427 CDesignator* desigParent = this->makeDesignator(evEvent.cdDesignator->stringValue("type-parent"), ckvpDescParent->children());
00428
00429 string strEquationTime = this->equateDesignators(strMemAddrChild, desigChild, strMemAddrParent, desigParent);
00430
00431 delete desigChild;
00432 delete desigParent;
00433
00434 string strUniqueIDParent = this->getDesignatorID(strMemAddrParent);
00435 string strUniqueIDChild = this->getDesignatorID(strMemAddrChild);
00436
00437 this->info("Equated designators " + strUniqueIDChild + " (successor) and " + strUniqueIDParent + " (parent).");
00438
00439 Event evEquateDesigs = defaultEvent("symbolic-equate-designators");
00440 evEquateDesigs.cdDesignator = new CDesignator();
00441 evEquateDesigs.cdDesignator->setType(ACTION);
00442 evEquateDesigs.cdDesignator->setValue("parent-id", strUniqueIDParent);
00443 evEquateDesigs.cdDesignator->setValue("child-id", strUniqueIDChild);
00444 evEquateDesigs.cdDesignator->setValue("equation-time", strEquationTime);
00445
00446 this->deployEvent(evEquateDesigs);
00447 }
00448 }
00449 }
00450 } else if(evEvent.strEventName == "add-object") {
00451 if(evEvent.cdDesignator) {
00452 CKeyValuePair* ckvpDesc = evEvent.cdDesignator->childForKey("description");
00453
00454 if(ckvpDesc) {
00455 Node* ndSubject = this->relativeActiveNode(evEvent);
00456
00457 if(ndSubject) {
00458 string strType = evEvent.cdDesignator->stringValue("type");
00459 string strMemAddr = evEvent.cdDesignator->stringValue("memory-address");
00460
00461 bool bDesigExists = (this->getDesignatorID(strMemAddr) != "");
00462
00463 CDesignator* desigCurrent = this->makeDesignator(strType, ckvpDesc->children());
00464 string strUniqueID = this->getUniqueDesignatorID(strMemAddr, desigCurrent);
00465 delete desigCurrent;
00466
00467 if(!bDesigExists) {
00468 this->info("Adding non-existant object-designator to current context");
00469
00470 CKeyValuePair *ckvpDesc = evEvent.cdDesignator->childForKey("description");
00471 list<CKeyValuePair*> lstDescription = ckvpDesc->children();
00472
00473 CDesignator* cdTemp = new CDesignator(OBJECT, lstDescription);
00474 cdTemp->setValue("_id", strUniqueID);
00475
00476
00477 Event evLoggedDesignator = defaultEvent("symbolic-create-designator");
00478 evLoggedDesignator.cdDesignator = cdTemp;
00479
00480 this->deployEvent(evLoggedDesignator);
00481
00482
00483 Event evAddedDesignator = defaultEvent("symbolic-add-designator");
00484 evAddedDesignator.cdDesignator = new CDesignator(cdTemp);
00485 evAddedDesignator.lstNodes.push_back(ndSubject);
00486 evAddedDesignator.strAnnotation = evEvent.cdDesignator->stringValue("annotation");
00487
00488 this->deployEvent(evAddedDesignator);
00489 }
00490
00491 ckvpDesc->setValue("__id", strUniqueID);
00492
00493 if(evEvent.cdDesignator->childForKey("class")) {
00494 ckvpDesc->setValue(std::string("_class"), evEvent.cdDesignator->stringValue("class"));
00495
00496 if(evEvent.cdDesignator->childForKey("classnamespace")) {
00497 ckvpDesc->setValue(std::string("_classnamespace"), evEvent.cdDesignator->stringValue("classnamespace"));
00498 }
00499 }
00500
00501 if(evEvent.cdDesignator->childForKey("property")) {
00502 ckvpDesc->setValue(std::string("_property"), evEvent.cdDesignator->stringValue("property"));
00503 }
00504
00505 ndSubject->addObject(ckvpDesc->children());
00506 this->info("Added object (" + strUniqueID + ") to active node (id " + this->str(ndSubject->id()) + ").");
00507
00508
00509 Event evSymAddObj = defaultEvent("symbolic-add-object");
00510 evSymAddObj.cdDesignator = new CDesignator(OBJECT, ckvpDesc);
00511
00512
00513
00514
00515
00516 evSymAddObj.cdDesignator->setValue("name", "object0");
00517
00518 if(evSymAddObj.cdDesignator->childForKey("pose") != NULL) {
00519 if(evSymAddObj.cdDesignator->childForKey("pose")->type() == POSESTAMPED) {
00520 evSymAddObj.cdDesignator->setValue("pose-stamped", evSymAddObj.cdDesignator->poseStampedValue("pose"));
00521 } else if(evSymAddObj.cdDesignator->childForKey("pose")->type() == POSE) {
00522 evSymAddObj.cdDesignator->setValue("pose", evSymAddObj.cdDesignator->poseStampedValue("pose"));
00523 }
00524 }
00525
00526 string strObjName = evSymAddObj.cdDesignator->stringValue("name");
00527
00528 CKeyValuePair* ckvpMenu = evSymAddObj.cdDesignator->addChild("menu");
00529 CKeyValuePair* ckvpMenuPickObject = ckvpMenu->addChild("PICK-OBJECT");
00530 ckvpMenuPickObject->setValue("label", "Pick up object " + strObjName);
00531 ckvpMenuPickObject->setValue("parameter", strObjName);
00532
00533 this->deployEvent(evSymAddObj);
00534 } else {
00535 this->warn("No node context available. Cannot add object while on top-level.");
00536 }
00537 }
00538 }
00539 } else if(evEvent.strEventName == "start-new-experiment") {
00540 this->info("Clearing symbolic log for new experiment.");
00541
00542 m_mapNodeIDs.clear();
00543
00544 for(Node* ndNode : m_lstNodes) {
00545 delete ndNode;
00546 }
00547
00548 m_lstNodes.clear();
00549 m_lstRootNodes.clear();
00550 m_ndActive = NULL;
00551
00552 m_lstDesignatorIDs.clear();
00553 m_lstDesignatorEquations.clear();
00554 m_lstDesignatorEquationTimes.clear();
00555
00556 m_prLastFailure = make_pair("", (Node*)NULL);
00557
00558 srand(time(NULL));
00559
00560 this->info("Ready for new experiment.");
00561 } else {
00562 this->warn("Unknown event name: '" + evEvent.strEventName + "'");
00563 }
00564 }
00565
00566 Node* PLUGIN_CLASS::addNode(string strName, int nContextID, Node* ndParent) {
00567 Node* ndNew = new Node(strName);
00568 ndNew->setID(nContextID);
00569
00570 m_mapNodeIDs[nContextID] = ndNew;
00571
00572 if(ndParent == NULL) {
00573
00574
00575 ndParent = m_ndActive;
00576 }
00577
00578 bool bSetAsActive = (ndParent == m_ndActive);
00579
00580 if(ndParent == NULL) {
00581
00582 m_lstNodes.push_back(ndNew);
00583
00584 this->info("Adding new top-level context with ID " + this->str(nContextID));
00585 } else {
00586
00587 ndParent->addSubnode(ndNew);
00588
00589 this->info("Adding new sub context with ID " + this->str(nContextID));
00590 }
00591
00592 if(bSetAsActive) {
00593 this->setNodeAsActive(ndNew);
00594 this->info("The new context's name is '" + strName + "' (now active)");
00595 } else {
00596 this->info("The new context's name is '" + strName + "'");
00597 }
00598
00599 return ndNew;
00600 }
00601
00602 void PLUGIN_CLASS::setNodeAsActive(Node* ndActive) {
00603 bool bSame = false;
00604
00605 if(!m_ndActive && ndActive) {
00606 m_lstRootNodes.push_back(ndActive);
00607 }
00608
00609 m_ndActive = ndActive;
00610
00611 if(m_ndActive) {
00612 bSame = (m_ndActive->id() == ndActive->id());
00613 }
00614
00615 if(m_ndActive) {
00616 if(!bSame) {
00617 this->info("Setting context ID " + this->str(m_ndActive->id()) + " as active context");
00618 }
00619
00620
00621 Event evActiveNode = defaultEvent("symbolic-node-active");
00622 evActiveNode.lstNodes.push_back(m_ndActive);
00623 this->deployEvent(evActiveNode);
00624 } else {
00625 this->info("Removed active context, returning to top-level");
00626
00627
00628 Event evActiveNode = defaultEvent("symbolic-node-active");
00629 this->deployEvent(evActiveNode);
00630 }
00631 }
00632
00633 Node* PLUGIN_CLASS::activeNode() {
00634 return m_ndActive;
00635 }
00636
00637 std::string PLUGIN_CLASS::getDesignatorID(std::string strMemoryAddress) {
00638 std::string strID = "";
00639
00640 for(pair<string, string> prPair : m_lstDesignatorIDs) {
00641 if(prPair.first == strMemoryAddress) {
00642 strID = prPair.second;
00643 break;
00644 }
00645 }
00646
00647 return strID;
00648 }
00649
00650 std::string PLUGIN_CLASS::getDesignatorIDType(CDesignator* desigCurrent) {
00651
00652
00653 std::string strType = "designator";
00654
00655 switch(desigCurrent->type()) {
00656 case ACTION:
00657 strType = "action";
00658 break;
00659
00660 case OBJECT:
00661 strType = "object";
00662 break;
00663
00664 case LOCATION:
00665 strType = "location";
00666 break;
00667
00668 default:
00669 break;
00670 }
00671
00672 return strType;
00673 }
00674
00675 std::string PLUGIN_CLASS::getUniqueDesignatorID(string strMemoryAddress, CDesignator* desigCurrent) {
00676 string strID = this->getDesignatorID(strMemoryAddress);
00677
00678 if(strID == "") {
00679 strID = this->generateRandomIdentifier(this->getDesignatorIDType(desigCurrent) + "_", 14);
00680 m_lstDesignatorIDs.push_back(make_pair(strMemoryAddress, strID));
00681 }
00682
00683 return strID;
00684 }
00685
00686 string PLUGIN_CLASS::generateRandomIdentifier(string strPrefix, unsigned int unLength) {
00687 stringstream sts;
00688 sts << strPrefix;
00689
00690 for(unsigned int unI = 0; unI < unLength; unI++) {
00691 int nRandom;
00692 do {
00693 nRandom = rand() % 122 + 48;
00694 } while(nRandom < 48 ||
00695 (nRandom > 57 && nRandom < 65) ||
00696 (nRandom > 90 && nRandom < 97) ||
00697 nRandom > 122);
00698
00699 char cRandom = (char)nRandom;
00700 sts << cRandom;
00701 }
00702
00703 return sts.str();
00704 }
00705
00706 string PLUGIN_CLASS::equateDesignators(std::string strMAChild, CDesignator* desigChild, std::string strMAParent, CDesignator* desigParent) {
00707 string strIDChild = this->getUniqueDesignatorID(strMAChild, desigChild);
00708 string strIDParent = this->getUniqueDesignatorID(strMAParent, desigParent);
00709
00710 string strTimeStart = this->getTimeStampStr();
00711
00712 m_lstDesignatorEquations.push_back(make_pair(strIDParent, strIDChild));
00713 m_lstDesignatorEquationTimes.push_back(make_pair(strIDChild, strTimeStart));
00714
00715 return strTimeStart;
00716 }
00717
00718 bool PLUGIN_CLASS::ensureDesignatorPublished(list<CKeyValuePair*> lstDescription, string strMemoryAddress, string strType, string strAnnotation, bool bAdd, Node* ndRelative) {
00719 bool bDesigExists = (this->getDesignatorID(strMemoryAddress) != "");
00720 bool bReturn = false;
00721 bool bDeleteMe = true;
00722
00723 if(ndRelative == NULL) {
00724 ndRelative = this->activeNode();
00725 }
00726
00727 CDesignator* desigCurrent = this->makeDesignator(strType, lstDescription);
00728 desigCurrent->setValue("_time_created", this->getTimeStampStr());
00729
00730 std::string strUniqueID = this->getUniqueDesignatorID(strMemoryAddress, desigCurrent);
00731
00732 if(bAdd) {
00733 ndRelative->addDesignator(strType, desigCurrent->children(), strUniqueID, strAnnotation);
00734
00735 this->info("Added '" + strType + "' designator (addr=" + strMemoryAddress + ") to context (id " + this->str(ndRelative->id()) + "): '" + strUniqueID + "', annotation: '" + strAnnotation + "'");
00736 }
00737
00738 if(!bDesigExists) {
00739 desigCurrent->setValue("_id", strUniqueID);
00740
00741 if(strAnnotation != "") {
00742 desigCurrent->setValue("_annotation", strAnnotation);
00743 }
00744
00745
00746 Event evLoggedDesignator = defaultEvent("symbolic-create-designator");
00747 evLoggedDesignator.cdDesignator = new CDesignator(desigCurrent);
00748 evLoggedDesignator.strAnnotation = strAnnotation;
00749
00750 this->deployEvent(evLoggedDesignator);
00751
00752
00753 Event evAddedDesignator = defaultEvent("symbolic-add-designator");
00754 evAddedDesignator.cdDesignator = new CDesignator(desigCurrent);
00755 evAddedDesignator.strAnnotation = strAnnotation;
00756 evAddedDesignator.lstNodes.push_back(ndRelative);
00757
00758 this->deployEvent(evAddedDesignator);
00759
00760
00761
00762
00763 this->setNestedDesignatorUniqueIDs(desigCurrent);
00764
00765 bReturn = true;
00766 }
00767
00768 if(bDeleteMe) {
00769 delete desigCurrent;
00770 }
00771
00772 return bReturn;
00773 }
00774
00775 void PLUGIN_CLASS::setNestedDesignatorUniqueIDs(CKeyValuePair* ckvpParent) {
00776 bool bIsDesignator = false;
00777 string strMemAddr = "";
00778
00779 if(ckvpParent->childForKey("_designator_memory_address")) {
00780 strMemAddr = ckvpParent->childForKey("_designator_memory_address")->stringValue();
00781 CDesignator* desigCurrent = this->makeDesignator("", ckvpParent->children());
00782 string strID = this->getUniqueDesignatorID(strMemAddr, desigCurrent);
00783 delete desigCurrent;
00784
00785 ckvpParent->setValue("_id", strID);
00786 bIsDesignator = true;
00787 }
00788
00789 list<CKeyValuePair*> lstChildren = ckvpParent->children();
00790
00791 for(CKeyValuePair* ckvpChild : lstChildren) {
00792 this->setNestedDesignatorUniqueIDs(ckvpChild);
00793 }
00794
00795 if(bIsDesignator) {
00796 string strTypePre = ckvpParent->stringValue("_designator_type");
00797 string strType = (strTypePre == "" ? "OBJECT" : strTypePre);
00798
00799 this->ensureDesignatorPublished(ckvpParent->children(), strMemAddr, strType);
00800 }
00801 }
00802
00803 CDesignator* PLUGIN_CLASS::makeDesignator(enum DesignatorType edtType, list<CKeyValuePair*> lstDescription) {
00804 return new CDesignator(edtType, lstDescription);
00805 }
00806
00807 CDesignator* PLUGIN_CLASS::makeDesignator(std::string strType, list<CKeyValuePair*> lstDescription) {
00808 enum DesignatorType edtType = UNKNOWN;
00809
00810 if(strType == "ACTION") {
00811 edtType = ACTION;
00812 } else if(strType == "OBJECT") {
00813 edtType = OBJECT;
00814 } else if(strType == "LOCATION") {
00815 edtType = LOCATION;
00816 }
00817
00818 return this->makeDesignator(edtType, lstDescription);
00819 }
00820
00821 Node* PLUGIN_CLASS::nodeByID(int nID) {
00822 if(m_mapNodeIDs.find(nID) != m_mapNodeIDs.end()) {
00823 return m_mapNodeIDs[nID];
00824 }
00825
00826 return NULL;
00827 }
00828
00829 Node* PLUGIN_CLASS::relativeActiveNode(Event evEvent) {
00830 Node* ndSubject = this->activeNode();
00831
00832 if(evEvent.cdDesignator) {
00833 if(evEvent.cdDesignator->childForKey("_relative_context_id")) {
00834 ndSubject = this->nodeByID(evEvent.cdDesignator->floatValue("_relative_context_id"));
00835 }
00836 }
00837
00838 return ndSubject;
00839 }
00840 }
00841
00842 extern "C" plugins::PLUGIN_CLASS* createInstance() {
00843 return new plugins::PLUGIN_CLASS();
00844 }
00845
00846 extern "C" void destroyInstance(plugins::PLUGIN_CLASS* icDestroy) {
00847 delete icDestroy;
00848 }
00849 }