27 bool FindApproxPath::Component::
34 return (_name == node->get_name());
36 case CT_match_name_insensitive:
38 return cmp_nocase(_name, node->get_name()) == 0;
40 case CT_match_name_glob:
42 return (_glob.matches(node->get_name()));
44 case CT_match_exact_type:
48 case CT_match_inexact_type:
55 return (node->has_tag(_name));
57 case CT_match_tag_value:
59 if (node->has_tag(_name)) {
60 return _glob.matches(node->get_tag(_name));
69 case CT_match_pointer:
71 return (_pointer == node);
75 <<
"Invalid component in FindApproxPath\n";
82 void FindApproxPath::Component::
83 output(ostream &out)
const {
87 case CT_match_name_insensitive:
88 case CT_match_name_glob:
90 out <<
" \"" << _name <<
"\"";
93 case CT_match_tag_value:
94 out <<
" \"" << _name <<
"\"=\"" << _glob <<
"\"";
97 case CT_match_exact_type:
98 case CT_match_inexact_type:
99 out <<
" " << _type_handle;
102 case CT_match_pointer:
103 out <<
" (" << *_pointer <<
")";
119 vector_string components;
122 size_t slash = str_path.find(
'/');
123 while (slash != string::npos) {
124 components.push_back(str_path.substr(start, slash - start));
126 slash = str_path.find(
'/', start);
129 size_t semicolon = str_path.rfind(
';');
135 if (semicolon < start) {
136 semicolon = string::npos;
139 components.push_back(str_path.substr(start, semicolon - start));
141 if (semicolon != string::npos) {
142 if (!
add_flags(str_path.substr(semicolon + 1))) {
148 vector_string::const_iterator ci;
149 for (ci = components.begin(); ci != components.end(); ++ci) {
165 string::const_iterator pi = str_flags.begin();
166 while (pi != str_flags.end()) {
177 <<
"Invalid control flag string: " << str_flags <<
"\n";
182 if (pi == str_flags.end()) {
184 <<
"Invalid control flag string: " << str_flags <<
"\n";
194 _return_stashed = on;
198 _case_insensitive = on;
203 <<
"Invalid control flag string: " << str_flags <<
"\n";
222 if (str_component.size() >= 2 && str_component.substr(0, 2) ==
"@@") {
224 str_component = str_component.substr(2);
227 if (str_component ==
"*") {
230 }
else if (str_component ==
"**") {
231 if ((flags & CF_stashed) != 0) {
233 <<
"@@** is undefined; use @@*/** or **/@@* instead.\n";
238 }
else if (!str_component.empty() && str_component[0] ==
'-') {
239 string type_name = str_component.substr(1);
242 if (handle == TypeHandle::none()) {
244 <<
"Invalid type name: " << type_name <<
"\n";
251 }
else if (!str_component.empty() && str_component[0] ==
'+') {
252 string type_name = str_component.substr(1);
255 if (handle == TypeHandle::none()) {
257 <<
"Invalid type name: " << type_name <<
"\n";
264 }
else if (!str_component.empty() && str_component[0] ==
'=') {
265 size_t equals = str_component.find(
'=', 1);
266 if (equals != string::npos) {
268 string tag_key = str_component.substr(1, equals - 1);
269 string tag_value = str_component.substr(equals + 1);
273 string tag_key = str_component.substr(1);
290 comp._type = _case_insensitive ? CT_match_name_insensitive : CT_match_name;
293 _path.push_back(comp);
303 comp._type = CT_match_name_glob;
305 comp._glob.set_pattern(name);
306 comp._glob.set_case_sensitive(!_case_insensitive);
308 if (!comp._glob.has_glob_characters()) {
313 _path.push_back(comp);
324 comp._type = CT_match_exact_type;
325 comp._type_handle = type;
327 _path.push_back(comp);
337 comp._type = CT_match_inexact_type;
338 comp._type_handle = type;
340 _path.push_back(comp);
350 comp._type = CT_match_tag;
353 _path.push_back(comp);
364 comp._type = CT_match_tag_value;
366 comp._glob.set_pattern(value);
368 _path.push_back(comp);
377 comp._type = CT_match_one;
379 _path.push_back(comp);
388 comp._type = CT_match_many;
390 _path.push_back(comp);
399 comp._type = CT_match_pointer;
400 comp._pointer = pointer;
402 _path.push_back(comp);
408 void FindApproxPath::
409 output(ostream &out)
const {
411 if (!_path.empty()) {
412 Path::const_iterator pi = _path.begin();
415 while (pi != _path.end()) {
424 operator << (ostream &out, FindApproxPath::ComponentType type) {
426 case FindApproxPath::CT_match_name:
427 return out <<
"match_name";
429 case FindApproxPath::CT_match_name_insensitive:
430 return out <<
"match_name_insensitive";
432 case FindApproxPath::CT_match_name_glob:
433 return out <<
"match_name_glob";
435 case FindApproxPath::CT_match_exact_type:
436 return out <<
"match_exact_type";
438 case FindApproxPath::CT_match_inexact_type:
439 return out <<
"match_inexact_type";
441 case FindApproxPath::CT_match_tag:
442 return out <<
"match_tag";
444 case FindApproxPath::CT_match_tag_value:
445 return out <<
"match_tag_value";
447 case FindApproxPath::CT_match_one:
448 return out <<
"match_one";
450 case FindApproxPath::CT_match_many:
451 return out <<
"match_many";
453 case FindApproxPath::CT_match_pointer:
454 return out <<
"match_pointer";
457 return out <<
"**invalid**";
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_match_pointer(PandaNode *pointer, int flags)
Adds a component that must match a particular node exactly, by pointer.
A basic node of the scene graph or data graph.
bool is_exact_type(TypeHandle handle) const
Returns true if the current object is the indicated type exactly.
void add_match_name_glob(const std::string &glob, int flags)
Adds a component that must match the name of a node using standard shell globbing rules,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool add_flags(const std::string &str_flags)
Adds a sequence of control flags.
bool add_component(std::string str_component)
Adds a single component to the path sequence, defined by a string as might appear between slashes in ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_match_one(int flags)
Adds a component that will match any node (but not a chain of many nodes).
void add_match_inexact_type(TypeHandle type, int flags)
Adds a component that must match the type of a node or be a base class of the node's type.
TypeHandle find_type(const std::string &name) const
Looks for a previously-registered type of the given name.
void add_match_name(const std::string &name, int flags)
Adds a component that must match the name of a node exactly.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_match_exact_type(TypeHandle type, int flags)
Adds a component that must match the type of a node exactly, with no derived types matching.
bool add_string(const std::string &str_path)
Adds a sequence of components separated by slashes, followed optionally by a semicolon and a sequence...
void add_match_many(int flags)
Adds a component that will match a chain of zero or more consecutive nodes.
static TypeRegistry * ptr()
Returns the pointer to the global TypeRegistry object.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
TypeHandle is the identifier used to differentiate C++ class types.
void add_match_tag_value(const std::string &key, const std::string &value, int flags)
Adds a component that will match a node that has a tag with the indicated key.
void add_match_tag(const std::string &key, int flags)
Adds a component that will match a node that has a tag with the indicated key, no matter what the val...