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