yum-mirror/slang

Making it easier to work with shaders

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

Julius IkkalaReplace SLANG_ALIGN_OF with C++11 alignof (#7523)551d0c365

master
7.2 KiB257 linesraw
1#include "slang-rtti-info.h"
2
3#include "slang-com-helper.h"
4#include "slang-rtti-util.h"
5
6#include <mutex>
7
8namespace Slang
9{
10
11#define SLANG_RTTI_INFO_INVALID(name) \
12    RttiInfo                          \
13    {                                 \
14        RttiInfo::Kind::Invalid, 0, 0 \
15    }
16#define SLANG_RTTI_INFO_BASIC(name, type)                             \
17    RttiInfo                                                          \
18    {                                                                 \
19        RttiInfo::Kind::name, RttiInfo::AlignmentType(alignof(type)), \
20            RttiInfo::SizeType(sizeof(type))                          \
21    }
22
23/* static */ const RttiInfo RttiInfo::g_basicTypes[Index(Kind::CountOf)] = {
24    SLANG_RTTI_INFO_INVALID(Invalid),
25    SLANG_RTTI_INFO_BASIC(I32, int32_t),
26    SLANG_RTTI_INFO_BASIC(U32, uint32_t),
27    SLANG_RTTI_INFO_BASIC(I64, int64_t),
28    SLANG_RTTI_INFO_BASIC(U64, uint64_t),
29    SLANG_RTTI_INFO_BASIC(F32, float),
30    SLANG_RTTI_INFO_BASIC(F64, double),
31    SLANG_RTTI_INFO_BASIC(Bool, bool),
32    SLANG_RTTI_INFO_BASIC(String, String),
33    SLANG_RTTI_INFO_BASIC(UnownedStringSlice, UnownedStringSlice),
34    SLANG_RTTI_INFO_BASIC(Ptr, void*),
35    SLANG_RTTI_INFO_BASIC(RefPtr, RefPtr<StringRepresentation>),
36    SLANG_RTTI_INFO_INVALID(FixedArray),
37    SLANG_RTTI_INFO_INVALID(Struct),
38    SLANG_RTTI_INFO_INVALID(Other),
39    SLANG_RTTI_INFO_INVALID(Enum),
40    SLANG_RTTI_INFO_INVALID(List),
41    SLANG_RTTI_INFO_INVALID(Dictionary),
42};
43
44struct RttiInfoManager
45{
46    void* allocate(size_t size)
47    {
48        std::lock_guard<std::recursive_mutex> guard(m_mutex);
49        return m_arena.allocate(size);
50    }
51    void deallocateAll()
52    {
53        std::lock_guard<std::recursive_mutex> guard(m_mutex);
54        m_arena.reset();
55    }
56
57    static RttiInfoManager& getSingleton()
58    {
59        static RttiInfoManager g_manager;
60        return g_manager;
61    }
62
63protected:
64    RttiInfoManager()
65        : m_arena(1024)
66    {
67    }
68
69    std::recursive_mutex m_mutex; ///< We need a mutex to guard access to m_arena
70    MemoryArena m_arena;
71};
72
73/* static */ void* RttiInfo::allocate(size_t size)
74{
75    return RttiInfoManager::getSingleton().allocate(size);
76}
77
78/* static */ void RttiInfo::deallocateAll()
79{
80    return RttiInfoManager::getSingleton().deallocateAll();
81}
82
83/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StructRttiBuilder !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
84 */
85
86static void _appendFixedArray(const FixedArrayRttiInfo* inFixedArray, StringBuilder& out)
87{
88    List<const FixedArrayRttiInfo*> fixedArrays;
89    fixedArrays.add(inFixedArray);
90
91    const RttiInfo* cur = inFixedArray->m_elementType;
92    while (cur->m_kind == RttiInfo::Kind::FixedArray)
93    {
94        const FixedArrayRttiInfo* curArray = static_cast<const FixedArrayRttiInfo*>(cur);
95        fixedArrays.add(curArray);
96        cur = curArray->m_elementType;
97    }
98
99    // Append the 'target' which is in cur
100    RttiInfo::append(cur, out);
101    // Now all the fixed array values, in order
102    for (auto fixedArray : fixedArrays)
103    {
104        out << "[" << int32_t(fixedArray->m_elementCount) << "]";
105    }
106}
107
108/* static */ void RttiInfo::append(const RttiInfo* info, StringBuilder& out)
109{
110    switch (info->m_kind)
111    {
112    case RttiInfo::Kind::I32:
113        out << "int32_t";
114        break;
115    case RttiInfo::Kind::U32:
116        out << "uint32_t";
117        break;
118    case RttiInfo::Kind::I64:
119        out << "int64_t";
120        break;
121    case RttiInfo::Kind::U64:
122        out << "uint64_t";
123        break;
124    case RttiInfo::Kind::F32:
125        out << "float";
126        break;
127    case RttiInfo::Kind::F64:
128        out << "double";
129        break;
130    case RttiInfo::Kind::Bool:
131        out << "bool";
132        break;
133    case RttiInfo::Kind::String:
134        out << "String";
135        break;
136    case RttiInfo::Kind::UnownedStringSlice:
137        out << "UnownedStringSlice";
138        break;
139    case RttiInfo::Kind::Ptr:
140        {
141            const PtrRttiInfo* ptrRttiInfo = static_cast<const PtrRttiInfo*>(info);
142            append(ptrRttiInfo->m_targetType, out);
143            out << "*";
144            break;
145        }
146    case RttiInfo::Kind::RefPtr:
147        {
148            const RefPtrRttiInfo* ptrRttiInfo = static_cast<const RefPtrRttiInfo*>(info);
149            out << "RefPtr<";
150            append(ptrRttiInfo->m_targetType, out);
151            out << ">";
152            break;
153        }
154    case RttiInfo::Kind::FixedArray:
155        {
156            const FixedArrayRttiInfo* arrayRttiInfo = static_cast<const FixedArrayRttiInfo*>(info);
157            _appendFixedArray(arrayRttiInfo, out);
158            break;
159        }
160    case RttiInfo::Kind::List:
161        {
162            const ListRttiInfo* listRttiInfo = static_cast<const ListRttiInfo*>(info);
163            out << "List<";
164            append(listRttiInfo->m_elementType, out);
165            out << ">";
166            break;
167        }
168    case RttiInfo::Kind::Dictionary:
169        {
170            const DictionaryRttiInfo* dictionaryRttiInfo =
171                static_cast<const DictionaryRttiInfo*>(info);
172
173            out << "Dictionary<";
174            append(dictionaryRttiInfo->m_keyType, out);
175            out << ",";
176            append(dictionaryRttiInfo->m_valueType, out);
177            out << ">";
178            break;
179        }
180    default:
181        {
182            if (info->isNamed())
183            {
184                const NamedRttiInfo* namedRttiInfo = static_cast<const NamedRttiInfo*>(info);
185                out << namedRttiInfo->m_name;
186                break;
187            }
188
189            out << "%Unknown%";
190            break;
191        }
192    }
193}
194
195/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StructRttiBuilder !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
196 */
197
198void StructRttiBuilder::_init(const char* name, const StructRttiInfo* super, const Byte* base)
199{
200    m_rttiInfo.m_name = name;
201    m_rttiInfo.m_super = super;
202    m_base = base;
203
204    m_rttiInfo.m_fieldCount = 0;
205    m_rttiInfo.m_fields = nullptr;
206}
207
208StructRttiInfo StructRttiBuilder::make()
209{
210    const Index fieldCount = m_fields.getCount();
211
212    if (fieldCount)
213    {
214        StructRttiInfo::Field* dstFields =
215            (StructRttiInfo::Field*)RttiInfo::allocate(sizeof(StructRttiInfo::Field) * fieldCount);
216        ::memcpy(dstFields, m_fields.getBuffer(), sizeof(StructRttiInfo::Field) * fieldCount);
217
218        m_rttiInfo.m_fields = dstFields;
219        m_rttiInfo.m_fieldCount = fieldCount;
220    }
221
222    return m_rttiInfo;
223}
224
225/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RttiTypeFuncsMap !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
226 */
227
228RttiTypeFuncs RttiTypeFuncsMap::getFuncsForType(const RttiInfo* rttiInfo)
229{
230    if (auto funcsPtr = m_map.tryGetValue(rttiInfo))
231    {
232        return *funcsPtr;
233    }
234
235    // Try to get the default impl
236    // NOTE! funcs could be invalid if there is no default impl.
237    const auto funcs = RttiUtil::getDefaultTypeFuncs(rttiInfo);
238
239    // Add to the map
240    m_map.add(rttiInfo, funcs);
241    return funcs;
242}
243
244void RttiTypeFuncsMap::add(const RttiInfo* rttiInfo, const RttiTypeFuncs& funcs)
245{
246    if (auto funcsPtr = m_map.tryGetValueOrAdd(rttiInfo, funcs))
247    {
248        // If there are funcs set, they aren't valid otherwise this would be
249        // replacing, so assert on that scenario.
250        SLANG_ASSERT(!funcsPtr->isValid());
251
252        // Replace the funcs
253        *funcsPtr = funcs;
254    }
255}
256
257} // namespace Slang