// Description: a space that generates events in the presence of a node // //notes: // // // Category: Trigger // Author: Alex Hill // Revision: 10/01/02 // #include #include #include #include #include "betterNodeTrigger.h" using namespace std; extern "C" ygNode* construct_betterNodeTrigger(const char* name,bool master) { return new betterNodeTrigger(name,master); } struct _betterNodeTriggerPrivateData { ygString detectType; ygString detectName; set prevInside; bool debugInside; int lastFrame; }; betterNodeTrigger::betterNodeTrigger(const char* name,bool master) : ygSpace(name,master) { setClassName("betterNodeTrigger"); p_ = new struct _betterNodeTriggerPrivateData; p_->lastFrame = 0; debugFlag("inside", &p_->debugInside); } betterNodeTrigger::~betterNodeTrigger(void) { delete p_; } void betterNodeTrigger::reset(void) { //clear set of nodes previously inside p_->prevInside.clear(); p_->lastFrame = ygWorld::FrameNumber; ygSpace::reset(); } void betterNodeTrigger::message(const ygMessage& msg) { //set the type of node to detect if (msg == "type") { if (msg.args.size() > 0) setDetectType(msg.args[0]); else msg.error(name(),"(wrong number of arguments)"); } else if (msg == "node") { setDetectName(msg.args[0]); } else ygSpace::message(msg); } void betterNodeTrigger::setDetectType(const ygString& s) { p_->detectType = s; } void betterNodeTrigger::setDetectName(const ygString& s) { p_->detectName = s; } void betterNodeTrigger::app(void) { set inside; int i; if (p_->lastFrame < (ygWorld::FrameNumber-1)) p_->prevInside.clear(); p_->lastFrame = ygWorld::FrameNumber; const vector& nodes = ygNodeDB::nodesOfType(p_->detectType); //for each node of detect type in the world for (i=0; i < nodes.size(); i++) { if (p_->detectName == "" || nodes[i]->name() == p_->detectName) { //if node is within the space if (contains(nodes[i]->origin(this))) { if (p_->debugInside) cout << name() << ": " << nodes[i]->name() << " is inside\n"; //add to set of nodes inside inside.insert(inside.begin(),nodes[i]); //if inside but not previously then generate enter event if (p_->prevInside.find(nodes[i]) == p_->prevInside.end()) { ygString args("node="); args += nodes[i]->name(); //the node has entered the space eventOccurred("enter",args); } } } } set::const_iterator iter; //for each node previously inside for (iter = p_->prevInside.begin(); iter != p_->prevInside.end(); ++iter) //if not currently inside then generate exit event if (inside.find(*iter) == inside.end()) { ygString args("node="); args += (*iter)->name(); //the node has exited the space eventOccurred("exit",args); } p_->prevInside = inside; ygSpace::app(); }