7#ifndef PXR_USD_SDF_PATH_NODE_H
8#define PXR_USD_SDF_PATH_NODE_H
11#include "pxr/usd/sdf/api.h"
12#include "pxr/base/tf/delegatedCountPtr.h"
13#include "pxr/base/tf/functionRef.h"
17PXR_NAMESPACE_OPEN_SCOPE
42 Sdf_PathNode(Sdf_PathNode
const &) =
delete;
43 Sdf_PathNode &operator=(Sdf_PathNode
const &) =
delete;
46 static constexpr uint8_t IsAbsoluteFlag = 1 << 0;
47 static constexpr uint8_t ContainsPrimVarSelFlag = 1 << 1;
48 static constexpr uint8_t ContainsTargetPathFlag = 1 << 2;
50 static constexpr uint32_t HasTokenBit = 1u << 31;
51 static constexpr uint32_t RefCountMask = ~HasTokenBit;
56 enum NodeType : uint8_t {
73 PrimVariantSelectionNode,
97 RelationalAttributeNode,
114 static Sdf_PathPrimNodeHandle
115 FindOrCreatePrim(Sdf_PathNode
const *parent,
const TfToken &name,
118 static Sdf_PathPropNodeHandle
119 FindOrCreatePrimProperty(
120 Sdf_PathNode
const *parent,
const TfToken &name,
123 static Sdf_PathPrimNodeHandle
124 FindOrCreatePrimVariantSelection(Sdf_PathNode
const *parent,
129 static Sdf_PathPropNodeHandle
130 FindOrCreateTarget(Sdf_PathNode
const *parent,
134 static Sdf_PathPropNodeHandle
135 FindOrCreateRelationalAttribute(Sdf_PathNode
const *parent,
139 static Sdf_PathPropNodeHandle
140 FindOrCreateMapper(Sdf_PathNode
const *parent,
SdfPath const &targetPath,
143 static Sdf_PathPropNodeHandle
144 FindOrCreateMapperArg(Sdf_PathNode
const *parent,
const TfToken &name,
147 static Sdf_PathPropNodeHandle
148 FindOrCreateExpression(Sdf_PathNode
const *parent,
151 static Sdf_PathNode
const *GetAbsoluteRootNode();
152 static Sdf_PathNode
const *GetRelativeRootNode();
154 NodeType GetNodeType()
const {
return NodeType(_nodeType); }
156 static std::pair<Sdf_PathNode const *, Sdf_PathNode const *>
157 RemoveCommonSuffix(Sdf_PathNode
const *a,
158 Sdf_PathNode
const *b,
159 bool stopAtRootPrim);
162 inline Sdf_PathNode
const *GetParentNode()
const {
return _parent.get(); }
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;
170 bool IsNamespaced()
const {
173 return ((_nodeType == PrimPropertyNode) |
174 (_nodeType == RelationalAttributeNode)) && _IsNamespacedImpl();
177 bool ContainsPrimVariantSelection()
const {
178 return _nodeFlags & ContainsPrimVarSelFlag;
185 inline const TfToken &GetName()
const;
189 inline const SdfPath &GetTargetPath()
const;
191 typedef std::pair<TfToken, TfToken> VariantSelectionType;
192 inline const VariantSelectionType& GetVariantSelection()
const;
196 inline TfToken GetElement()
const;
200 GetPathToken(Sdf_PathNode
const *primPart, Sdf_PathNode
const *propPart);
204 GetPathAsToken(Sdf_PathNode
const *primPart, Sdf_PathNode
const *propPart);
207 GetDebugText(Sdf_PathNode
const *primPart, Sdf_PathNode
const *propPart);
212 inline bool operator()(T
const &a, T
const &b)
const {
219 template <
class Less>
220 inline bool Compare(
const Sdf_PathNode &rhs)
const;
224 uint32_t GetCurrentRefCount()
const {
225 return _refCount.load(std::memory_order_relaxed) & RefCountMask;
229 Sdf_PathNode(Sdf_PathNode
const *parent, NodeType nodeType)
230 : _parent(TfDelegatedCountIncrementTag, parent)
232 , _elementCount(parent ? parent->_elementCount + 1 : 1)
233 , _nodeType(nodeType)
235 (parent ? parent->_nodeFlags : 0) | _NodeTypeToFlags(nodeType))
240 explicit Sdf_PathNode(
bool isAbsolute);
243 if (_refCount.load(std::memory_order_relaxed) & HasTokenBit) {
244 _RemovePathTokenFromTable();
251 inline void _Destroy()
const;
253 TfToken _GetElementImpl()
const;
256 static TfToken _CreatePathToken(Sdf_PathNode
const *primPart,
257 Sdf_PathNode
const *propPart);
259 template <
class Buffer>
260 static void _WriteTextToBuffer(Sdf_PathNode
const *primPart,
261 Sdf_PathNode
const *propPart,
264 template <
class Buffer>
265 static void _WriteTextToBuffer(
SdfPath const &path, Buffer &out);
268 template <
class Buffer>
269 void _WriteText(Buffer &out)
const;
272 SDF_API
void _RemovePathTokenFromTable()
const;
274 struct _EqualElement {
276 inline bool operator()(T
const &a, T
const &b)
const {
281 friend struct Sdf_PathNodePrivateAccess;
284 friend void TfDelegatedCountIncrement(
const Sdf_PathNode*)
noexcept;
285 friend void TfDelegatedCountDecrement(
const Sdf_PathNode*)
noexcept;
288 static constexpr uint8_t _NodeTypeToFlags(NodeType nt) {
289 if (nt == PrimVariantSelectionNode) {
290 return ContainsPrimVarSelFlag;
292 if (nt == TargetNode || nt == MapperNode) {
293 return ContainsTargetPathFlag;
299 template <
class Derived>
300 Derived
const *_Downcast()
const {
301 return static_cast<Derived
const *
>(
this);
305 bool _IsNamespacedImpl()
const;
308 VariantSelectionType
const &_GetEmptyVariantSelection()
const;
316 mutable std::atomic<uint32_t> _refCount;
318 const uint16_t _elementCount;
319 const NodeType _nodeType;
320 const uint8_t _nodeFlags;
324class Sdf_PrimPartPathNode :
public Sdf_PathNode {
326 using Sdf_PathNode::Sdf_PathNode;
327 SDF_API
void operator delete (
void *p);
330class Sdf_PropPartPathNode :
public Sdf_PathNode {
332 using Sdf_PathNode::Sdf_PathNode;
333 SDF_API
void operator delete (
void *p);
336class Sdf_RootPathNode :
public Sdf_PrimPartPathNode {
338 typedef bool ComparisonType;
339 static const NodeType nodeType = Sdf_PathNode::RootNode;
341 static SDF_API Sdf_PathNode
const *New(
bool isAbsolute);
345 Sdf_RootPathNode(
bool isAbsolute) : Sdf_PrimPartPathNode(isAbsolute) {}
347 ComparisonType _GetComparisonValue()
const {
350 return !IsAbsolutePath();
353 friend class Sdf_PathNode;
354 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
357class Sdf_PrimPathNode :
public Sdf_PrimPartPathNode {
359 typedef TfToken ComparisonType;
360 static const NodeType nodeType = Sdf_PathNode::PrimNode;
363 Sdf_PrimPathNode(Sdf_PathNode
const *parent,
365 : Sdf_PrimPartPathNode(parent, nodeType)
368 SDF_API ~Sdf_PrimPathNode();
370 const ComparisonType &_GetComparisonValue()
const {
return _name; }
372 friend class Sdf_PathNode;
373 friend struct Sdf_PathNodePrivateAccess;
374 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
380class Sdf_PrimPropertyPathNode :
public Sdf_PropPartPathNode {
382 typedef TfToken ComparisonType;
383 static const NodeType nodeType = Sdf_PathNode::PrimPropertyNode;
386 Sdf_PrimPropertyPathNode(Sdf_PathNode
const *parent,
388 : Sdf_PropPartPathNode(parent, nodeType)
391 SDF_API ~Sdf_PrimPropertyPathNode();
393 friend class Sdf_PathNode;
394 friend struct Sdf_PathNodePrivateAccess;
395 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
397 const ComparisonType &_GetComparisonValue()
const {
return _name; }
403class Sdf_PrimVariantSelectionNode :
public Sdf_PrimPartPathNode {
405 typedef VariantSelectionType ComparisonType;
406 static const NodeType nodeType = Sdf_PathNode::PrimVariantSelectionNode;
408 const TfToken &_GetNameImpl()
const;
410 template <
class Buffer>
411 void _WriteTextImpl(Buffer &out)
const;
414 Sdf_PrimVariantSelectionNode(Sdf_PathNode
const *parent,
415 const VariantSelectionType &variantSelection)
416 : Sdf_PrimPartPathNode(parent, nodeType)
417 , _variantSelection(new VariantSelectionType(variantSelection)) {}
419 SDF_API ~Sdf_PrimVariantSelectionNode();
421 const ComparisonType &_GetComparisonValue()
const {
422 return *_variantSelection;
425 friend class Sdf_PathNode;
426 friend struct Sdf_PathNodePrivateAccess;
427 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
430 std::unique_ptr<VariantSelectionType> _variantSelection;
433class Sdf_TargetPathNode :
public Sdf_PropPartPathNode {
435 typedef SdfPath ComparisonType;
436 static const NodeType nodeType = Sdf_PathNode::TargetNode;
438 template <
class Buffer>
439 void _WriteTextImpl(Buffer &out)
const;
442 Sdf_TargetPathNode(Sdf_PathNode
const *parent,
444 : Sdf_PropPartPathNode(parent, nodeType)
445 , _targetPath(targetPath) {}
447 SDF_API ~Sdf_TargetPathNode();
449 const ComparisonType& _GetComparisonValue()
const {
return _targetPath; }
451 friend class Sdf_PathNode;
452 friend struct Sdf_PathNodePrivateAccess;
453 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
459class Sdf_RelationalAttributePathNode :
public Sdf_PropPartPathNode {
461 typedef TfToken ComparisonType;
462 static const NodeType nodeType = Sdf_PathNode::RelationalAttributeNode;
465 Sdf_RelationalAttributePathNode(Sdf_PathNode
const *parent,
467 : Sdf_PropPartPathNode(parent, nodeType)
470 SDF_API ~Sdf_RelationalAttributePathNode();
472 const ComparisonType& _GetComparisonValue()
const {
return _name; }
474 friend class Sdf_PathNode;
475 friend struct Sdf_PathNodePrivateAccess;
476 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
482class Sdf_MapperPathNode :
public Sdf_PropPartPathNode {
484 typedef SdfPath ComparisonType;
485 static const NodeType nodeType = Sdf_PathNode::MapperNode;
487 template <
class Buffer>
488 void _WriteTextImpl(Buffer &out)
const;
491 Sdf_MapperPathNode(Sdf_PathNode
const *parent,
493 : Sdf_PropPartPathNode(parent, nodeType)
494 , _targetPath(targetPath) {}
496 SDF_API ~Sdf_MapperPathNode();
498 const ComparisonType& _GetComparisonValue()
const {
return _targetPath; }
500 friend class Sdf_PathNode;
501 friend struct Sdf_PathNodePrivateAccess;
502 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
508class Sdf_MapperArgPathNode :
public Sdf_PropPartPathNode {
510 typedef TfToken ComparisonType;
511 static const NodeType nodeType = Sdf_PathNode::MapperArgNode;
513 template <
class Buffer>
514 void _WriteTextImpl(Buffer &out)
const;
517 Sdf_MapperArgPathNode(Sdf_PathNode
const *parent,
519 : Sdf_PropPartPathNode(parent, nodeType)
522 SDF_API ~Sdf_MapperArgPathNode();
524 const ComparisonType& _GetComparisonValue()
const {
return _name; }
526 friend class Sdf_PathNode;
527 friend struct Sdf_PathNodePrivateAccess;
528 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
534class Sdf_ExpressionPathNode :
public Sdf_PropPartPathNode {
536 typedef void *ComparisonType;
537 static const NodeType nodeType = Sdf_PathNode::ExpressionNode;
539 template <
class Buffer>
540 void _WriteTextImpl(Buffer &out)
const;
543 Sdf_ExpressionPathNode(Sdf_PathNode
const *parent)
544 : Sdf_PropPartPathNode(parent, nodeType) {}
546 SDF_API ~Sdf_ExpressionPathNode();
548 ComparisonType _GetComparisonValue()
const {
return nullptr; }
550 friend class Sdf_PathNode;
551 friend struct Sdf_PathNodePrivateAccess;
552 template <
int nodeType,
class Comp>
friend struct Sdf_PathNodeCompare;
558template <
int nodeType>
559struct Sdf_PathNodeTypeToType {
561template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::PrimNode> {
562 typedef Sdf_PrimPathNode Type;
564template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::PrimPropertyNode> {
565 typedef Sdf_PrimPropertyPathNode Type;
567template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::RelationalAttributeNode> {
568 typedef Sdf_RelationalAttributePathNode Type;
570template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::MapperArgNode> {
571 typedef Sdf_MapperArgPathNode Type;
573template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::TargetNode> {
574 typedef Sdf_TargetPathNode Type;
576template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::MapperNode> {
577 typedef Sdf_MapperPathNode Type;
579template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::PrimVariantSelectionNode> {
580 typedef Sdf_PrimVariantSelectionNode Type;
582template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::ExpressionNode> {
583 typedef Sdf_ExpressionPathNode Type;
585template <>
struct Sdf_PathNodeTypeToType<Sdf_PathNode::RootNode> {
586 typedef Sdf_RootPathNode Type;
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());
601Sdf_PathNode::Compare(
const Sdf_PathNode &rhs)
const
611 NodeType nodeType = GetNodeType(), rhsNodeType = rhs.GetNodeType();
612 if (nodeType != rhsNodeType) {
613 return Comp()(nodeType, rhsNodeType);
618 case Sdf_PathNode::PrimNode:
619 return Sdf_PathNodeCompare<Sdf_PathNode::PrimNode,
621 case Sdf_PathNode::PrimPropertyNode:
622 return Sdf_PathNodeCompare<Sdf_PathNode::PrimPropertyNode,
624 case Sdf_PathNode::RelationalAttributeNode:
625 return Sdf_PathNodeCompare<Sdf_PathNode::RelationalAttributeNode,
627 case Sdf_PathNode::MapperArgNode:
628 return Sdf_PathNodeCompare<Sdf_PathNode::MapperArgNode,
630 case Sdf_PathNode::TargetNode:
631 return Sdf_PathNodeCompare<Sdf_PathNode::TargetNode,
633 case Sdf_PathNode::MapperNode:
634 return Sdf_PathNodeCompare<Sdf_PathNode::MapperNode,
636 case Sdf_PathNode::PrimVariantSelectionNode:
637 return Sdf_PathNodeCompare<Sdf_PathNode::PrimVariantSelectionNode,
639 case Sdf_PathNode::ExpressionNode:
640 return Sdf_PathNodeCompare<Sdf_PathNode::ExpressionNode,
642 case Sdf_PathNode::RootNode:
643 return Sdf_PathNodeCompare<Sdf_PathNode::RootNode,
652Sdf_PathNode::_Destroy()
const
657 return delete _Downcast<Sdf_RootPathNode>();
659 return delete _Downcast<Sdf_PrimPathNode>();
660 case PrimPropertyNode:
661 return delete _Downcast<Sdf_PrimPropertyPathNode>();
662 case PrimVariantSelectionNode:
663 return delete _Downcast<Sdf_PrimVariantSelectionNode>();
665 return delete _Downcast<Sdf_TargetPathNode>();
666 case RelationalAttributeNode:
667 return delete _Downcast<Sdf_RelationalAttributePathNode>();
669 return delete _Downcast<Sdf_MapperPathNode>();
671 return delete _Downcast<Sdf_MapperArgPathNode>();
673 return delete _Downcast<Sdf_ExpressionPathNode>();
680Sdf_PathNode::GetName()
const
684 return SdfPathTokens->empty;
686 return IsAbsolutePath() ?
687 SdfPathTokens->absoluteIndicator : SdfPathTokens->relativeRoot;
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;
697 return _Downcast<Sdf_MapperArgPathNode>()->_name;
699 return SdfPathTokens->expressionIndicator;
704Sdf_PathNode::GetTargetPath()
const
710 return _Downcast<Sdf_TargetPathNode>()->_targetPath;
712 return _Downcast<Sdf_MapperPathNode>()->_targetPath;
716inline const Sdf_PathNode::VariantSelectionType &
717Sdf_PathNode::GetVariantSelection()
const
719 if (ARCH_LIKELY(_nodeType == PrimVariantSelectionNode)) {
720 return *_Downcast<Sdf_PrimVariantSelectionNode>()->_variantSelection;
722 return _GetEmptyVariantSelection();
726Sdf_PathNode::GetElement()
const
732 return _Downcast<Sdf_PrimPathNode>()->_name;
734 return _GetElementImpl();
739SDF_API
void Sdf_DumpPathStats();
741inline void TfDelegatedCountIncrement(
const PXR_NS::Sdf_PathNode* p)
noexcept {
742 p->_refCount.fetch_add(1, std::memory_order_relaxed);
744inline void TfDelegatedCountDecrement(
const PXR_NS::Sdf_PathNode* p)
noexcept {
745 if ((p->_refCount.fetch_sub(1) & PXR_NS::Sdf_PathNode::RefCountMask) == 1) {
750PXR_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...