cesium-native  0.41.0
SharedAsset.h
1 #pragma once
2 
3 #include <CesiumUtility/Assert.h>
4 #include <CesiumUtility/ExtensibleObject.h>
5 #include <CesiumUtility/IDepotOwningAsset.h>
6 #include <CesiumUtility/Library.h>
7 
8 #include <atomic>
9 
10 namespace CesiumAsync {
11 template <typename TAssetType, typename TAssetKey> class SharedAssetDepot;
12 }
13 
14 namespace CesiumUtility {
15 
51 template <typename T>
52 class CESIUMUTILITY_API SharedAsset : public CesiumUtility::ExtensibleObject {
53 public:
59  void addReference() const noexcept { this->addReference(false); }
60 
67  void releaseReference() const noexcept { this->releaseReference(false); }
68 
73  const IDepotOwningAsset<T>* getDepot() const { return this->_pDepot; }
74 
79  IDepotOwningAsset<T>* getDepot() { return this->_pDepot; }
80 
81 protected:
82  SharedAsset() = default;
83  ~SharedAsset() { CESIUM_ASSERT(this->_referenceCount == 0); }
84 
90  : ExtensibleObject(rhs), _referenceCount(0), _pDepot(nullptr) {}
91 
97  : ExtensibleObject(std::move(rhs)),
98  _referenceCount(0),
99  _pDepot(nullptr) {}
100 
106  CesiumUtility::ExtensibleObject::operator=(rhs);
107  return *this;
108  }
109 
110  SharedAsset& operator=(SharedAsset&& rhs) {
111  CesiumUtility::ExtensibleObject::operator=(std::move(rhs));
112  return *this;
113  }
114 
115 private:
116  void addReference(bool threadOwnsDepotLock) const noexcept {
117  const int32_t prevReferences = this->_referenceCount++;
118  if (this->_pDepot && prevReferences <= 0) {
119  this->_pDepot->unmarkDeletionCandidate(
120  *static_cast<const T*>(this),
121  threadOwnsDepotLock);
122  }
123  }
124 
125  void releaseReference(bool threadOwnsDepotLock) const noexcept {
126  CESIUM_ASSERT(this->_referenceCount > 0);
127  const int32_t references = --this->_referenceCount;
128  if (references == 0) {
129  IDepotOwningAsset<T>* pDepot = this->_pDepot;
130  if (pDepot) {
131  // Let the depot manage this object's lifetime.
132  pDepot->markDeletionCandidate(
133  *static_cast<const T*>(this),
134  threadOwnsDepotLock);
135  } else {
136  // No depot, so destroy this object directly.
137  delete static_cast<const T*>(this);
138  }
139  }
140  }
141 
142  mutable std::atomic<std::int32_t> _referenceCount{0};
143  IDepotOwningAsset<T>* _pDepot{nullptr};
144 
145  // To allow the depot to modify _pDepot.
146  template <typename TAssetType, typename TAssetKey>
147  friend class CesiumAsync::SharedAssetDepot;
148 };
149 
150 } // namespace CesiumUtility
A depot for SharedAsset instances, which are potentially shared between multiple objects.
An asset that is potentially shared between multiple objects, such as an image shared between multipl...
Definition: SharedAsset.h:52
SharedAsset(const SharedAsset &rhs)
Definition: SharedAsset.h:89
SharedAsset & operator=(const SharedAsset &rhs)
Definition: SharedAsset.h:105
void releaseReference() const noexcept
Removes a counted reference from this object. When the last reference is removed, this method will de...
Definition: SharedAsset.h:67
void addReference() const noexcept
Adds a counted reference to this object. Use CesiumUtility::IntrusivePointer instead of calling this ...
Definition: SharedAsset.h:59
const IDepotOwningAsset< T > * getDepot() const
Gets the shared asset depot that owns this asset, or nullptr if this asset is independent of an asset...
Definition: SharedAsset.h:73
IDepotOwningAsset< T > * getDepot()
Gets the shared asset depot that owns this asset, or nullptr if this asset is independent of an asset...
Definition: SharedAsset.h:79
SharedAsset(SharedAsset &&rhs)
Definition: SharedAsset.h:96
Classes that support asynchronous operations.
Utility classes for Cesium.
The base class for objects that have extensions and extras.