diff options
author | Chris Robinson <[email protected]> | 2019-08-01 15:19:37 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2019-08-01 15:19:37 -0700 |
commit | 0be823320d651130e79fbba33eff81676d59b09c (patch) | |
tree | c9c3f111530680363be4c8fb04e20b24ca12679d | |
parent | 57e7fff6f67f302d0202b2229a960c02c3cb3c5d (diff) |
Add and use an intrusive_ptr type
-rw-r--r-- | alc/alc.cpp | 63 | ||||
-rw-r--r-- | alc/alcontext.h | 50 | ||||
-rw-r--r-- | common/intrusive_ptr.h | 65 |
3 files changed, 73 insertions, 105 deletions
diff --git a/alc/alc.cpp b/alc/alc.cpp index 462d4bd0..6837d107 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -906,53 +906,7 @@ constexpr ALCint alcEFXMinorVersion = 0; al::FlexArray<ALCcontext*> EmptyContextArray{0u}; -/* Simple RAII device reference. Takes the reference of the provided ALCdevice, - * and decrements it when leaving scope. Movable (transfer reference) but not - * copyable (no new references). - */ -class DeviceRef { - ALCdevice *mDev{nullptr}; - - void reset() noexcept - { - if(mDev) - mDev->release(); - mDev = nullptr; - } - -public: - DeviceRef() noexcept = default; - DeviceRef(DeviceRef&& rhs) noexcept : mDev{rhs.mDev} - { rhs.mDev = nullptr; } - explicit DeviceRef(ALCdevice *dev) noexcept : mDev(dev) { } - ~DeviceRef() { reset(); } - - DeviceRef& operator=(const DeviceRef&) = delete; - DeviceRef& operator=(DeviceRef&& rhs) noexcept - { - std::swap(mDev, rhs.mDev); - return *this; - } - - operator bool() const noexcept { return mDev != nullptr; } - - ALCdevice* operator->() const noexcept { return mDev; } - ALCdevice* get() const noexcept { return mDev; } - - ALCdevice* release() noexcept - { - ALCdevice *ret{mDev}; - mDev = nullptr; - return ret; - } -}; - -inline bool operator==(const DeviceRef &lhs, const ALCdevice *rhs) noexcept -{ return lhs.get() == rhs; } -inline bool operator!=(const DeviceRef &lhs, const ALCdevice *rhs) noexcept -{ return !(lhs == rhs); } -inline bool operator<(const DeviceRef &lhs, const ALCdevice *rhs) noexcept -{ return lhs.get() < rhs; } +using DeviceRef = al::intrusive_ptr<ALCdevice>; /************************************************ @@ -2345,11 +2299,8 @@ static DeviceRef VerifyDevice(ALCdevice *device) std::lock_guard<std::recursive_mutex> _{ListLock}; auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device); if(iter != DeviceList.cend() && *iter == device) - { - (*iter)->add_ref(); - return DeviceRef{iter->get()}; - } - return DeviceRef{}; + return *iter; + return nullptr; } @@ -2590,14 +2541,10 @@ static ContextRef VerifyContext(ALCcontext *context) std::lock_guard<std::recursive_mutex> _{ListLock}; auto iter = std::lower_bound(ContextList.cbegin(), ContextList.cend(), context); if(iter != ContextList.cend() && *iter == context) - { - (*iter)->add_ref(); - return ContextRef{iter->get()}; - } - return ContextRef{}; + return *iter; + return nullptr; } - /* GetContextRef * * Returns a new reference to the currently active context for this thread. diff --git a/alc/alcontext.h b/alc/alcontext.h index 53da10dc..ebb70a79 100644 --- a/alc/alcontext.h +++ b/alc/alcontext.h @@ -178,56 +178,12 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext> { } while(0) -void UpdateContextProps(ALCcontext *context); - - -/* Simple RAII context reference. Takes the reference of the provided - * ALCcontext, and decrements it when leaving scope. Movable (transfer - * reference) but not copyable (no new references). - */ -class ContextRef { - ALCcontext *mCtx{nullptr}; - - void reset() noexcept - { - if(mCtx) - mCtx->release(); - mCtx = nullptr; - } - -public: - ContextRef() noexcept = default; - ContextRef(ContextRef&& rhs) noexcept : mCtx{rhs.mCtx} - { rhs.mCtx = nullptr; } - explicit ContextRef(ALCcontext *ctx) noexcept : mCtx(ctx) { } - ~ContextRef() { reset(); } - - ContextRef& operator=(const ContextRef&) = delete; - ContextRef& operator=(ContextRef&& rhs) noexcept - { std::swap(mCtx, rhs.mCtx); return *this; } - - operator bool() const noexcept { return mCtx != nullptr; } - - ALCcontext* operator->() const noexcept { return mCtx; } - ALCcontext* get() const noexcept { return mCtx; } - - ALCcontext* release() noexcept - { - ALCcontext *ret{mCtx}; - mCtx = nullptr; - return ret; - } -}; - -inline bool operator==(const ContextRef &lhs, const ALCcontext *rhs) noexcept -{ return lhs.get() == rhs; } -inline bool operator!=(const ContextRef &lhs, const ALCcontext *rhs) noexcept -{ return !(lhs == rhs); } -inline bool operator<(const ContextRef &lhs, const ALCcontext *rhs) noexcept -{ return lhs.get() < rhs; } +using ContextRef = al::intrusive_ptr<ALCcontext>; ContextRef GetContextRef(void); +void UpdateContextProps(ALCcontext *context); + extern bool TrapALError; diff --git a/common/intrusive_ptr.h b/common/intrusive_ptr.h index 8f34aeac..85f019fd 100644 --- a/common/intrusive_ptr.h +++ b/common/intrusive_ptr.h @@ -43,6 +43,71 @@ public: } }; + +template<typename T> +class intrusive_ptr { + T *mPtr{nullptr}; + +public: + intrusive_ptr() noexcept = default; + intrusive_ptr(const intrusive_ptr &rhs) noexcept : mPtr{rhs.mPtr} + { if(mPtr) mPtr->add_ref(); } + intrusive_ptr(intrusive_ptr&& rhs) noexcept : mPtr{rhs.mPtr} + { rhs.mPtr = nullptr; } + intrusive_ptr(std::nullptr_t) noexcept { } + explicit intrusive_ptr(T *ptr) noexcept : mPtr{ptr} { } + ~intrusive_ptr() { reset(); } + + intrusive_ptr& operator=(const intrusive_ptr &rhs) noexcept + { + if(rhs.mPtr) rhs.mPtr->add_ref(); + if(mPtr) mPtr->release(); + mPtr = rhs.mPtr; + return *this; + } + intrusive_ptr& operator=(intrusive_ptr&& rhs) noexcept + { std::swap(mPtr, rhs.mPtr); return *this; } + + operator bool() const noexcept { return mPtr != nullptr; } + + T* operator->() const noexcept { return mPtr; } + T* get() const noexcept { return mPtr; } + + void reset() noexcept + { + if(mPtr) + mPtr->release(); + mPtr = nullptr; + } + + T* release() noexcept + { + T *ret{mPtr}; + mPtr = nullptr; + return ret; + } + + void swap(intrusive_ptr &rhs) noexcept { std::swap(mPtr, rhs.mPtr); } + void swap(intrusive_ptr&& rhs) noexcept { std::swap(mPtr, rhs.mPtr); } +}; + +#define AL_DECL_OP(op) \ +template<typename T> \ +inline bool operator op(const intrusive_ptr<T> &lhs, const T *rhs) noexcept \ +{ return lhs.get() op rhs; } \ +template<typename T> \ +inline bool operator op(const T *lhs, const intrusive_ptr<T> &rhs) noexcept \ +{ return lhs op rhs.get(); } + +AL_DECL_OP(==) +AL_DECL_OP(!=) +AL_DECL_OP(<=) +AL_DECL_OP(>=) +AL_DECL_OP(<) +AL_DECL_OP(>) + +#undef AL_DECL_OP + } // namespace al #endif /* INTRUSIVE_PTR_H */ |