summaryrefslogtreecommitdiff
path: root/source/core/slang-com-object.h
diff options
context:
space:
mode:
Diffstat (limited to 'source/core/slang-com-object.h')
-rw-r--r--source/core/slang-com-object.h68
1 files changed, 68 insertions, 0 deletions
diff --git a/source/core/slang-com-object.h b/source/core/slang-com-object.h
index 50dac5ba2..617b7ccca 100644
--- a/source/core/slang-com-object.h
+++ b/source/core/slang-com-object.h
@@ -6,6 +6,74 @@
namespace Slang
{
+
+/// A base class for COM interfaces that require atomic ref counting
+/// and are *NOT* derived from RefObject
+class ComBaseObject
+{
+public:
+
+ /// If assigned the the ref count is *NOT* copied
+ ComBaseObject& operator=(const ComBaseObject&) { return *this; }
+
+ /// Copy Ctor, does not copy ref count
+ ComBaseObject(const ComBaseObject&) :
+ m_refCount(0)
+ {}
+
+ /// Default Ctor sets with no refs
+ ComBaseObject()
+ : m_refCount(0)
+ {}
+
+ /// Dtor needs to be virtual to avoid needing to
+ /// Implement release for all derived types.
+ virtual ~ComBaseObject()
+ {}
+
+protected:
+ inline uint32_t _releaseImpl();
+
+ std::atomic<uint32_t> m_refCount;
+};
+
+// ------------------------------------------------------------------
+inline uint32_t ComBaseObject::_releaseImpl()
+{
+ // Check there is a ref count to avoid underflow
+ SLANG_ASSERT(m_refCount != 0);
+ const uint32_t count = --m_refCount;
+ if (count == 0)
+ {
+ delete this;
+ }
+ return count;
+}
+
+#define SLANG_COM_BASE_IUNKNOWN_QUERY_INTERFACE \
+ SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) \
+ SLANG_OVERRIDE \
+ { \
+ void* intf = getInterface(uuid); \
+ if (intf) \
+ { \
+ ++m_refCount; \
+ *outObject = intf; \
+ return SLANG_OK; \
+ } \
+ return SLANG_E_NO_INTERFACE; \
+ }
+#define SLANG_COM_BASE_IUNKNOWN_ADD_REF \
+ SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return ++m_refCount; }
+#define SLANG_COM_BASE_IUNKNOWN_RELEASE \
+ SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return _releaseImpl(); }
+#define SLANG_COM_BASE_IUNKNOWN_ALL \
+ SLANG_COM_BASE_IUNKNOWN_QUERY_INTERFACE \
+ SLANG_COM_BASE_IUNKNOWN_ADD_REF \
+ SLANG_COM_BASE_IUNKNOWN_RELEASE
+
+
+/// COM object that derives from RefObject
class ComObject : public RefObject
{
protected: