24#ifndef PXR_USD_SDF_PATH_NODE_H
25#define PXR_USD_SDF_PATH_NODE_H
28#include "pxr/usd/sdf/api.h"
29#include "pxr/base/tf/delegatedCountPtr.h"
30#include "pxr/base/tf/functionRef.h"
34PXR_NAMESPACE_OPEN_SCOPE
59 Sdf_PathNode(Sdf_PathNode
const &) =
delete;
60 Sdf_PathNode &operator=(Sdf_PathNode
const &) =
delete;
63 static constexpr uint8_t IsAbsoluteFlag = 1 << 0;
64 static constexpr uint8_t ContainsPrimVarSelFlag = 1 << 1;
65 static constexpr uint8_t ContainsTargetPathFlag = 1 << 2;
67 static constexpr uint32_t HasTokenBit = 1u << 31;
68 static constexpr uint32_t RefCountMask = ~HasTokenBit;
73 enum NodeType : uint8_t {
90 PrimVariantSelectionNode,
114 RelationalAttributeNode,
131 static Sdf_PathPrimNodeHandle
132 FindOrCreatePrim(Sdf_PathNode
const *parent,
const TfToken &name,
135 static Sdf_PathPropNodeHandle
136 FindOrCreatePrimProperty(
137 Sdf_PathNode
const *parent,
const TfToken &name,
140 static Sdf_PathPrimNodeHandle
141 FindOrCreatePrimVariantSelection(Sdf_PathNode
const *parent,
146 static Sdf_PathPropNodeHandle
147 FindOrCreateTarget(Sdf_PathNode
const *parent,
151 static Sdf_PathPropNodeHandle
152 FindOrCreateRelationalAttribute(Sdf_PathNode
const *parent,
156 static Sdf_PathPropNodeHandle
157 FindOrCreateMapper(Sdf_PathNode
const *parent,
SdfPath const &targetPath,
160 static Sdf_PathPropNodeHandle
161 FindOrCreateMapperArg(Sdf_PathNode
const *parent,
const TfToken &name,
164 static Sdf_PathPropNodeHandle
165 FindOrCreateExpression(Sdf_PathNode
const *parent,
168 static Sdf_PathNode
const *GetAbsoluteRootNode();
169 static Sdf_PathNode
const *GetRelativeRootNode();
171 NodeType GetNodeType()
const {
return NodeType(_nodeType); }
173 static std::pair<Sdf_PathNode const *, Sdf_PathNode const *>
174 RemoveCommonSuffix(Sdf_PathNode
const *a,
175 Sdf_PathNode
const *b,
176 bool stopAtRootPrim);
179 inline Sdf_PathNode
const *GetParentNode()
const {
return _parent.get(); }
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;
187 bool IsNamespaced()
const {
190 return ((_nodeType == PrimPropertyNode) |
191 (_nodeType == RelationalAttributeNode)) && _IsNamespacedImpl();
194 bool ContainsPrimVariantSelection()
const {
195 return _nodeFlags & ContainsPrimVarSelFlag;
202 inline const TfToken &GetName()
const;
206 inline const SdfPath &GetTargetPath()
const;
208 typedef std::pair<TfToken, TfToken> VariantSelectionType;
209 inline const VariantSelectionType& GetVariantSelection()
const;
213 inline TfToken GetElement()
const;
217 GetPathToken(Sdf_PathNode
const *primPart, Sdf_PathNode
const *propPart);
221 GetPathAsToken(Sdf_PathNode
const *primPart, Sdf_PathNode
const *propPart);
224 GetDebugText(Sdf_PathNode
const *primPart, Sdf_PathNode
const *propPart);
229 inline bool operator()(T
const &a, T
const &b)
const {
236 template <
class Less>
237 inline bool Compare(
const Sdf_PathNode &rhs)
const;
241 uint32_t GetCurrentRefCount()
const {
242 return _refCount.load(std::memory_order_relaxed) & RefCountMask;
246 Sdf_PathNode(Sdf_PathNode
const *parent, NodeType nodeType)
247 : _parent(TfDelegatedCountIncrementTag, parent)
249 , _elementCount(parent ? parent->_elementCount + 1 : 1)
250 , _nodeType(nodeType)
252 (parent ? parent->_nodeFlags : 0) | _NodeTypeToFlags(nodeType))
257 explicit Sdf_PathNode(
bool isAbsolute);
260 if (_refCount.load(std::memory_order_relaxed) & HasTokenBit) {
261 _RemovePathTokenFromTable();
268 inline void _Destroy()
const;
270 TfToken _GetElementImpl()
const;
273 static TfToken _CreatePathToken(Sdf_PathNode
const *primPart,
274 Sdf_PathNode
const *propPart);
276 template <
class Buffer>
277 static void _WriteTextToBuffer(Sdf_PathNode
const *primPart,
278 Sdf_PathNode
const *propPart,
281 template <
class Buffer>
282 static void _WriteTextToBuffer(
SdfPath const &path, Buffer &out);
285 template <
class Buffer>
286 void _WriteText(Buffer &out)
const;
289 SDF_API
void _RemovePathTokenFromTable()
const;
291 struct _EqualElement {
293 inline bool operator()(T
const &a, T
const &b)
const {
298 friend struct Sdf_PathNodePrivateAccess;
301 friend void TfDelegatedCountIncrement(
const Sdf_PathNode*)
noexcept;
302 friend void TfDelegatedCountDecrement(
const Sdf_PathNode*)
noexcept;
305 static constexpr uint8_t _NodeTypeToFlags(NodeType nt) {
306 if (nt == PrimVariantSelectionNode) {
307 return ContainsPrimVarSelFlag;
309 if (nt == TargetNode || nt == MapperNode) {
310 return ContainsTargetPathFlag;
316 template <
class Derived>
317 Derived
const *_Downcast()
const {
318 return static_cast<Derived
const *
>(
this);
322 bool _IsNamespacedImpl()
const;
325 VariantSelectionType
const &_GetEmptyVariantSelection()
const;
333 mutable std::atomic<uint32_t> _refCount;
335 const uint16_t _elementCount;
336 const NodeType _nodeType;
337 const uint8_t _nodeFlags;
341class Sdf_PrimPartPathNode :
public Sdf_PathNode {
343 using Sdf_PathNode::Sdf_PathNode;
344 SDF_API
void operator delete (
void *p);
347class Sdf_PropPartPathNode :
public Sdf_PathNode {
349 using Sdf_PathNode::Sdf_PathNode;
350 SDF_API
void operator delete (
void *p);
353class Sdf_RootPathNode :
public Sdf_PrimPartPathNode {
355 typedef bool ComparisonType;
356 static const NodeType nodeType = Sdf_PathNode::RootNode;
358 static SDF_API Sdf_PathNode
const *New(
bool isAbsolute);
362 Sdf_RootPathNode(
bool isAbsolute) : Sdf_PrimPartPathNode(isAbsolute) {}
364 ComparisonType _GetComparisonValue()
const {
367 return !IsAbsolutePath();
370 friend class Sdf_PathNode;
371 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
374class Sdf_PrimPathNode :
public Sdf_PrimPartPathNode {
376 typedef TfToken ComparisonType;
377 static const NodeType nodeType = Sdf_PathNode::PrimNode;
380 Sdf_PrimPathNode(Sdf_PathNode
const *parent,
382 : Sdf_PrimPartPathNode(parent, nodeType)
385 SDF_API ~Sdf_PrimPathNode();
387 const ComparisonType &_GetComparisonValue()
const {
return _name; }
389 friend class Sdf_PathNode;
390 friend struct Sdf_PathNodePrivateAccess;
391 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
397class Sdf_PrimPropertyPathNode :
public Sdf_PropPartPathNode {
399 typedef TfToken ComparisonType;
400 static const NodeType nodeType = Sdf_PathNode::PrimPropertyNode;
403 Sdf_PrimPropertyPathNode(Sdf_PathNode
const *parent,
405 : Sdf_PropPartPathNode(parent, nodeType)
408 SDF_API ~Sdf_PrimPropertyPathNode();
410 friend class Sdf_PathNode;
411 friend struct Sdf_PathNodePrivateAccess;
412 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
414 const ComparisonType &_GetComparisonValue()
const {
return _name; }
420class Sdf_PrimVariantSelectionNode :
public Sdf_PrimPartPathNode {
422 typedef VariantSelectionType ComparisonType;
423 static const NodeType nodeType = Sdf_PathNode::PrimVariantSelectionNode;
425 const TfToken &_GetNameImpl()
const;
427 template <
class Buffer>
428 void _WriteTextImpl(Buffer &out)
const;
431 Sdf_PrimVariantSelectionNode(Sdf_PathNode
const *parent,
432 const VariantSelectionType &variantSelection)
433 : Sdf_PrimPartPathNode(parent, nodeType)
434 , _variantSelection(new VariantSelectionType(variantSelection)) {}
436 SDF_API ~Sdf_PrimVariantSelectionNode();
438 const ComparisonType &_GetComparisonValue()
const {
439 return *_variantSelection;
442 friend class Sdf_PathNode;
443 friend struct Sdf_PathNodePrivateAccess;
444 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
447 std::unique_ptr<VariantSelectionType> _variantSelection;
450class Sdf_TargetPathNode :
public Sdf_PropPartPathNode {
452 typedef SdfPath ComparisonType;
453 static const NodeType nodeType = Sdf_PathNode::TargetNode;
455 template <
class Buffer>
456 void _WriteTextImpl(Buffer &out)
const;
459 Sdf_TargetPathNode(Sdf_PathNode
const *parent,
461 : Sdf_PropPartPathNode(parent, nodeType)
462 , _targetPath(targetPath) {}
464 SDF_API ~Sdf_TargetPathNode();
466 const ComparisonType& _GetComparisonValue()
const {
return _targetPath; }
468 friend class Sdf_PathNode;
469 friend struct Sdf_PathNodePrivateAccess;
470 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
476class Sdf_RelationalAttributePathNode :
public Sdf_PropPartPathNode {
478 typedef TfToken ComparisonType;
479 static const NodeType nodeType = Sdf_PathNode::RelationalAttributeNode;
482 Sdf_RelationalAttributePathNode(Sdf_PathNode
const *parent,
484 : Sdf_PropPartPathNode(parent, nodeType)
487 SDF_API ~Sdf_RelationalAttributePathNode();
489 const ComparisonType& _GetComparisonValue()
const {
return _name; }
491 friend class Sdf_PathNode;
492 friend struct Sdf_PathNodePrivateAccess;
493 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
499class Sdf_MapperPathNode :
public Sdf_PropPartPathNode {
501 typedef SdfPath ComparisonType;
502 static const NodeType nodeType = Sdf_PathNode::MapperNode;
504 template <
class Buffer>
505 void _WriteTextImpl(Buffer &out)
const;
508 Sdf_MapperPathNode(Sdf_PathNode
const *parent,
510 : Sdf_PropPartPathNode(parent, nodeType)
511 , _targetPath(targetPath) {}
513 SDF_API ~Sdf_MapperPathNode();
515 const ComparisonType& _GetComparisonValue()
const {
return _targetPath; }
517 friend class Sdf_PathNode;
518 friend struct Sdf_PathNodePrivateAccess;
519 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
525class Sdf_MapperArgPathNode :
public Sdf_PropPartPathNode {
527 typedef TfToken ComparisonType;
528 static const NodeType nodeType = Sdf_PathNode::MapperArgNode;
530 template <
class Buffer>
531 void _WriteTextImpl(Buffer &out)
const;
534 Sdf_MapperArgPathNode(Sdf_PathNode
const *parent,
536 : Sdf_PropPartPathNode(parent, nodeType)
539 SDF_API ~Sdf_MapperArgPathNode();
541 const ComparisonType& _GetComparisonValue()
const {
return _name; }
543 friend class Sdf_PathNode;
544 friend struct Sdf_PathNodePrivateAccess;
545 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
551class Sdf_ExpressionPathNode :
public Sdf_PropPartPathNode {
553 typedef void *ComparisonType;
554 static const NodeType nodeType = Sdf_PathNode::ExpressionNode;
556 template <
class Buffer>
557 void _WriteTextImpl(Buffer &out)
const;
560 Sdf_ExpressionPathNode(Sdf_PathNode
const *parent)
561 : Sdf_PropPartPathNode(parent, nodeType) {}
563 SDF_API ~Sdf_ExpressionPathNode();
565 ComparisonType _GetComparisonValue()
const {
return nullptr; }
567 friend class Sdf_PathNode;
568 friend struct Sdf_PathNodePrivateAccess;
569 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
575template <
int nodeType>
576struct Sdf_PathNodeTypeToType {
578template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::PrimNode> {
579 typedef Sdf_PrimPathNode Type;
581template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::PrimPropertyNode> {
582 typedef Sdf_PrimPropertyPathNode Type;
584template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::RelationalAttributeNode> {
585 typedef Sdf_RelationalAttributePathNode Type;
587template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::MapperArgNode> {
588 typedef Sdf_MapperArgPathNode Type;
590template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::TargetNode> {
591 typedef Sdf_TargetPathNode Type;
593template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::MapperNode> {
594 typedef Sdf_MapperPathNode Type;
596template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::PrimVariantSelectionNode> {
597 typedef Sdf_PrimVariantSelectionNode Type;
599template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::ExpressionNode> {
600 typedef Sdf_ExpressionPathNode Type;
602template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::RootNode> {
603 typedef Sdf_RootPathNode Type;
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());
618Sdf_PathNode::Compare(
const Sdf_PathNode &rhs)
const
628 NodeType nodeType = GetNodeType(), rhsNodeType = rhs.GetNodeType();
629 if (nodeType != rhsNodeType) {
630 return Comp()(nodeType, rhsNodeType);
635 case Sdf_PathNode::PrimNode:
636 return Sdf_PathNodeCompare<Sdf_PathNode::PrimNode,
638 case Sdf_PathNode::PrimPropertyNode:
639 return Sdf_PathNodeCompare<Sdf_PathNode::PrimPropertyNode,
641 case Sdf_PathNode::RelationalAttributeNode:
642 return Sdf_PathNodeCompare<Sdf_PathNode::RelationalAttributeNode,
644 case Sdf_PathNode::MapperArgNode:
645 return Sdf_PathNodeCompare<Sdf_PathNode::MapperArgNode,
647 case Sdf_PathNode::TargetNode:
648 return Sdf_PathNodeCompare<Sdf_PathNode::TargetNode,
650 case Sdf_PathNode::MapperNode:
651 return Sdf_PathNodeCompare<Sdf_PathNode::MapperNode,
653 case Sdf_PathNode::PrimVariantSelectionNode:
654 return Sdf_PathNodeCompare<Sdf_PathNode::PrimVariantSelectionNode,
656 case Sdf_PathNode::ExpressionNode:
657 return Sdf_PathNodeCompare<Sdf_PathNode::ExpressionNode,
659 case Sdf_PathNode::RootNode:
660 return Sdf_PathNodeCompare<Sdf_PathNode::RootNode,
669Sdf_PathNode::_Destroy()
const
674 return delete _Downcast<Sdf_RootPathNode>();
676 return delete _Downcast<Sdf_PrimPathNode>();
677 case PrimPropertyNode:
678 return delete _Downcast<Sdf_PrimPropertyPathNode>();
679 case PrimVariantSelectionNode:
680 return delete _Downcast<Sdf_PrimVariantSelectionNode>();
682 return delete _Downcast<Sdf_TargetPathNode>();
683 case RelationalAttributeNode:
684 return delete _Downcast<Sdf_RelationalAttributePathNode>();
686 return delete _Downcast<Sdf_MapperPathNode>();
688 return delete _Downcast<Sdf_MapperArgPathNode>();
690 return delete _Downcast<Sdf_ExpressionPathNode>();
697Sdf_PathNode::GetName()
const
701 return SdfPathTokens->empty;
703 return IsAbsolutePath() ?
704 SdfPathTokens->absoluteIndicator : SdfPathTokens->relativeRoot;
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;
714 return _Downcast<Sdf_MapperArgPathNode>()->_name;
716 return SdfPathTokens->expressionIndicator;
721Sdf_PathNode::GetTargetPath()
const
727 return _Downcast<Sdf_TargetPathNode>()->_targetPath;
729 return _Downcast<Sdf_MapperPathNode>()->_targetPath;
733inline const Sdf_PathNode::VariantSelectionType &
734Sdf_PathNode::GetVariantSelection()
const
736 if (ARCH_LIKELY(_nodeType == PrimVariantSelectionNode)) {
737 return *_Downcast<Sdf_PrimVariantSelectionNode>()->_variantSelection;
739 return _GetEmptyVariantSelection();
743Sdf_PathNode::GetElement()
const
749 return _Downcast<Sdf_PrimPathNode>()->_name;
751 return _GetElementImpl();
756SDF_API
void Sdf_DumpPathStats();
758inline void TfDelegatedCountIncrement(
const PXR_NS::Sdf_PathNode* p)
noexcept {
759 p->_refCount.fetch_add(1, std::memory_order_relaxed);
761inline void TfDelegatedCountDecrement(
const PXR_NS::Sdf_PathNode* p)
noexcept {
762 if ((p->_refCount.fetch_sub(1) & PXR_NS::Sdf_PathNode::RefCountMask) == 1) {
767PXR_NAMESPACE_CLOSE_SCOPE
A path value used to locate objects in layers or scenegraphs.
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...
Token for efficient comparison, assignment, and hashing of known strings.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...