From df1a85e306a0403264dce219ef00696f4f82cedd Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 6 Aug 2003 18:34:48 +0000 Subject: [PATCH] improve tag-based events --- panda/src/collide/collisionHandlerEvent.I | 179 ++++++++++++++++---- panda/src/collide/collisionHandlerEvent.cxx | 56 +++--- panda/src/collide/collisionHandlerEvent.h | 31 +++- 3 files changed, 200 insertions(+), 66 deletions(-) diff --git a/panda/src/collide/collisionHandlerEvent.I b/panda/src/collide/collisionHandlerEvent.I index 94c3aeef0b..81516dd27f 100644 --- a/panda/src/collide/collisionHandlerEvent.I +++ b/panda/src/collide/collisionHandlerEvent.I @@ -49,12 +49,23 @@ operator = (const CollisionHandlerEvent::SortEntries &) { } //////////////////////////////////////////////////////////////////// -// Function: CollisionHandlerEvent::set_in_pattern +// Function: CollisionHandlerEvent::clear_in_patterns // Access: Public -// Description: Sets the pattern string that indicates how the event -// names are generated for each collision detected. -// This is a string that may contain any of the -// following: +// Description: Removes all of the previously-added in patterns. See +// add_in_pattern. +//////////////////////////////////////////////////////////////////// +INLINE void CollisionHandlerEvent:: +clear_in_patterns() { + _in_patterns.clear(); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerEvent::add_in_pattern +// Access: Public +// Description: Adds a pattern string to the list of events that will +// be generated in response to a collision. The pattern +// string describes how the event name will be composed. +// It is a string that may contain any of the following: // // %fn - the name of the "from" object's node // %in - the name of the "into" object's node @@ -63,15 +74,16 @@ operator = (const CollisionHandlerEvent::SortEntries &) { // %ig - 'c' if the collision is into a // CollisionNode, 'g' if it is a geom. // -// %(tag)fh - '1' if "from" has the indicated tag, -// '0' if it does not. -// %(tag)ih - '1' if "into" has the indicated tag, -// '0' if it does not. -// %(tag)iH - '1' if "into" has the indicated net tag, -// '0' if it does not. +// %(tag)fh - generate event only if "from" node has +// the indicated tag. +// %(tag)fx - generate event only if "from" node does +// not have the indicated tag. +// %(tag)ih - generate event only if "into" node has +// the indicated net tag. +// %(tag)ix - generate event only if "into" node does +// not have the indicated net tag. // %(tag)ft - the indicated tag value of the "from" node. -// %(tag)it - the indicated tag value of the "to" node. -// %(tag)iT - the indicated net tag value of the "to" node. +// %(tag)it - the indicated net tag value of the "into" node. // // Parentheses in the above are literal and should be // included in the actual pattern. @@ -89,26 +101,62 @@ operator = (const CollisionHandlerEvent::SortEntries &) { // out_pattern event is thrown. //////////////////////////////////////////////////////////////////// INLINE void CollisionHandlerEvent:: +add_in_pattern(const string &in_pattern) { + _in_patterns.push_back(in_pattern); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerEvent::set_in_pattern +// Access: Public +// Description: This method is deprecated; it completely replaces all +// the in patterns that have previously been set with +// the indicated pattern. +//////////////////////////////////////////////////////////////////// +INLINE void CollisionHandlerEvent:: set_in_pattern(const string &in_pattern) { - _in_pattern = in_pattern; + clear_in_patterns(); + add_in_pattern(in_pattern); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerEvent::get_num_in_patterns +// Access: Public +// Description: Returns the number of in pattern strings that have +// been added. +//////////////////////////////////////////////////////////////////// +INLINE int CollisionHandlerEvent:: +get_num_in_patterns() const { + return _in_patterns.size(); } //////////////////////////////////////////////////////////////////// // Function: CollisionHandlerEvent::get_in_pattern // Access: Public -// Description: Returns the pattern string that indicates how the +// Description: Returns the nth pattern string that indicates how the // event names are generated for each collision -// detected. See set_in_pattern(). +// detected. See add_in_pattern(). //////////////////////////////////////////////////////////////////// INLINE string CollisionHandlerEvent:: -get_in_pattern() const { - return _in_pattern; +get_in_pattern(int n) const { + nassertr(n >= 0 && n < (int)_in_patterns.size(), string()); + return _in_patterns[n]; } //////////////////////////////////////////////////////////////////// -// Function: CollisionHandlerEvent::set_again_pattern +// Function: CollisionHandlerEvent::clear_again_patterns // Access: Public -// Description: Sets the pattern string that indicates how the event +// Description: Removes all of the previously-added in patterns. See +// add_again_pattern. +//////////////////////////////////////////////////////////////////// +INLINE void CollisionHandlerEvent:: +clear_again_patterns() { + _again_patterns.clear(); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerEvent::add_again_pattern +// Access: Public +// Description: Adds the pattern string that indicates how the event // names are generated when a collision between two // particular nodes is *still* detected. This event is // thrown each consecutive time a collision between two @@ -124,28 +172,62 @@ get_in_pattern() const { // out_pattern event is thrown. //////////////////////////////////////////////////////////////////// INLINE void CollisionHandlerEvent:: +add_again_pattern(const string &again_pattern) { + _again_patterns.push_back(again_pattern); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerEvent::set_again_pattern +// Access: Public +// Description: This method is deprecated; it completely replaces all +// the in patterns that have previously been set with +// the indicated pattern. +//////////////////////////////////////////////////////////////////// +INLINE void CollisionHandlerEvent:: set_again_pattern(const string &again_pattern) { - _again_pattern = again_pattern; + clear_again_patterns(); + add_again_pattern(again_pattern); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerEvent::get_num_again_patterns +// Access: Public +// Description: Returns the number of in pattern strings that have +// been added. +//////////////////////////////////////////////////////////////////// +INLINE int CollisionHandlerEvent:: +get_num_again_patterns() const { + return _again_patterns.size(); } //////////////////////////////////////////////////////////////////// // Function: CollisionHandlerEvent::get_again_pattern // Access: Public -// Description: Returns the pattern string that indicates how the -// event names are generated when a collision between -// two particular nodes is *still* detected. See -// set_again_pattern() and set_in_pattern(). +// Description: Returns the nth pattern string that indicates how the +// event names are generated for each collision +// detected. See add_again_pattern(). //////////////////////////////////////////////////////////////////// INLINE string CollisionHandlerEvent:: -get_again_pattern() const { - return _again_pattern; +get_again_pattern(int n) const { + nassertr(n >= 0 && n < (int)_again_patterns.size(), string()); + return _again_patterns[n]; } +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerEvent::clear_out_patterns +// Access: Public +// Description: Removes all of the previously-added in patterns. See +// add_out_pattern. +//////////////////////////////////////////////////////////////////// +INLINE void CollisionHandlerEvent:: +clear_out_patterns() { + _out_patterns.clear(); +} //////////////////////////////////////////////////////////////////// -// Function: CollisionHandlerEvent::set_out_pattern +// Function: CollisionHandlerEvent::add_out_pattern // Access: Public -// Description: Sets the pattern string that indicates how the event +// Description: Adds the pattern string that indicates how the event // names are generated when a collision between two // particular nodes is *no longer* detected. // @@ -158,20 +240,43 @@ get_again_pattern() const { // out_pattern event is thrown. //////////////////////////////////////////////////////////////////// INLINE void CollisionHandlerEvent:: +add_out_pattern(const string &out_pattern) { + _out_patterns.push_back(out_pattern); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerEvent::set_out_pattern +// Access: Public +// Description: This method is deprecated; it completely replaces all +// the in patterns that have previously been set with +// the indicated pattern. +//////////////////////////////////////////////////////////////////// +INLINE void CollisionHandlerEvent:: set_out_pattern(const string &out_pattern) { - _out_pattern = out_pattern; + clear_out_patterns(); + add_out_pattern(out_pattern); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerEvent::get_num_out_patterns +// Access: Public +// Description: Returns the number of in pattern strings that have +// been added. +//////////////////////////////////////////////////////////////////// +INLINE int CollisionHandlerEvent:: +get_num_out_patterns() const { + return _out_patterns.size(); } //////////////////////////////////////////////////////////////////// // Function: CollisionHandlerEvent::get_out_pattern // Access: Public -// Description: Returns the pattern string that indicates how the -// event names are generated when a collision between -// two particular nodes is *no longer* detected. See -// set_out_pattern() and set_in_pattern(). +// Description: Returns the nth pattern string that indicates how the +// event names are generated for each collision +// detected. See add_out_pattern(). //////////////////////////////////////////////////////////////////// INLINE string CollisionHandlerEvent:: -get_out_pattern() const { - return _out_pattern; +get_out_pattern(int n) const { + nassertr(n >= 0 && n < (int)_out_patterns.size(), string()); + return _out_patterns[n]; } - diff --git a/panda/src/collide/collisionHandlerEvent.cxx b/panda/src/collide/collisionHandlerEvent.cxx index fbb94dbaa6..985474c2d2 100644 --- a/panda/src/collide/collisionHandlerEvent.cxx +++ b/panda/src/collide/collisionHandlerEvent.cxx @@ -31,7 +31,7 @@ TypeHandle CollisionHandlerEvent::_type_handle; // Access: Public // Description: The default CollisionHandlerEvent will throw no // events. Its pattern strings must first be set via a -// call to set_in_pattern() and/or set_out_pattern(). +// call to add_in_pattern() and/or add_out_pattern(). //////////////////////////////////////////////////////////////////// CollisionHandlerEvent:: CollisionHandlerEvent() { @@ -109,18 +109,18 @@ end_group() { if (order(*ca, *cb)) { // Here's an element in a but not in b. That's a newly entered // intersection. - throw_event_pattern(_in_pattern, *ca); + throw_event_for(_in_patterns, *ca); ++ca; } else if (order(*cb, *ca)) { // Here's an element in b but not in a. That's a newly exited // intersection. - throw_event_pattern(_out_pattern, *cb); + throw_event_for(_out_patterns, *cb); ++cb; } else { // This element is in both b and a. It hasn't changed. - throw_event_pattern(_again_pattern, *cb); + throw_event_for(_again_patterns, *cb); ++ca; ++cb; } @@ -129,14 +129,14 @@ end_group() { while (ca != _current_colliding.end()) { // Here's an element in a but not in b. That's a newly entered // intersection. - throw_event_pattern(_in_pattern, *ca); + throw_event_for(_in_patterns, *ca); ++ca; } while (cb != _last_colliding.end()) { // Here's an element in b but not in a. That's a newly exited // intersection. - throw_event_pattern(_out_pattern, *cb); + throw_event_for(_out_patterns, *cb); ++cb; } @@ -154,7 +154,7 @@ end_group() { // This can be called each frame to defeat the // persistent "in" event mechanism, which prevents the // same "in" event from being thrown repeatedly. -// However, also see set_again_pattern(), which can be +// However, also see add_again_pattern(), which can be // used to set the event that is thrown when a collision // is detected for two or more consecutive frames. //////////////////////////////////////////////////////////////////// @@ -164,6 +164,20 @@ clear() { _current_colliding.clear(); } +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerEvent::throw_event_for +// Access: Private +// Description: Throws whatever events are suggested by the list of +// patterns. +//////////////////////////////////////////////////////////////////// +void CollisionHandlerEvent:: +throw_event_for(const vector_string &patterns, CollisionEntry *entry) { + vector_string::const_iterator pi; + for (pi = patterns.begin(); pi != patterns.end(); ++pi) { + throw_event_pattern(*pi, entry); + } +} + //////////////////////////////////////////////////////////////////// // Function: CollisionHandlerEvent::throw_event_pattern // Access: Private @@ -213,27 +227,29 @@ throw_event_pattern(const string &pattern, CollisionEntry *entry) { (entry->has_into() ? 'c' : 'g'); } else if (cmd == "fh") { - event += (entry->get_from_node()->has_tag(key) ? '1' : '0'); - - } else if (cmd == "ih") { - if (entry->has_into()) { - event += (entry->get_into_node()->has_tag(key) ? '1' : '0'); + if (!entry->get_from_node()->has_tag(key)) { + return; } - } else if (cmd == "iH") { - if (entry->has_into()) { - event += (entry->get_into_node_path().has_net_tag(key) ? '1' : '0'); + } else if (cmd == "fx") { + if (entry->get_from_node()->has_tag(key)) { + return; + } + + } else if (cmd == "ih") { + if (!(entry->has_into() && entry->get_into_node_path().has_net_tag(key))) { + return; + } + + } else if (cmd == "ix") { + if (entry->has_into() && entry->get_into_node_path().has_net_tag(key)) { + return; } } else if (cmd == "ft") { event += entry->get_from_node()->get_tag(key); } else if (cmd == "it") { - if (entry->has_into()) { - event += entry->get_into_node()->get_tag(key); - } - - } else if (cmd == "iT") { if (entry->has_into()) { event += entry->get_into_node_path().get_net_tag(key); } diff --git a/panda/src/collide/collisionHandlerEvent.h b/panda/src/collide/collisionHandlerEvent.h index bfa0f308a6..a7d3d91f86 100644 --- a/panda/src/collide/collisionHandlerEvent.h +++ b/panda/src/collide/collisionHandlerEvent.h @@ -25,6 +25,7 @@ #include "collisionNode.h" #include "collisionEntry.h" +#include "vector_string.h" #include "pointerTo.h" /////////////////////////////////////////////////////////////////// @@ -46,21 +47,33 @@ public: virtual bool end_group(); PUBLISHED: - INLINE void set_in_pattern(const string &pattern); - INLINE string get_in_pattern() const; - INLINE void set_again_pattern(const string &pattern); - INLINE string get_again_pattern() const; - INLINE void set_out_pattern(const string &pattern); - INLINE string get_out_pattern() const; + INLINE void clear_in_patterns(); + INLINE void add_in_pattern(const string &in_pattern); + INLINE void set_in_pattern(const string &in_pattern); + INLINE int get_num_in_patterns() const; + INLINE string get_in_pattern(int n) const; + + INLINE void clear_again_patterns(); + INLINE void add_again_pattern(const string &again_pattern); + INLINE void set_again_pattern(const string &again_pattern); + INLINE int get_num_again_patterns() const; + INLINE string get_again_pattern(int n) const; + + INLINE void clear_out_patterns(); + INLINE void add_out_pattern(const string &out_pattern); + INLINE void set_out_pattern(const string &out_pattern); + INLINE int get_num_out_patterns() const; + INLINE string get_out_pattern(int n) const; void clear(); private: + void throw_event_for(const vector_string &patterns, CollisionEntry *entry); void throw_event_pattern(const string &pattern, CollisionEntry *entry); - string _in_pattern; - string _again_pattern; - string _out_pattern; + vector_string _in_patterns; + vector_string _again_patterns; + vector_string _out_patterns; int _index;