yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1#ifndef SLANG_COM_OBJECT_H 2#define SLANG_COM_OBJECT_H 3 4#include "slang-basic.h" 5 6#include <atomic> 7 8namespace Slang 9{ 10 11/// A base class for COM interfaces that require atomic ref counting 12/// and are *NOT* derived from RefObject 13class ComBaseObject 14{ 15public : 16/// If assigned the the ref count is *NOT* copied 17ComBaseObject & operator = (const ComBaseObject & ) {return * this ; } 18 19/// Copy Ctor, does not copy ref count 20ComBaseObject (const ComBaseObject & ) 21 :m_refCount (0 ) 22 { 23 } 24 25/// Default Ctor sets with no refs 26ComBaseObject () 27 :m_refCount (0 ) 28 { 29 } 30 31/// Dtor needs to be virtual to avoid needing to 32/// Implement release for all derived types. 33virtual ~ComBaseObject () {} 34 35protected : 36inline uint32_t _releaseImpl (); 37 38std ::atomic < uint32_t > m_refCount ; 39}; 40 41// ------------------------------------------------------------------ 42inline uint32_t ComBaseObject ::_releaseImpl () 43{ 44// Check there is a ref count to avoid underflow 45SLANG_ASSERT (m_refCount != 0 ); 46const uint32_t count = -- m_refCount ; 47if (count == 0 ) 48 { 49delete this ; 50 } 51return count ; 52} 53 54#define SLANG_COM_BASE_IUNKNOWN_QUERY_INTERFACE \ 55 SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) \ 56 SLANG_OVERRIDE \ 57 { \ 58 void* intf = getInterface(uuid); \ 59 if (intf) \ 60 { \ 61 ++m_refCount; \ 62 *outObject = intf; \ 63 return SLANG_OK; \ 64 } \ 65 return SLANG_E_NO_INTERFACE; \ 66 } 67#define SLANG_COM_BASE_IUNKNOWN_ADD_REF \ 68 SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE \ 69 { \ 70 return ++m_refCount; \ 71 } 72#define SLANG_COM_BASE_IUNKNOWN_RELEASE \ 73 SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE \ 74 { \ 75 return _releaseImpl(); \ 76 } 77#define SLANG_COM_BASE_IUNKNOWN_ALL \ 78 SLANG_COM_BASE_IUNKNOWN_QUERY_INTERFACE \ 79 SLANG_COM_BASE_IUNKNOWN_ADD_REF \ 80 SLANG_COM_BASE_IUNKNOWN_RELEASE 81 82 83/// COM object that derives from RefObject 84class ComObject :public RefObject 85{ 86protected : 87std ::atomic < uint32_t > comRefCount ; 88 89public : 90ComObject () 91 :comRefCount (0 ) 92 { 93 } 94ComObject (const ComObject & rhs ) 95 :RefObject (rhs ),comRefCount (0 ) 96 { 97 } 98 99ComObject & operator = (const ComObject & ) {return * this ; } 100 101virtual void comFree () {} 102 103uint32_t addRefImpl () 104 { 105 autooldRefCount = comRefCount ++ ; 106if (oldRefCount == 0 ) 107addReference (); 108return oldRefCount + 1 ; 109} 110 111uint32_t releaseImpl () 112{ 113auto oldRefCount = comRefCount -- ; 114if (oldRefCount == 1 ) 115{ 116comFree (); 117releaseReference (); 118} 119return oldRefCount - 1 ; 120} 121}; 122 123#define SLANG_COM_OBJECT_IUNKNOWN_QUERY_INTERFACE \ 124SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) \ 125SLANG_OVERRIDE \ 126{ \ 127void* intf = getInterface(uuid); \ 128if (intf) \ 129{ \ 130addRef(); \ 131*outObject = intf; \ 132return SLANG_OK; \ 133} \ 134return SLANG_E_NO_INTERFACE; \ 135} 136#define SLANG_COM_OBJECT_IUNKNOWN_ADD_REF \ 137SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE \ 138{ \ 139return addRefImpl(); \ 140} 141#define SLANG_COM_OBJECT_IUNKNOWN_RELEASE \ 142SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE \ 143{ \ 144return releaseImpl(); \ 145} 146#define SLANG_COM_OBJECT_IUNKNOWN_ALL \ 147SLANG_COM_OBJECT_IUNKNOWN_QUERY_INTERFACE \ 148SLANG_COM_OBJECT_IUNKNOWN_ADD_REF \ 149SLANG_COM_OBJECT_IUNKNOWN_RELEASE 150 151} // namespace Slang 152 153#endif