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