nx_metadata_sdk 1.0 Metadata SDK

ref_countable.h
1 // Copyright 2018-present Network Optix, Inc. Licensed under MPL 2.0: www.mozilla.org/MPL/2.0/
2
3 #pragma once
4
5 #include <atomic>
6
7 #include <nx/sdk/i_ref_countable.h>
8 #include <nx/sdk/helpers/lib_context.h>
9
10 namespace nx {
11 namespace sdk {
12
24 class RefCountableHolder
25 {
26 public:
27 RefCountableHolder(const RefCountableHolder&) = delete;
28 RefCountableHolder& operator=(const RefCountableHolder&) = delete;
29 RefCountableHolder(RefCountableHolder&&) = delete;
30 RefCountableHolder& operator=(RefCountableHolder&&) = delete;
31 ~RefCountableHolder() = default;
32
39 RefCountableHolder(const IRefCountable* refCountable): m_refCountable(refCountable) {}
40
44 RefCountableHolder(const RefCountableHolder* delegate): m_refCountHolderDelegate(delegate) {}
45
46 int addRef() const
47 {
48 return m_refCountHolderDelegate ? m_refCountHolderDelegate->addRef() : ++m_refCount;
49 }
50
54 int releaseRef() const
55 {
56 if (m_refCountHolderDelegate)
57 return m_refCountHolderDelegate->releaseRef();
58
59 const int newRefCounter = --m_refCount;
60 if (newRefCounter == 0)
61 delete m_refCountable;
62 return newRefCounter;
63 }
64
65 int refCount() const
66 {
67 if (m_refCountHolderDelegate)
68 return m_refCountHolderDelegate->refCount();
69 return m_refCount;
70 }
71
72 private:
73 mutable std::atomic<int> m_refCount{1};
74 const IRefCountable* const m_refCountable = nullptr;
75 const RefCountableHolder* const m_refCountHolderDelegate = nullptr;
76 };
77
83 template<class RefCountableInterface>
84 class RefCountable: public RefCountableInterface
85 {
86 public:
87 RefCountable(const RefCountable&) = delete;
88 RefCountable& operator=(const RefCountable&) = delete;
89 RefCountable(RefCountable&&) = delete;
90 RefCountable& operator=(RefCountable&&) = delete;
91
92 virtual ~RefCountable()
93 {
94 if (const auto refCountableRegistry = libContext().refCountableRegistry())
95 refCountableRegistry->notifyDestroyed(this, refCount());
96 }
97
98 virtual int addRef() const override { return m_refCountableHolder.addRef(); }
99 virtual int releaseRef() const override { return m_refCountableHolder.releaseRef(); }
100
101 int refCount() const { return m_refCountableHolder.refCount(); }
102
103 protected:
104 RefCountable(): m_refCountableHolder(static_cast<const RefCountableInterface*>(this))
105 {
106 if (const auto refCountableRegistry = libContext().refCountableRegistry())
107 refCountableRegistry->notifyCreated(this, refCount());
108 }
109
110 private:
111 const RefCountableHolder m_refCountableHolder;
112 };
113
114 } // namespace sdk
115 } // namespace nx
nx::sdk::RefCountableHolder::RefCountableHolder
RefCountableHolder(const RefCountableHolder *delegate)
Definition: ref_countable.h:44
nx::sdk::RefCountableHolder::RefCountableHolder
RefCountableHolder(const IRefCountable *refCountable)
Definition: ref_countable.h:39
nx::sdk::RefCountableHolder::releaseRef
int releaseRef() const
Definition: ref_countable.h:54
nx
Definition: apple_utils.h:6
nx::sdk::RefCountableHolder
Definition: ref_countable.h:24
nx::sdk::IRefCountable
Definition: i_ref_countable.h:50
nx::sdk::RefCountable
Definition: ref_countable.h:84