HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
refBase.h
Go to the documentation of this file.
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_BASE_TF_REF_BASE_H
8 #define PXR_BASE_TF_REF_BASE_H
9 
10 /// \file tf/refBase.h
11 /// \ingroup group_tf_Memory
12 
13 #include "pxr/pxr.h"
14 
15 #include "pxr/base/tf/api.h"
16 
17 #include <atomic>
18 #include <cmath>
19 
21 
22 template <class T> class TfRefPtr;
23 template <class T> class TfWeakPtr;
24 
25 /// \class TfRefBase
26 /// \ingroup group_tf_Memory
27 ///
28 /// Enable a concrete base class for use with \c TfRefPtr.
29 ///
30 /// You should be familiar with the \c TfRefPtr type before reading further.
31 ///
32 /// A class (but not an interface class) is enabled for reference
33 /// counting via the \c TfRefPtr type by publicly deriving from \c
34 /// TfRefBase.
35 ///
36 /// For example,
37 /// \code
38 /// #include "pxr/base/tf/refPtr.h"
39 ///
40 /// class Simple : public TfRefBase {
41 /// public:
42 /// TfRefPtr<Simple> New() {
43 /// return TfCreateRefPtr(new Simple);
44 /// }
45 /// private:
46 /// Simple();
47 /// };
48 /// \endcode
49 ///
50 /// The class \c Simple can now only be manipulated in terms of
51 /// a \c TfRefPtr<Simple>.
52 ///
53 /// To disable the cost of the "unique changed" system, derive
54 /// from TfSimpleRefBase instead.
55 ///
56 class TfRefBase {
57 public:
58 
59  typedef void (*UniqueChangedFuncPtr)(TfRefBase const *, bool);
61  void (*lock)();
63  void (*unlock)();
64  };
65 
66  // This mimics the old TfRefCount's default ctor behavior, which set
67  // _refCount to 1.
68  TfRefBase() : _refCount(1) {}
69 
70  // This mimics the old TfRefCount's copy ctor behavior, which set _refCount
71  // to 1 on copy construction.
72  TfRefBase(TfRefBase const &) : _refCount(1) {}
73 
74  // This mimics the old TfRefCount's copy assignment behavior, which took no
75  // action.
77  return *this;
78  }
79 
80  /// Return the current reference count of this object.
81  size_t GetCurrentCount() const {
82  // Return the absolute value since the sign encodes whether or not this
83  // TfRefBase invokes the UniqueChangedListener.
84  return std::abs(_refCount.load(std::memory_order_relaxed));
85  }
86 
87  /// Return true if only one \c TfRefPtr points to this object.
88  bool IsUnique() const {
89  return GetCurrentCount() == 1;
90  }
91 
92  void SetShouldInvokeUniqueChangedListener(bool shouldCall) {
93  int curValue = _refCount.load(std::memory_order_relaxed);
94  while ((curValue > 0 && shouldCall) ||
95  (curValue < 0 && !shouldCall)) {
96  if (_refCount.compare_exchange_weak(curValue, -curValue)) {
97  return;
98  }
99  }
100  }
101 
102  TF_API static void SetUniqueChangedListener(UniqueChangedListener listener);
103 
104 protected:
105  /*
106  * Prohibit deletion through a TfRefBase pointer.
107  */
108  TF_API virtual ~TfRefBase();
109 
110 private:
111  // For TfRefPtr's use.
112  std::atomic_int &_GetRefCount() const {
113  return _refCount;
114  }
115 
116  // Note! Counts can be both positive or negative. Negative counts indicate
117  // that we must invoke the _uniqueChangedListener if the count goes 1 -> 2
118  // or 2 -> 1 (which is really -1 -> -2 or -2 -> -1).
119  mutable std::atomic_int _refCount;
120 
121  static UniqueChangedListener _uniqueChangedListener;
122  template <typename T> friend class TfRefPtr;
124  friend struct Tf_RefPtr_Counter;
125 
126  template <typename T> friend TfRefPtr<T>
128 };
129 
130 /// \class TfSimpleRefBase
131 /// \ingroup group_tf_Memory
132 ///
133 /// Enable a concrete base class for use with \c TfRefPtr that inhibits the
134 /// "unique changed" facility of TfRefPtr.
135 ///
136 /// Derive from this class if you don't plan on wrapping your
137 /// reference-counted object via pxr_boost::python.
138 ///
139 class TfSimpleRefBase : public TfRefBase {
140 public:
141  TF_API virtual ~TfSimpleRefBase();
142 };
143 
145 
146 #endif // PXR_BASE_TF_REF_BASE_H
bool IsUnique() const
Return true if only one TfRefPtr points to this object.
Definition: refBase.h:88
#define TF_API
Definition: api.h:23
TfRefBase & operator=(TfRefBase const &)
Definition: refBase.h:76
void
Definition: png.h:1083
friend TfRefPtr< T > TfCreateRefPtrFromProtectedWeakPtr(TfWeakPtr< T > const &)
Definition: weakPtr.h:260
virtual TF_API ~TfRefBase()
void(* UniqueChangedFuncPtr)(TfRefBase const *, bool)
Definition: refBase.h:59
OutGridT const XformOp bool bool
TfRefBase(TfRefBase const &)
Definition: refBase.h:72
atomic< int > atomic_int
Definition: atomic.h:25
virtual TF_API ~TfSimpleRefBase()
UniqueChangedFuncPtr func
Definition: refBase.h:62
static TF_API void SetUniqueChangedListener(UniqueChangedListener listener)
size_t GetCurrentCount() const
Return the current reference count of this object.
Definition: refBase.h:81
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER IMATH_HOSTDEVICE constexpr T abs(T a) IMATH_NOEXCEPT
Definition: ImathFun.h:26
void SetShouldInvokeUniqueChangedListener(bool shouldCall)
Definition: refBase.h:92
TfRefBase()
Definition: refBase.h:68