SpiderMachineBehavior.ccGo to the documentation of this file.00001 #include "SpiderMachineBehavior.h"
00002 #include "Events/EventRouter.h"
00003 #include "Behaviors/StateNode.h"
00004 #include "Wireless/Wireless.h"
00005
00006 SpiderMachineBehavior * SpiderMachineBehavior::theOne=NULL;
00007 unsigned int SpiderMachineBehavior::port=10081;
00008
00009 void SpiderMachineBehavior::DoStart() {
00010 BehaviorBase::DoStart();
00011 theOne=this;
00012
00013 cmdsock=wireless->socket(SocketNS::SOCK_STREAM, 1024, 1024*10);
00014 wireless->setDaemon(cmdsock,true);
00015 wireless->setReceiver(cmdsock->sock, callback);
00016 wireless->listen(cmdsock->sock, port);
00017 erouter->addListener(this,EventBase::stateMachineEGID);
00018 erouter->addListener(this,EventBase::stateTransitionEGID);
00019 }
00020
00021 void SpiderMachineBehavior::DoStop() {
00022 erouter->removeListener(this);
00023 expected.clear();
00024 while(!queuedEvents.empty())
00025 queuedEvents.pop();
00026
00027 wireless->setDaemon(cmdsock,false);
00028 wireless->close(cmdsock);
00029 if(theOne==this)
00030 theOne=NULL;
00031 BehaviorBase::DoStop();
00032 }
00033
00034 void SpiderMachineBehavior::processEvent(const EventBase& e) {
00035 if(!wireless->isConnected(cmdsock->sock) || listen.size()==0)
00036 return;
00037
00038 if(e.getGeneratorID()==EventBase::stateTransitionEGID) {
00039 bool care=false;
00040 const Transition * trans = reinterpret_cast<Transition*>(e.getSourceID());
00041 const std::vector<StateNode*>& incoming=trans->getSources();
00042 const std::vector<StateNode*>& outgoing=trans->getDestinations();
00043 for(std::vector<StateNode*>::const_iterator it=incoming.begin(); it!=incoming.end() && !care; it++)
00044 care=isListening(*it);
00045 for(std::vector<StateNode*>::const_iterator it=outgoing.begin(); it!=outgoing.end() && !care; it++)
00046 care=isListening(*it);
00047 if(!care)
00048 return;
00049
00050 if(expected.size()!=0) {
00051 queuedEvents.push(e);
00052 } else {
00053 cmdsock->printf("<event>\n");
00054 indent(1);
00055 cmdsock->printf("<fire id=\"%s\" time=\"%d\" />\n",trans->getName().c_str(),e.getTimeStamp());
00056 expected.insert(incoming.begin(),incoming.end());
00057 expected.insert(outgoing.begin(),outgoing.end());
00058 while(queuedEvents.size()>0) {
00059 EventBase qe=queuedEvents.front();
00060 queuedEvents.pop();
00061 processEvent(qe);
00062 }
00063 }
00064
00065 } else if(e.getGeneratorID()==EventBase::stateMachineEGID) {
00066 if(e.getTypeID()==EventBase::statusETID)
00067 return;
00068 const StateNode * beh=reinterpret_cast<StateNode*>(e.getSourceID());
00069 expected_t::iterator it=expected.find(beh);
00070 char * format;
00071 if(isListening(beh)) {
00072 if(it==expected.end()) {
00073 if(queuedEvents.size()==0)
00074 format="<event><state%s id=\"%s\" time=\"%d\" /></event>\n";
00075 else {
00076 queuedEvents.push(e);
00077 return;
00078 }
00079 } else
00080 format=" <state%s id=\"%s\" time=\"%d\" />\n";
00081 if(e.getTypeID()==EventBase::activateETID)
00082 cmdsock->printf(format,"start",beh->getName().c_str(),e.getTimeStamp());
00083 else if(e.getTypeID()==EventBase::deactivateETID)
00084 cmdsock->printf(format,"stop",beh->getName().c_str(),e.getTimeStamp());
00085 else
00086 serr->printf("WARNING: Unrecognized TypeID %d\n",e.getTypeID());
00087 }
00088 if(it!=expected.end()) {
00089 expected.erase(it);
00090 if(expected.size()==0) {
00091 cmdsock->printf("</event>\n");
00092 while(queuedEvents.size()>0) {
00093 EventBase qe=queuedEvents.front();
00094 queuedEvents.pop();
00095 processEvent(qe);
00096 }
00097 }
00098 }
00099
00100 } else {
00101 serr->printf("WARNING: Unknown event %s (%s)\n",e.getName().c_str(),e.getDescription().c_str());
00102 }
00103 }
00104
00105 void SpiderMachineBehavior::spider(const StateNode* n, unsigned int depth) {
00106 if(n==NULL)
00107 return;
00108
00109 const std::vector<StateNode*>& subnodes=n->getNodes();
00110 if(subnodes.size()==0) {
00111
00112 indent(depth);
00113 cmdsock->printf("<state class=\"%s\" id=\"%s\" />\n", n->getClassName().c_str(), n->getName().c_str());
00114 } else {
00115
00116
00117 indent(depth);
00118 cmdsock->printf("<state class=\"%s\" id=\"%s\">\n", n->getClassName().c_str(), n->getName().c_str());
00119
00120 std::set<const Transition*> transitions;
00121
00122 for(unsigned int i=0; i<subnodes.size(); i++) {
00123 spider(subnodes[i],depth+1);
00124 const std::vector<Transition*>& curt=subnodes[i]->getTransitions();
00125 transitions.insert(curt.begin(),curt.end());
00126 }
00127
00128
00129 for(std::set<const Transition*>::const_iterator it=transitions.begin(); it!=transitions.end(); it++) {
00130 indent(depth+1);
00131 cmdsock->printf("<transition class=\"%s\" id=\"%s\">\n", (*it)->getClassName().c_str(), (*it)->getName().c_str());
00132 const std::vector<StateNode*>& incoming=(*it)->getSources();
00133 for(unsigned int i=0; i<incoming.size(); i++) {
00134 indent(depth+2);
00135 cmdsock->printf("<source>%s</source>\n",incoming[i]->getName().c_str());
00136 }
00137 const std::vector<StateNode*>& outgoing=(*it)->getDestinations();
00138 for(unsigned int i=0; i<outgoing.size(); i++) {
00139 indent(depth+2);
00140 cmdsock->printf("<destination>%s</destination>\n",outgoing[i]->getName().c_str());
00141 }
00142 indent(depth+1);
00143 cmdsock->printf("</transition>\n");
00144 }
00145
00146 indent(depth);
00147 cmdsock->printf("</state>\n");
00148 }
00149 }
00150
00151 bool SpiderMachineBehavior::isListening(const StateNode* n) {
00152 while(n!=NULL) {
00153 if(listen.find(n->getName())!=listen.end())
00154 return true;
00155 n=n->getParent();
00156 }
00157 return false;
00158 }
00159
00160 void SpiderMachineBehavior::indent(unsigned int level) {
00161 for(unsigned int i=0; i<level; i++)
00162 cmdsock->printf(" ");
00163 }
00164
00165 const StateNode * SpiderMachineBehavior::find(const std::string& name) {
00166 for(registry_t::const_iterator it=registry.begin(); it!=registry.end(); it++) {
00167 const StateNode * cur=dynamic_cast<const StateNode*>(*it);
00168 if(cur!=NULL && cur->getName()==name)
00169 return cur;
00170 }
00171
00172 return NULL;
00173 }
00174
00175 void SpiderMachineBehavior::runCommand(const std::string& s) {
00176 if(s==std::string("list")) {
00177 unsigned int numstate=0;
00178 for(registry_t::const_iterator it=registry.begin(); it!=registry.end(); it++) {
00179 const StateNode * cur=dynamic_cast<const StateNode*>(*it);
00180 if(cur!=NULL)
00181 numstate++;
00182 }
00183 cmdsock->printf("%d\n",numstate);
00184 for(registry_t::const_iterator it=registry.begin(); it!=registry.end(); it++) {
00185 const StateNode * cur=dynamic_cast<const StateNode*>(*it);
00186 if(cur!=NULL)
00187 cmdsock->printf("%s\n",cur->getName().c_str());
00188 }
00189
00190 } else if(s.find("spider ")==0) {
00191 const StateNode * n=find(s.substr(7));
00192 if(n==NULL) {
00193 serr->printf("WARNING: SpiderMachineBehavior could not find \"%s\" for spidering\n",s.substr(7).c_str());
00194 cmdsock->printf("<model></model>\n");
00195 } else {
00196 cmdsock->printf("<model>\n");
00197 spider(n);
00198 cmdsock->printf("</model>\n");
00199 }
00200
00201 } else if(s.find("listen ")==0) {
00202 listen.insert(s.substr(7));
00203
00204 } else if(s.find("ignore ")==0) {
00205 listen.erase(s.substr(7));
00206
00207 } else if(s=="clear") {
00208 listen.clear();
00209
00210 } else {
00211 serr->printf("SpiderMachineBehavior::runCommand() - bad message: '%s'\n",s.c_str());
00212 }
00213 }
00214
00215
00216 int SpiderMachineBehavior::callback(char *buf, int bytes) {
00217 if(SpiderMachineBehavior::theOne==NULL)
00218 return 0;
00219 static std::string cmd;
00220 for(int i=0; i<bytes; i++) {
00221 if(buf[i]=='\n') {
00222 SpiderMachineBehavior::theOne->runCommand(cmd);
00223 cmd.clear();
00224 } else if(buf[i]!='\r')
00225 cmd+=buf[i];
00226 }
00227 return 0;
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
|