yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
d5220b327
master
1#ifndef SLANG_COM_HELPER_H 2#define SLANG_COM_HELPER_H 3 4/** \file slang-com-helper.h 5*/ 6 7#include "slang.h" 8 9#include <atomic> 10 11/* !!!!!!!!!!!!!!!!!!!!! Macros to help checking SlangResult !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ 12 13/*! Set SLANG_HANDLE_RESULT_FAIL(x) to code to be executed whenever an error occurs, and is detected 14* by one of the macros */ 15#ifndef SLANG_HANDLE_RESULT_FAIL 16#define SLANG_HANDLE_RESULT_FAIL (x ) 17#endif 18 19//! Helper macro, that makes it easy to add result checking to calls in functions/methods that 20//! themselves return Result. 21#define SLANG_RETURN_ON_FAIL (x ) \ 22 { \ 23 SlangResult _res = (x); \ 24 if (SLANG_FAILED(_res)) \ 25 { \ 26 SLANG_HANDLE_RESULT_FAIL(_res); \ 27 return _res; \ 28 } \ 29 } 30//! Helper macro that can be used to test the return value from a call, and will return in a void 31//! method/function 32#define SLANG_RETURN_VOID_ON_FAIL (x ) \ 33 { \ 34 SlangResult _res = (x); \ 35 if (SLANG_FAILED(_res)) \ 36 { \ 37 SLANG_HANDLE_RESULT_FAIL(_res); \ 38 return; \ 39 } \ 40 } 41//! Helper macro that will return false on failure. 42#define SLANG_RETURN_FALSE_ON_FAIL (x ) \ 43 { \ 44 SlangResult _res = (x); \ 45 if (SLANG_FAILED(_res)) \ 46 { \ 47 SLANG_HANDLE_RESULT_FAIL(_res); \ 48 return false; \ 49 } \ 50 } 51//! Helper macro that will return nullptr on failure. 52#define SLANG_RETURN_NULL_ON_FAIL (x ) \ 53 { \ 54 SlangResult _res = (x); \ 55 if (SLANG_FAILED(_res)) \ 56 { \ 57 SLANG_HANDLE_RESULT_FAIL(_res); \ 58 return nullptr; \ 59 } \ 60 } 61 62//! Helper macro that will assert if the return code from a call is failure, also returns the 63//! failure. 64#define SLANG_ASSERT_ON_FAIL (x ) \ 65 { \ 66 SlangResult _res = (x); \ 67 if (SLANG_FAILED(_res)) \ 68 { \ 69 assert(false); \ 70 return _res; \ 71 } \ 72 } 73//! Helper macro that will assert if the result from a call is a failure, also returns. 74#define SLANG_ASSERT_VOID_ON_FAIL (x ) \ 75 { \ 76 SlangResult _res = (x); \ 77 if (SLANG_FAILED(_res)) \ 78 { \ 79 assert(false); \ 80 return; \ 81 } \ 82 } 83 84/* !!!!!!!!!!!!!!!!!!!!!!! C++ helpers !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ 85 86#if defined(__cplusplus ) 87namespace Slang 88{ 89 90// Alias SlangResult to Slang::Result 91typedef SlangResult Result ; 92// Alias SlangUUID to Slang::Guid 93typedef SlangUUID Guid ; 94 95}// namespace Slang 96 97// Operator == and != for Guid/SlangUUID 98 99SLANG_FORCE_INLINE bool operator == (const Slang ::Guid & aIn ,const Slang ::Guid & bIn ) 100{ 101using namespace Slang ; 102// Use the largest type the honors the alignment of Guid 103typedef uint32_t CmpType ; 104union GuidCompare 105 { 106Guid guid ; 107CmpType data [sizeof (Guid ) /sizeof (CmpType )]; 108 }; 109// Type pun - so compiler can 'see' the pun and not break aliasing rules 110const CmpType * a = reinterpret_cast < const GuidCompare &> (aIn ).data ; 111const CmpType * b = reinterpret_cast < const GuidCompare &> (bIn ).data ; 112// Make the guid comparison a single branch, by not using short circuit 113return ((a [0 ] ^b [0 ]) | (a [1 ] ^b [1 ]) | (a [2 ] ^b [2 ]) | (a [3 ] ^b [3 ]))== 0 ; 114} 115 116SLANG_FORCE_INLINE bool operator != (const Slang ::Guid & a ,const Slang ::Guid & b ) 117{ 118return !(a == b ); 119} 120 121/* !!!!!!!! Macros to simplify implementing COM interfaces !!!!!!!!!!!!!!!!!!!!!!!!!!!! */ 122 123/* Assumes underlying implementation has a member m_refCount that is initialized to 0 and can 124have ++ and -- operate on it. For SLANG_IUNKNOWN_QUERY_INTERFACE to work - must have a method 125'getInterface' that returns valid pointers for the Guid, or nullptr if not found. */ 126 127#define SLANG_IUNKNOWN_QUERY_INTERFACE \ 128 SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface( \ 129 SlangUUID const& uuid, \ 130 void** outObject) SLANG_OVERRIDE \ 131 { \ 132 ISlangUnknown* intf = getInterface(uuid); \ 133 if (intf) \ 134 { \ 135 addRef(); \ 136 *outObject = intf; \ 137 return SLANG_OK; \ 138 } \ 139 return SLANG_E_NO_INTERFACE; \ 140 } 141 142#define SLANG_IUNKNOWN_ADD_REF \ 143 SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE \ 144 { \ 145 return ++m_refCount; \ 146 } 147 148#define SLANG_IUNKNOWN_RELEASE \ 149 SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE \ 150 { \ 151 --m_refCount; \ 152 if (m_refCount == 0) \ 153 { \ 154 delete this; \ 155 return 0; \ 156 } \ 157 return m_refCount; \ 158 } 159 160#define SLANG_IUNKNOWN_ALL \ 161 SLANG_IUNKNOWN_QUERY_INTERFACE \ 162 SLANG_IUNKNOWN_ADD_REF \ 163 SLANG_IUNKNOWN_RELEASE 164 165// ------------------------ RefObject IUnknown ----------------------------- 166 167#define SLANG_REF_OBJECT_IUNKNOWN_QUERY_INTERFACE \ 168 SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface( \ 169 SlangUUID const& uuid, \ 170 void** outObject) SLANG_OVERRIDE \ 171 { \ 172 void* intf = getInterface(uuid); \ 173 if (intf) \ 174 { \ 175 addReference(); \ 176 *outObject = intf; \ 177 return SLANG_OK; \ 178 } \ 179 return SLANG_E_NO_INTERFACE; \ 180 } 181 182#define SLANG_REF_OBJECT_IUNKNOWN_ADD_REF \ 183 SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE \ 184 { \ 185 return (uint32_t)addReference(); \ 186 } 187#define SLANG_REF_OBJECT_IUNKNOWN_RELEASE \ 188 SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE \ 189 { \ 190 return (uint32_t)releaseReference(); \ 191 } 192 193#define SLANG_REF_OBJECT_IUNKNOWN_ALL \ 194 SLANG_REF_OBJECT_IUNKNOWN_QUERY_INTERFACE \ 195 SLANG_REF_OBJECT_IUNKNOWN_ADD_REF \ 196 SLANG_REF_OBJECT_IUNKNOWN_RELEASE 197 198#endif // defined(__cplusplus) 199 200#endif