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