All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pathNode.h
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_USD_SDF_PATH_NODE_H
25 #define PXR_USD_SDF_PATH_NODE_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/sdf/api.h"
29 #include "pxr/base/tf/token.h"
30 #include "pxr/base/tf/mallocTag.h"
31 
32 #include <boost/noncopyable.hpp>
33 #include <boost/intrusive_ptr.hpp>
34 
35 #include <tbb/atomic.h>
36 
37 PXR_NAMESPACE_OPEN_SCOPE
38 
39 // Sdf_PathNode
40 //
41 // This class is the root of the path node hierarchy. It used to use ordinary
42 // C++ polymorphism, but it no longer does. This is primarily a space
43 // optimization: the set of node types is fixed, we already have an enum 'type'
44 // field, and we typically have lots (e.g. ~1e8) of these objects. Dropping the
45 // C++ polymorphism saves us the vtable pointer, and we can pack the '_nodeType'
46 // field in a much smaller space with other flags.
47 //
48 // We currently store PathNode objects in two prefix trees. The "prim like"
49 // path nodes (the root nodes '/' and '.', prim path nodes, and prim variant
50 // selection nodes are in one prefix tree, and the "property like" nodes are in
51 // another prefix tree (prim property nodes, target nodes, expression nodes,
52 // mapper arg nodes). We do this because there are far fewer unique property
53 // nodes (generally) than there are prim nodes. We allocate these in Sdf_Pools,
54 // so that the SdfPath class can store a handle to an element in each tree in 64
55 // bits total. (Sdf_Pool is designed so that we can refer to objects in memory
56 // using 32-bit indexes instead of 64-bit pointers). An SdfPath joins together
57 // these two elements to form a whole path. For example, the path
58 // '/Foo/Bar.attr' would store a prim-part handle to the '/Foo/Bar' node, and a
59 // property-part handle to 'attr'.
60 //
61 class Sdf_PathNode {
62  Sdf_PathNode(Sdf_PathNode const &) = delete;
63  Sdf_PathNode &operator=(Sdf_PathNode const &) = delete;
64 public:
65  // Node types identify what kind of path node a given instance is.
66  // There are restrictions on what type of children each node type
67  // can have,
68  enum NodeType {
69 
70  /********************************************************/
71  /******************************* Prim portion nodes *****/
72 
73  RootNode,
74  // Allowable child node types:
75  // PrimNode
76  // PrimPropertyNode (only for relative root)
77  // PrimVariantSelectionNode (only for relative root)
78 
79  PrimNode,
80  // Allowable child node types:
81  // PrimNode
82  // PrimPropertyNode
83  // PrimVariantSelectionNode
84 
85  PrimVariantSelectionNode,
86  // Allowable child node types:
87  // PrimNode
88  // PrimPropertyNode
89  // PrimVariantSelectionNode
90  // (for variants that contain variant sets)
91 
92  /********************************************************/
93  /******************************* Property portion nodes */
94 
95  PrimPropertyNode,
96  // Allowable child node types:
97  // TargetNode
98  // MapperNode
99  // ExpressionNode
100 
101  TargetNode,
102  // Allowable child node types:
103  // RelationalAttributeNode (only if parent is PrimPropertyNode)
104 
105  MapperNode,
106  // Allowable child node types:
107  // MapperArgNode
108 
109  RelationalAttributeNode,
110  // Allowable child node types:
111  // TargetNode
112  // MapperNode
113  // ExpressionNode
114 
115  MapperArgNode,
116  // Allowable child node types:
117  // <none>
118 
119  ExpressionNode,
120  // Allowable child node types:
121  // <none>
122 
123  NumNodeTypes
124  };
125 
126  static Sdf_PathPrimNodeHandle
127  FindOrCreatePrim(Sdf_PathNode const *parent, const TfToken &name);
128 
129  static Sdf_PathPropNodeHandle
130  FindOrCreatePrimProperty(Sdf_PathNode const *parent, const TfToken &name);
131 
132  static Sdf_PathPrimNodeHandle
133  FindOrCreatePrimVariantSelection(Sdf_PathNode const *parent,
134  const TfToken &variantSet,
135  const TfToken &variant);
136 
137  static Sdf_PathPropNodeHandle
138  FindOrCreateTarget(Sdf_PathNode const *parent,
139  SdfPath const &targetPath);
140 
141  static Sdf_PathPropNodeHandle
142  FindOrCreateRelationalAttribute(Sdf_PathNode const *parent,
143  const TfToken &name);
144 
145  static Sdf_PathPropNodeHandle
146  FindOrCreateMapper(Sdf_PathNode const *parent, SdfPath const &targetPath);
147 
148  static Sdf_PathPropNodeHandle
149  FindOrCreateMapperArg(Sdf_PathNode const *parent, const TfToken &name);
150 
151  static Sdf_PathPropNodeHandle
152  FindOrCreateExpression(Sdf_PathNode const *parent);
153 
154  static Sdf_PathNode const *GetAbsoluteRootNode();
155  static Sdf_PathNode const *GetRelativeRootNode();
156 
157  NodeType GetNodeType() const { return NodeType(_nodeType); }
158 
159  static std::pair<Sdf_PathNode const *, Sdf_PathNode const *>
160  RemoveCommonSuffix(Sdf_PathNode const *a,
161  Sdf_PathNode const *b,
162  bool stopAtRootPrim);
163 
164  // This method returns a node pointer
165  Sdf_PathNode const *GetParentNode() const { return _parent.get(); }
166 
167  size_t GetElementCount() const { return size_t(_elementCount); }
168  bool IsAbsolutePath() const { return _isAbsolute; }
169  bool IsAbsoluteRoot() const { return (_isAbsolute) & (!_elementCount); }
170  bool ContainsTargetPath() const { return _containsTargetPath; }
171  bool IsNamespaced() const {
172  return (_nodeType == PrimPropertyNode ||
173  _nodeType == RelationalAttributeNode) && _IsNamespacedImpl();
174  }
175 
176  bool ContainsPrimVariantSelection() const {
177  return _containsPrimVariantSelection;
178  }
179 
180  // For PrimNode, PrimPropertyNode, RelationalAttributeNode, and
181  // MapperArgNode this is the name (with no "dot" for
182  // properties/relational attributes/mapper args). For others, it
183  // is EmptyToken.
184  inline const TfToken &GetName() const;
185 
186  // For TargetNode and MapperNode this is the target path.
187  // For others, it is InvalidPath.
188  inline const SdfPath &GetTargetPath() const;
189 
190  typedef std::pair<TfToken, TfToken> VariantSelectionType;
191  inline const VariantSelectionType& GetVariantSelection() const;
192 
193  // Returns the path element string (".name" for properties, "[path]" for
194  // targets, etc...)
195  inline TfToken GetElement() const;
196 
197  // Append this element's text (same as GetElement()) to \p str.
198  void AppendText(std::string *str) const;
199 
200  // Return the stringified path to this node as a TfToken lvalue.
201  SDF_API static const TfToken &
202  GetPathToken(Sdf_PathNode const *primPart, Sdf_PathNode const *propPart);
203 
204  // Return the stringified path to this node as a TfToken rvalue.
205  SDF_API static TfToken
206  GetPathAsToken(Sdf_PathNode const *primPart, Sdf_PathNode const *propPart);
207 
208  // Lexicographic ordering for Compare().
209  struct LessThan {
210  template <class T>
211  inline bool operator()(T const &a, T const &b) const {
212  return a < b;
213  }
214  };
215 
216  // This operator only works properly when the rhs has the same parent
217  // as this node.
218  template <class Less>
219  inline bool Compare(const Sdf_PathNode &rhs) const;
220 
221  // Return the current ref-count.
222  // Meant for diagnostic use.
223  unsigned int GetCurrentRefCount() const { return _refCount; }
224 
225 protected:
226  Sdf_PathNode(Sdf_PathNode const *parent, NodeType nodeType)
227  : _parent(parent)
228  , _refCount(1)
229  , _elementCount(parent ? parent->_elementCount + 1 : 1)
230  , _nodeType(nodeType)
231  , _isAbsolute(parent && parent->IsAbsolutePath())
232  , _containsPrimVariantSelection(
233  nodeType == PrimVariantSelectionNode ||
234  (parent && parent->_containsPrimVariantSelection))
235  , _containsTargetPath(nodeType == TargetNode ||
236  nodeType == MapperNode ||
237  (parent && parent->_containsTargetPath))
238  , _hasToken(false)
239  {}
240 
241  // This constructor is used only to create the two special root nodes.
242  explicit Sdf_PathNode(bool isAbsolute);
243 
244  ~Sdf_PathNode() {
245  if (_hasToken)
246  _RemovePathTokenFromTable();
247  }
248 
249  // Helper to downcast and destroy the dynamic type of this object -- this is
250  // required since this class hierarchy doesn't use normal C++ polymorphism
251  // for space reasons.
252  inline void _Destroy() const;
253 
254  // // Helper function for GetPathToken, which lazily creates its token
255  static TfToken _CreatePathToken(Sdf_PathNode const *primPart,
256  Sdf_PathNode const *propPart);
257 
258  // Helper for dtor, removes this path node's token from the token table.
259  SDF_API void _RemovePathTokenFromTable() const;
260 
261  struct _EqualElement {
262  template <class T>
263  inline bool operator()(T const &a, T const &b) const {
264  return a == b;
265  }
266  };
267 
268  friend struct Sdf_PathNodePrivateAccess;
269 
270  // Ref-counting ops manage _refCount.
271  friend void intrusive_ptr_add_ref(const Sdf_PathNode*);
272  friend void intrusive_ptr_release(const Sdf_PathNode*);
273 
274 private:
275  // Downcast helper, just sugar to static_cast this to Derived const *.
276  template <class Derived>
277  Derived const *_Downcast() const {
278  return static_cast<Derived const *>(this);
279  }
280 
281  // Helper to scan this node's name for the property namespace delimiter.
282  bool _IsNamespacedImpl() const;
283 
284  // Helper to return a const lvalue variant selection.
285  VariantSelectionType const &_GetEmptyVariantSelection() const;
286 
287  // Instance variables. PathNode's size is important to keep small. Please
288  // be mindful of that when making any changes here.
289  const Sdf_PathNodeConstRefPtr _parent;
290  mutable tbb::atomic<unsigned int> _refCount;
291 
292  const short _elementCount;
293  const unsigned char _nodeType;
294  const bool _isAbsolute:1;
295  const bool _containsPrimVariantSelection:1;
296  const bool _containsTargetPath:1;
297 
298  // This is racy -- we ensure that the token creation code carefully
299  // synchronizes so that if we read 'true' from this flag, it guarantees that
300  // there's a token for this path node in the token table. If we read
301  // 'false' it means there may or may not be, unless we're in the destructor,
302  // which must run exclusively, then reading 'false' guarantees there is no
303  // token in the table. We use this flag to do that optimization in the
304  // destructor so we can avoid looking in the table in the case where we
305  // haven't created a token.
306  mutable bool _hasToken:1;
307 };
308 
309 class Sdf_PrimPartPathNode : public Sdf_PathNode {
310 public:
311  using Sdf_PathNode::Sdf_PathNode;
312  SDF_API void operator delete (void *p);
313 };
314 
315 class Sdf_PropPartPathNode : public Sdf_PathNode {
316 public:
317  using Sdf_PathNode::Sdf_PathNode;
318  SDF_API void operator delete (void *p);
319 };
320 
321 class Sdf_RootPathNode : public Sdf_PrimPartPathNode {
322 public:
323  typedef bool ComparisonType;
324  static const NodeType nodeType = Sdf_PathNode::RootNode;
325 
326  static SDF_API Sdf_PathNode const *New(bool isAbsolute);
327 
328 private:
329  // This constructor is used only to create the two special root nodes.
330  Sdf_RootPathNode(bool isAbsolute) : Sdf_PrimPartPathNode(isAbsolute) {}
331 
332  ComparisonType _GetComparisonValue() const {
333  // Root nodes, there are only two, one absolute and one relative.
334  // (absolute < relative...)
335  return !IsAbsolutePath();
336  }
337 
338  friend class Sdf_PathNode;
339  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
340 };
341 
342 class Sdf_PrimPathNode : public Sdf_PrimPartPathNode {
343 public:
344  typedef TfToken ComparisonType;
345  static const NodeType nodeType = Sdf_PathNode::PrimNode;
346 
347 private:
348  Sdf_PrimPathNode(Sdf_PathNode const *parent,
349  const TfToken &name)
350  : Sdf_PrimPartPathNode(parent, nodeType)
351  , _name(name) {}
352 
353  SDF_API ~Sdf_PrimPathNode();
354 
355  const ComparisonType &_GetComparisonValue() const { return _name; }
356 
357  friend class Sdf_PathNode;
358  friend struct Sdf_PathNodePrivateAccess;
359  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
360 
361  // Instance variables
362  TfToken _name;
363 };
364 
365 class Sdf_PrimPropertyPathNode : public Sdf_PropPartPathNode {
366 public:
367  typedef TfToken ComparisonType;
368  static const NodeType nodeType = Sdf_PathNode::PrimPropertyNode;
369 
370 private:
371  Sdf_PrimPropertyPathNode(Sdf_PathNode const *parent,
372  const TfToken &name)
373  : Sdf_PropPartPathNode(parent, nodeType)
374  , _name(name) {}
375 
376  SDF_API ~Sdf_PrimPropertyPathNode();
377 
378  friend class Sdf_PathNode;
379  friend struct Sdf_PathNodePrivateAccess;
380  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
381 
382  const ComparisonType &_GetComparisonValue() const { return _name; }
383 
384  // Instance variables
385  TfToken _name;
386 };
387 
388 class Sdf_PrimVariantSelectionNode : public Sdf_PrimPartPathNode {
389 public:
390  typedef VariantSelectionType ComparisonType;
391  static const NodeType nodeType = Sdf_PathNode::PrimVariantSelectionNode;
392 
393  const TfToken &_GetNameImpl() const;
394  void _AppendText(std::string *str) const;
395 
396 private:
397  Sdf_PrimVariantSelectionNode(Sdf_PathNode const *parent,
398  const VariantSelectionType &variantSelection)
399  : Sdf_PrimPartPathNode(parent, nodeType)
400  , _variantSelection(new VariantSelectionType(variantSelection)) {}
401 
402  SDF_API ~Sdf_PrimVariantSelectionNode();
403 
404  const ComparisonType &_GetComparisonValue() const {
405  return *_variantSelection;
406  }
407 
408  friend class Sdf_PathNode;
409  friend struct Sdf_PathNodePrivateAccess;
410  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
411 
412  // Instance variables
413  std::unique_ptr<VariantSelectionType> _variantSelection;
414 };
415 
416 class Sdf_TargetPathNode : public Sdf_PropPartPathNode {
417 public:
418  typedef SdfPath ComparisonType;
419  static const NodeType nodeType = Sdf_PathNode::TargetNode;
420 
421  void _AppendText(std::string *str) const;
422 
423 private:
424  Sdf_TargetPathNode(Sdf_PathNode const *parent,
425  const SdfPath &targetPath)
426  : Sdf_PropPartPathNode(parent, nodeType)
427  , _targetPath(targetPath) {}
428 
429  SDF_API ~Sdf_TargetPathNode();
430 
431  const ComparisonType& _GetComparisonValue() const { return _targetPath; }
432 
433  friend class Sdf_PathNode;
434  friend struct Sdf_PathNodePrivateAccess;
435  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
436 
437  // Instance variables
438  SdfPath _targetPath;
439 };
440 
441 class Sdf_RelationalAttributePathNode : public Sdf_PropPartPathNode {
442 public:
443  typedef TfToken ComparisonType;
444  static const NodeType nodeType = Sdf_PathNode::RelationalAttributeNode;
445 
446 private:
447  Sdf_RelationalAttributePathNode(Sdf_PathNode const *parent,
448  const TfToken &name)
449  : Sdf_PropPartPathNode(parent, nodeType)
450  , _name(name) {}
451 
452  SDF_API ~Sdf_RelationalAttributePathNode();
453 
454  const ComparisonType& _GetComparisonValue() const { return _name; }
455 
456  friend class Sdf_PathNode;
457  friend struct Sdf_PathNodePrivateAccess;
458  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
459 
460  // Instance variables
461  TfToken _name;
462 };
463 
464 class Sdf_MapperPathNode : public Sdf_PropPartPathNode {
465 public:
466  typedef SdfPath ComparisonType;
467  static const NodeType nodeType = Sdf_PathNode::MapperNode;
468 
469  void _AppendText(std::string *str) const;
470 
471 private:
472  Sdf_MapperPathNode(Sdf_PathNode const *parent,
473  const SdfPath &targetPath)
474  : Sdf_PropPartPathNode(parent, nodeType)
475  , _targetPath(targetPath) {}
476 
477  SDF_API ~Sdf_MapperPathNode();
478 
479  const ComparisonType& _GetComparisonValue() const { return _targetPath; }
480 
481  friend class Sdf_PathNode;
482  friend struct Sdf_PathNodePrivateAccess;
483  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
484 
485  // Instance variables
486  SdfPath _targetPath;
487 };
488 
489 class Sdf_MapperArgPathNode : public Sdf_PropPartPathNode {
490 public:
491  typedef TfToken ComparisonType;
492  static const NodeType nodeType = Sdf_PathNode::MapperArgNode;
493 
494  void _AppendText(std::string *str) const;
495 
496 private:
497  Sdf_MapperArgPathNode(Sdf_PathNode const *parent,
498  const TfToken &name)
499  : Sdf_PropPartPathNode(parent, nodeType)
500  , _name(name) {}
501 
502  SDF_API ~Sdf_MapperArgPathNode();
503 
504  const ComparisonType& _GetComparisonValue() const { return _name; }
505 
506  friend class Sdf_PathNode;
507  friend struct Sdf_PathNodePrivateAccess;
508  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
509 
510  // Instance variables
511  TfToken _name;
512 };
513 
514 class Sdf_ExpressionPathNode : public Sdf_PropPartPathNode {
515 public:
516  typedef void *ComparisonType;
517  static const NodeType nodeType = Sdf_PathNode::ExpressionNode;
518 
519  void _AppendText(std::string *str) const;
520 
521 private:
522  Sdf_ExpressionPathNode(Sdf_PathNode const *parent)
523  : Sdf_PropPartPathNode(parent, nodeType) {}
524 
525  SDF_API ~Sdf_ExpressionPathNode();
526 
527  ComparisonType _GetComparisonValue() const { return nullptr; }
528 
529  friend class Sdf_PathNode;
530  friend struct Sdf_PathNodePrivateAccess;
531  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
532 
533  // Instance variables
534  // <none>
535 };
536 
537 template <int nodeType>
538 struct Sdf_PathNodeTypeToType {
539 };
540 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::PrimNode> {
541  typedef Sdf_PrimPathNode Type;
542 };
543 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::PrimPropertyNode> {
544  typedef Sdf_PrimPropertyPathNode Type;
545 };
546 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::RelationalAttributeNode> {
547  typedef Sdf_RelationalAttributePathNode Type;
548 };
549 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::MapperArgNode> {
550  typedef Sdf_MapperArgPathNode Type;
551 };
552 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::TargetNode> {
553  typedef Sdf_TargetPathNode Type;
554 };
555 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::MapperNode> {
556  typedef Sdf_MapperPathNode Type;
557 };
558 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::PrimVariantSelectionNode> {
559  typedef Sdf_PrimVariantSelectionNode Type;
560 };
561 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::ExpressionNode> {
562  typedef Sdf_ExpressionPathNode Type;
563 };
564 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::RootNode> {
565  typedef Sdf_RootPathNode Type;
566 };
567 
568 template <int nodeType, class Comp>
569 struct Sdf_PathNodeCompare {
570  inline bool operator()(const Sdf_PathNode &lhs,
571  const Sdf_PathNode &rhs) const {
572  typedef typename Sdf_PathNodeTypeToType<nodeType>::Type Type;
573  return Comp()(static_cast<const Type&>(lhs)._GetComparisonValue(),
574  static_cast<const Type&>(rhs)._GetComparisonValue());
575  }
576 };
577 
578 template <class Comp>
579 inline bool
580 Sdf_PathNode::Compare(const Sdf_PathNode &rhs) const
581 {
582  // Compare two nodes.
583  // We first compare types, then, if types match, we compare
584  // based on the type-specific content.
585  // Names are compared lexicographically.
586 
587  // Compare types. If node types are different use Comp() on them, otherwise
588  // continue to node-specific comparisons.
589 
590  NodeType nodeType = GetNodeType(), rhsNodeType = rhs.GetNodeType();
591  if (nodeType != rhsNodeType) {
592  return Comp()(nodeType, rhsNodeType);
593  }
594 
595  // Types are the same. Avoid virtual function calls for performance.
596  switch (nodeType) {
597  case Sdf_PathNode::PrimNode:
598  return Sdf_PathNodeCompare<Sdf_PathNode::PrimNode,
599  Comp>()(*this, rhs);
600  case Sdf_PathNode::PrimPropertyNode:
601  return Sdf_PathNodeCompare<Sdf_PathNode::PrimPropertyNode,
602  Comp>()(*this, rhs);
603  case Sdf_PathNode::RelationalAttributeNode:
604  return Sdf_PathNodeCompare<Sdf_PathNode::RelationalAttributeNode,
605  Comp>()(*this, rhs);
606  case Sdf_PathNode::MapperArgNode:
607  return Sdf_PathNodeCompare<Sdf_PathNode::MapperArgNode,
608  Comp>()(*this, rhs);
609  case Sdf_PathNode::TargetNode:
610  return Sdf_PathNodeCompare<Sdf_PathNode::TargetNode,
611  Comp>()(*this, rhs);
612  case Sdf_PathNode::MapperNode:
613  return Sdf_PathNodeCompare<Sdf_PathNode::MapperNode,
614  Comp>()(*this, rhs);
615  case Sdf_PathNode::PrimVariantSelectionNode:
616  return Sdf_PathNodeCompare<Sdf_PathNode::PrimVariantSelectionNode,
617  Comp>()(*this, rhs);
618  case Sdf_PathNode::ExpressionNode:
619  return Sdf_PathNodeCompare<Sdf_PathNode::ExpressionNode,
620  Comp>()(*this, rhs);
621  case Sdf_PathNode::RootNode:
622  return Sdf_PathNodeCompare<Sdf_PathNode::RootNode,
623  Comp>()(*this, rhs);
624  default:
625  TF_CODING_ERROR("Unhandled Sdf_PathNode::NodeType enumerant");
626  return false;
627  }
628 }
629 
630 inline void
631 Sdf_PathNode::_Destroy() const
632 {
633  // Note: This function deletes this object!
634  switch (_nodeType) {
635  case RootNode:
636  return delete _Downcast<Sdf_RootPathNode>();
637  case PrimNode:
638  return delete _Downcast<Sdf_PrimPathNode>();
639  case PrimPropertyNode:
640  return delete _Downcast<Sdf_PrimPropertyPathNode>();
641  case PrimVariantSelectionNode:
642  return delete _Downcast<Sdf_PrimVariantSelectionNode>();
643  case TargetNode:
644  return delete _Downcast<Sdf_TargetPathNode>();
645  case RelationalAttributeNode:
646  return delete _Downcast<Sdf_RelationalAttributePathNode>();
647  case MapperNode:
648  return delete _Downcast<Sdf_MapperPathNode>();
649  case MapperArgNode:
650  return delete _Downcast<Sdf_MapperArgPathNode>();
651  case ExpressionNode:
652  return delete _Downcast<Sdf_ExpressionPathNode>();
653  default:
654  return;
655  };
656 }
657 
658 inline const TfToken &
659 Sdf_PathNode::GetName() const
660 {
661  switch (_nodeType) {
662  default:
663  return SdfPathTokens->empty;
664  case RootNode:
665  return IsAbsolutePath() ?
666  SdfPathTokens->absoluteIndicator : SdfPathTokens->relativeRoot;
667  case PrimNode:
668  return _Downcast<Sdf_PrimPathNode>()->_name;
669  case PrimPropertyNode:
670  return _Downcast<Sdf_PrimPropertyPathNode>()->_name;
671  case PrimVariantSelectionNode:
672  return _Downcast<Sdf_PrimVariantSelectionNode>()->_GetNameImpl();
673  case RelationalAttributeNode:
674  return _Downcast<Sdf_RelationalAttributePathNode>()->_name;
675  case MapperArgNode:
676  return _Downcast<Sdf_MapperArgPathNode>()->_name;
677  case ExpressionNode:
678  return SdfPathTokens->expressionIndicator;
679  }
680 }
681 
682 inline const SdfPath &
683 Sdf_PathNode::GetTargetPath() const
684 {
685  switch (_nodeType) {
686  default:
687  return SdfPath::EmptyPath();
688  case TargetNode:
689  return _Downcast<Sdf_TargetPathNode>()->_targetPath;
690  case MapperNode:
691  return _Downcast<Sdf_MapperPathNode>()->_targetPath;
692  };
693 }
694 
695 inline const Sdf_PathNode::VariantSelectionType &
696 Sdf_PathNode::GetVariantSelection() const
697 {
698  if (ARCH_LIKELY(_nodeType == PrimVariantSelectionNode)) {
699  return *_Downcast<Sdf_PrimVariantSelectionNode>()->_variantSelection;
700  }
701  return _GetEmptyVariantSelection();
702 }
703 
704 inline TfToken
705 Sdf_PathNode::GetElement() const
706 {
707  switch (_nodeType) {
708  case RootNode:
709  return TfToken();
710  case PrimNode:
711  return _Downcast<Sdf_PrimPathNode>()->_name;
712  default:
713  std::string str;
714  AppendText(&str);
715  return TfToken(str);
716  };
717 }
718 
720 SDF_API void Sdf_DumpPathStats();
721 
722 inline void intrusive_ptr_add_ref(const PXR_NS::Sdf_PathNode* p) {
723  ++p->_refCount;
724 }
725 inline void intrusive_ptr_release(const PXR_NS::Sdf_PathNode* p) {
726  if (p->_refCount.fetch_and_decrement() == 1)
727  p->_Destroy();
728 }
729 
730 PXR_NAMESPACE_CLOSE_SCOPE
731 
732 #endif // PXR_USD_SDF_PATH_NODE_H
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:85
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:87
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:288
static SDF_API const SdfPath & EmptyPath()
The empty path value, equivalent to SdfPath().
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...