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