yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

James0124Add SLANG_OVERRIDE to SLANG_IUNKNOWN_ macros (#6864)d5220b327

master
8.1 KiB200 linesraw
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{
101    using namespace Slang;
102    // Use the largest type the honors the alignment of Guid
103    typedef uint32_t CmpType;
104    union GuidCompare
105    {
106        Guid guid;
107        CmpType data[sizeof(Guid) / sizeof(CmpType)];
108    };
109    // Type pun - so compiler can 'see' the pun and not break aliasing rules
110    const CmpType* a = reinterpret_cast<const GuidCompare&>(aIn).data;
111    const CmpType* b = reinterpret_cast<const GuidCompare&>(bIn).data;
112    // Make the guid comparison a single branch, by not using short circuit
113    return ((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{
118    return !(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
124    have ++ 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