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/helpers/lib_context.h>
8 #include <nx/sdk/i_ref_countable.h>
9
10 namespace nx::sdk {
11
23 class RefCountableHolder
24 {
25 public:
26 RefCountableHolder(const RefCountableHolder&) = delete;
27 RefCountableHolder& operator=(const RefCountableHolder&) = delete;
28 RefCountableHolder(RefCountableHolder&&) = delete;
29 RefCountableHolder& operator=(RefCountableHolder&&) = delete;
30 ~RefCountableHolder() = default;
31
38 RefCountableHolder(const IRefCountable* refCountable): m_refCountable(refCountable) {}
39
43 RefCountableHolder(const RefCountableHolder* delegate): m_refCountHolderDelegate(delegate) {}
44
45 int addRef() const
46 {
47 return m_refCountHolderDelegate ? m_refCountHolderDelegate->addRef() : ++m_refCount;
48 }
49
53 int releaseRef() const
54 {
55 if (m_refCountHolderDelegate)
56 return m_refCountHolderDelegate->releaseRef();
57
58 const int newRefCounter = --m_refCount;
59 if (newRefCounter == 0)
60 delete m_refCountable;
61 return newRefCounter;
62 }
63
64 int refCount() const
65 {
66 if (m_refCountHolderDelegate)
67 return m_refCountHolderDelegate->refCount();
68 return m_refCount;
69 }
70
71 private:
72 mutable std::atomic<int> m_refCount{1};
73 const IRefCountable* const m_refCountable = nullptr;
74 const RefCountableHolder* const m_refCountHolderDelegate = nullptr;
75 };
76
82 template<class RefCountableInterface>
83 class RefCountable: public RefCountableInterface
84 {
85 public:
86 RefCountable(const RefCountable&) = delete;
87 RefCountable& operator=(const RefCountable&) = delete;
88 RefCountable(RefCountable&&) = delete;
89 RefCountable& operator=(RefCountable&&) = delete;
90
91 virtual ~RefCountable()
92 {
93 if (const auto refCountableRegistry = libContext().refCountableRegistry())
94 refCountableRegistry->notifyDestroyed(this, refCount());
95 }
96
97 virtual int addRef() const override { return m_refCountableHolder.addRef(); }
98 virtual int releaseRef() const override { return m_refCountableHolder.releaseRef(); }
99
100 int refCount() const { return m_refCountableHolder.refCount(); }
101
102 protected:
103 RefCountable(): m_refCountableHolder(static_cast<const IRefCountable*>(this))
104 {
105 if (const auto refCountableRegistry = libContext().refCountableRegistry())
106 refCountableRegistry->notifyCreated(this, refCount());
107 }
108
109 private:
110 const RefCountableHolder m_refCountableHolder;
111 };
112
113 } // namespace nx::sdk
nx::sdk::RefCountableHolder::RefCountableHolder
RefCountableHolder(const RefCountableHolder *delegate)
Definition: ref_countable.h:43
nx::sdk::RefCountableHolder::RefCountableHolder
RefCountableHolder(const IRefCountable *refCountable)
Definition: ref_countable.h:38
nx::sdk::RefCountableHolder::releaseRef
int releaseRef() const
Definition: ref_countable.h:53
nx::sdk
Definition: device_agent.h:12
nx::sdk::RefCountableHolder
Definition: ref_countable.h:23
nx::sdk::IRefCountable
Definition: i_ref_countable.h:49
nx::sdk::RefCountable
Definition: ref_countable.h:83