Ver código fonte

support find() for tags

David Rose 22 anos atrás
pai
commit
c04a6237ec

+ 35 - 0
panda/src/pgraph/findApproxPath.I

@@ -55,6 +55,7 @@ add_match_name_glob(const string &name, int flags) {
   Component comp;
   Component comp;
   comp._type = CT_match_name_glob;
   comp._type = CT_match_name_glob;
   comp._name = name;
   comp._name = name;
+  comp._glob.set_pattern(name);
   comp._flags = flags;
   comp._flags = flags;
   _path.push_back(comp);
   _path.push_back(comp);
 }
 }
@@ -89,6 +90,40 @@ add_match_inexact_type(TypeHandle type, int flags) {
   _path.push_back(comp);
   _path.push_back(comp);
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: FindApproxPath::add_match_tag
+//       Access: Public
+//  Description: Adds a component that will match a node that has a
+//               tag with the indicated key, no matter what the value
+//               is.
+////////////////////////////////////////////////////////////////////
+INLINE void FindApproxPath::
+add_match_tag(const string &name, int flags) {
+  Component comp;
+  comp._type = CT_match_tag;
+  comp._name = name;
+  comp._flags = flags;
+  _path.push_back(comp);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FindApproxPath::add_match_tag_value
+//       Access: Public
+//  Description: Adds a component that will match a node that has a
+//               tag with the indicated key.  The value may be "*" to
+//               match any value, or a particular glob pattern to
+//               match only those nodes with the indicated value.
+////////////////////////////////////////////////////////////////////
+INLINE void FindApproxPath::
+add_match_tag_value(const string &name, const string &value, int flags) {
+  Component comp;
+  comp._type = CT_match_tag_value;
+  comp._name = name;
+  comp._glob.set_pattern(value);
+  comp._flags = flags;
+  _path.push_back(comp);
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: FindApproxPath::add_match_one
 //     Function: FindApproxPath::add_match_one
 //       Access: Public
 //       Access: Public

+ 50 - 22
panda/src/pgraph/findApproxPath.cxx

@@ -19,7 +19,6 @@
 #include "findApproxPath.h"
 #include "findApproxPath.h"
 #include "config_pgraph.h"
 #include "config_pgraph.h"
 
 
-#include "globPattern.h"
 #include "pandaNode.h"
 #include "pandaNode.h"
 
 
 
 
@@ -40,10 +39,7 @@ matches(PandaNode *node) const {
 
 
   case CT_match_name_glob:
   case CT_match_name_glob:
     // Match the node's name according to filename globbing rules.
     // Match the node's name according to filename globbing rules.
-    {
-      GlobPattern pattern(_name);
-      return (pattern.matches(node->get_name()));
-    }
+    return (_glob.matches(node->get_name()));
 
 
   case CT_match_exact_type:
   case CT_match_exact_type:
     // Match the node's type exactly.
     // Match the node's type exactly.
@@ -54,6 +50,17 @@ matches(PandaNode *node) const {
     // is the type, or is derived from the type.
     // is the type, or is derived from the type.
     return (node->is_of_type(_type_handle));
     return (node->is_of_type(_type_handle));
 
 
+  case CT_match_tag:
+    // Match the node's tag only.
+    return (node->has_tag(_name));
+
+  case CT_match_tag_value:
+    // Match the node's tag and value.
+    if (node->has_tag(_name)) {
+      return _glob.matches(node->get_tag(_name));
+    }
+    return false;
+
   case CT_match_one:
   case CT_match_one:
   case CT_match_many:
   case CT_match_many:
     // Match any node.
     // Match any node.
@@ -77,14 +84,28 @@ matches(PandaNode *node) const {
 void FindApproxPath::Component::
 void FindApproxPath::Component::
 output(ostream &out) const {
 output(ostream &out) const {
   out << _type;
   out << _type;
-  if (_type == CT_match_name || _type == CT_match_name_glob) {
+  switch (_type) {
+  case CT_match_name:
+  case CT_match_name_glob:
+  case CT_match_tag:
     out << " \"" << _name << "\"";
     out << " \"" << _name << "\"";
+    break;
+
+  case CT_match_tag_value:
+    out << " \"" << _name << "\"=\"" << _glob << "\"";
+    break;
 
 
-  } else if (_type == CT_match_exact_type || _type == CT_match_inexact_type) {
+  case CT_match_exact_type:
+  case CT_match_inexact_type:
     out << " " << _type_handle;
     out << " " << _type_handle;
+    break;
 
 
-  } else if (_type == CT_match_pointer) {
+  case CT_match_pointer:
     out << " (" << *_pointer << ")";
     out << " (" << *_pointer << ")";
+    break;
+
+  default:
+    break;
   }
   }
 }
 }
 
 
@@ -213,13 +234,7 @@ add_component(string str_component) {
 
 
   } else if (!str_component.empty() && str_component[0] == '-') {
   } else if (!str_component.empty() && str_component[0] == '-') {
     string type_name = str_component.substr(1);
     string type_name = str_component.substr(1);
-
-    // *** for now, as a quick hack, if a type exists with the ""
-    // prefix on the named type, we search for that type instead.
-    TypeHandle handle = TypeRegistry::ptr()->find_type("" + type_name);
-    if (handle == TypeHandle::none()) {
-      handle = TypeRegistry::ptr()->find_type(type_name);
-    }
+    TypeHandle handle = TypeRegistry::ptr()->find_type(type_name);
 
 
     if (handle == TypeHandle::none()) {
     if (handle == TypeHandle::none()) {
       pgraph_cat.error()
       pgraph_cat.error()
@@ -232,13 +247,7 @@ add_component(string str_component) {
 
 
   } else if (!str_component.empty() && str_component[0] == '+') {
   } else if (!str_component.empty() && str_component[0] == '+') {
     string type_name = str_component.substr(1);
     string type_name = str_component.substr(1);
-
-    // *** for now, as a quick hack, if a type exists with the ""
-    // prefix on the named type, we search for that type instead.
-    TypeHandle handle = TypeRegistry::ptr()->find_type("" + type_name);
-    if (handle == TypeHandle::none()) {
-      handle = TypeRegistry::ptr()->find_type(type_name);
-    }
+    TypeHandle handle = TypeRegistry::ptr()->find_type(type_name);
 
 
     if (handle == TypeHandle::none()) {
     if (handle == TypeHandle::none()) {
       pgraph_cat.error()
       pgraph_cat.error()
@@ -249,6 +258,19 @@ add_component(string str_component) {
       add_match_inexact_type(handle, flags);
       add_match_inexact_type(handle, flags);
     }
     }
 
 
+  } else if (!str_component.empty() && str_component[0] == '=') {
+    size_t equals = str_component.find('=', 1);
+    if (equals != string::npos) {
+      // =key=value
+      string tag_key = str_component.substr(1, equals - 1);
+      string tag_value = str_component.substr(equals + 1);
+      add_match_tag_value(tag_key, tag_value, flags);
+    } else {
+      // =key
+      string tag_key = str_component.substr(1);
+      add_match_tag(tag_key, flags);
+    }
+
   } else {
   } else {
     add_match_name_glob(str_component, flags);
     add_match_name_glob(str_component, flags);
   }
   }
@@ -291,6 +313,12 @@ operator << (ostream &out, FindApproxPath::ComponentType type) {
   case FindApproxPath::CT_match_inexact_type:
   case FindApproxPath::CT_match_inexact_type:
     return out << "match_inexact_type";
     return out << "match_inexact_type";
 
 
+  case FindApproxPath::CT_match_tag:
+    return out << "match_tag";
+
+  case FindApproxPath::CT_match_tag_value:
+    return out << "match_tag_value";
+
   case FindApproxPath::CT_match_one:
   case FindApproxPath::CT_match_one:
     return out << "match_one";
     return out << "match_one";
 
 

+ 6 - 0
panda/src/pgraph/findApproxPath.h

@@ -21,6 +21,7 @@
 
 
 #include "pandabase.h"
 #include "pandabase.h"
 
 
+#include "globPattern.h"
 #include "typeHandle.h"
 #include "typeHandle.h"
 #include "pvector.h"
 #include "pvector.h"
 
 
@@ -45,6 +46,8 @@ public:
   INLINE void add_match_name_glob(const string &glob, int flags);
   INLINE void add_match_name_glob(const string &glob, int flags);
   INLINE void add_match_exact_type(TypeHandle type, int flags);
   INLINE void add_match_exact_type(TypeHandle type, int flags);
   INLINE void add_match_inexact_type(TypeHandle type, int flags);
   INLINE void add_match_inexact_type(TypeHandle type, int flags);
+  INLINE void add_match_tag(const string &key, int flags);
+  INLINE void add_match_tag_value(const string &key, const string &value, int flags);
   INLINE void add_match_one(int flags);
   INLINE void add_match_one(int flags);
   INLINE void add_match_many(int flags);
   INLINE void add_match_many(int flags);
   INLINE void add_match_pointer(PandaNode *pointer, int flags);
   INLINE void add_match_pointer(PandaNode *pointer, int flags);
@@ -70,6 +73,8 @@ private:
     CT_match_name_glob,
     CT_match_name_glob,
     CT_match_exact_type,
     CT_match_exact_type,
     CT_match_inexact_type,
     CT_match_inexact_type,
+    CT_match_tag,
+    CT_match_tag_value,
     CT_match_one,
     CT_match_one,
     CT_match_many,
     CT_match_many,
     CT_match_pointer
     CT_match_pointer
@@ -85,6 +90,7 @@ private:
 
 
     ComponentType _type;
     ComponentType _type;
     string _name;
     string _name;
+    GlobPattern _glob;
     TypeHandle _type_handle;
     TypeHandle _type_handle;
     PandaNode *_pointer;
     PandaNode *_pointer;
     int _flags;
     int _flags;

+ 4 - 1
panda/src/pgraph/nodePath.h

@@ -62,12 +62,15 @@ class GlobPattern;
 //   **         -- matches any sequence of zero or more nodes.
 //   **         -- matches any sequence of zero or more nodes.
 //   +typename  -- matches any node that is or derives from the given type.
 //   +typename  -- matches any node that is or derives from the given type.
 //   -typename  -- matches any node that is the given type exactly.
 //   -typename  -- matches any node that is the given type exactly.
+//   =tag       -- matches any node that has the indicated tag.
+//   =tag=value -- matches any node whose tag matches the indicated value.
 //
 //
 // Furthermore, a node name may itself contain standard filename
 // Furthermore, a node name may itself contain standard filename
 // globbing characters, like *, ?, and [a-z], that will be accepted as
 // globbing characters, like *, ?, and [a-z], that will be accepted as
 // a partial match.  (In fact, the '*' special name may be seen as
 // a partial match.  (In fact, the '*' special name may be seen as
 // just a special case of this.)  The globbing characters may not be
 // just a special case of this.)  The globbing characters may not be
-// used with the typename matches.
+// used with the typename matches or with tag matches, but they may
+// be used to match a tag's value in the =tag=value syntax.
 //
 //
 // The special characters "@@", appearing at the beginning of a node
 // The special characters "@@", appearing at the beginning of a node
 // name, indicate a stashed node.  Normally, stashed nodes are not
 // name, indicate a stashed node.  Normally, stashed nodes are not