• R/O
  • SSH
  • HTTPS

eirrepo: Commit


Commit MetaInfo

Revision441 (tree)
Time2022-02-16 01:13:44
Authorquiret

Log Message

- added some more unit tests for DTS + fixed bugs

Change Summary

Incremental Difference

--- common/sdk/DynamicTypeSystem.h (revision 440)
+++ common/sdk/DynamicTypeSystem.h (revision 441)
@@ -292,19 +292,19 @@
292292
293293 typedef ptrdiff_t pluginOffset_t;
294294
295- inline pluginDescriptor( void )
295+ inline pluginDescriptor( void ) noexcept
296296 {
297297 this->pluginId = DynamicTypeSystem::ANONYMOUS_PLUGIN_ID;
298298 this->typeInfo = nullptr;
299299 }
300300
301- inline pluginDescriptor( typeInfoBase *typeInfo )
301+ inline pluginDescriptor( typeInfoBase *typeInfo ) noexcept
302302 {
303303 this->pluginId = DynamicTypeSystem::ANONYMOUS_PLUGIN_ID;
304304 this->typeInfo = typeInfo;
305305 }
306306
307- inline pluginDescriptor( unsigned int id, typeInfoBase *typeInfo )
307+ inline pluginDescriptor( unsigned int id, typeInfoBase *typeInfo ) noexcept
308308 {
309309 this->pluginId = id;
310310 this->typeInfo = typeInfo;
@@ -408,8 +408,9 @@
408408 return typeInfo->typeSys;
409409 }
410410
411- // Function to get the offset of a plugin struct on an object of a specific type.
411+ // Function to get the plugin memory offset on an object of a specific type.
412412 // The offset should be added to the GenericRTTI pointer to receive the memory buffer.
413+ // Undefined behaviour if there is no memory buffer for the plugins.
413414 AINLINE static pluginOffset_t GetTypeInfoStructOffset( systemPointer_t *sysPtr, GenericRTTI *rtObj, typeInfoBase *offsetInfo )
414415 {
415416 // This method is thread safe, because every operation is based on immutable data or is atomic already.
@@ -609,7 +610,7 @@
609610 tInfo->tInterface = tInterface;
610611 tInfo->inheritsFrom = nullptr;
611612 tInfo->typeLock = lockProvider.CreateLock();
612- LIST_INSERT( registeredTypes.root, tInfo->node );
613+ LIST_APPEND( registeredTypes.root, tInfo->node );
613614
614615 // Set inheritance.
615616 try
@@ -699,7 +700,7 @@
699700 return tInfo;
700701 }
701702
702- template <DTSUsableType structType>
703+ template <typename structType>
703704 inline typeInfoBase* RegisterAbstractType( const char *typeName, typeInfoBase *inheritsFrom = nullptr )
704705 {
705706 struct structTypeInterface : public typeInterface
@@ -726,17 +727,17 @@
726727
727728 void CopyAssign( void *mem, const void *srcMem ) const override
728729 {
729- exceptMan::throw_undefined_method( eir::eMethodType::COPY_ASSIGNMENT );
730+ exceptMan::throw_abstraction_construction();
730731 }
731732
732733 void MoveAssign( void *mem, void *srcMem ) const override
733734 {
734- exceptMan::throw_undefined_method( eir::eMethodType::MOVE_ASSIGNMENT );
735+ exceptMan::throw_abstraction_construction();
735736 }
736737
737738 size_t GetTypeSize( systemPointer_t *sysPtr, void *construct_params ) const noexcept override
738739 {
739- return sizeof( structType );
740+ return (size_t)0;
740741 }
741742
742743 size_t GetTypeSizeByObject( systemPointer_t *sysPtr, const void *langObj ) const noexcept override
@@ -746,7 +747,7 @@
746747
747748 size_t GetTypeAlignment( systemPointer_t *sysPtr ) const noexcept override
748749 {
749- return alignof( structType );
750+ return 1;
750751 }
751752 };
752753
@@ -901,8 +902,8 @@
901902 }
902903
903904 // THREAD-SAFEty cannot be guarranteed. Use with caution.
904- template <SPCFClassType classType, typename staticRegistry>
905- inline pluginOffset_t StaticPluginRegistryRegisterTypeConstruction( staticRegistry& registry, typeInfoBase *typeInfo, systemPointer_t *sysPtr, void *construction_params = nullptr )
905+ template <DTSUsableType classType, typename staticRegistry>
906+ inline typename staticRegistry::pluginOffset_t StaticPluginRegistryRegisterTypeConstruction( staticRegistry& registry, typeInfoBase *typeInfo, systemPointer_t *sysPtr, void *construction_params = nullptr )
906907 {
907908 struct structPluginInterface : staticRegistry::pluginInterface
908909 {
@@ -927,22 +928,24 @@
927928 // Construct the type.
928929 GenericRTTI *rtObj = typeSys->ConstructPlacement( sysPtr, structMem, typeInfo, construction_params );
929930
930- // Hack: tell it about the struct.
931- if ( rtObj != nullptr )
931+ if constexpr ( DependantInitializableStructType <classType, typename staticRegistry::hostType_t> )
932932 {
933- size_t typeAlignment = typeInfo->tInterface->GetTypeAlignment( sysPtr );
933+ if ( rtObj != nullptr )
934+ {
935+ size_t typeAlignment = typeInfo->tInterface->GetTypeAlignment( sysPtr );
934936
935- void *langObj = DynamicTypeSystem::GetObjectFromTypeStruct( rtObj, typeAlignment );
937+ void *langObj = DynamicTypeSystem::GetObjectFromTypeStruct( rtObj, typeAlignment );
936938
937- try
938- {
939- ((classType*)langObj)->Initialize( obj );
940- }
941- catch( ... )
942- {
943- typeSys->DestroyPlacement( sysPtr, rtObj );
939+ try
940+ {
941+ ((classType*)langObj)->Initialize( obj );
942+ }
943+ catch( ... )
944+ {
945+ typeSys->DestroyPlacement( sysPtr, rtObj );
944946
945- throw;
947+ throw;
948+ }
946949 }
947950 }
948951
@@ -964,7 +967,7 @@
964967 void *langObj = GetObjectMemoryFromAllocation( objMem, typeAlignment );
965968 GenericRTTI *rtObj = GetTypeStructFromObject( langObj );
966969
967- // Hack: deinitialize the class.
970+ if constexpr ( DependantShutdownableStructType <classType, typename staticRegistry::hostType_t> )
968971 {
969972 ((classType*)langObj)->Shutdown( obj );
970973 }
@@ -1042,9 +1045,12 @@
10421045
10431046 try
10441047 {
1048+ size_t align;
1049+ size_t objsize = this->GetTypeStructSize( sysPtr, typeInfo, construction_params, align );
1050+
10451051 offset = registry.RegisterPlugin(
1046- this->GetTypeStructSize( sysPtr, typeInfo, construction_params ),
1047- alignof( classType ),
1052+ objsize,
1053+ align,
10481054 typename staticRegistry::pluginDescriptor( staticRegistry::ANONYMOUS_PLUGIN_ID ),
10491055 tInterface
10501056 );
@@ -1462,6 +1468,11 @@
14621468 return objMemSize;
14631469 }
14641470
1471+ inline bool DoesTypeInfoBelongTo( typeInfoBase *typeInfo ) const noexcept
1472+ {
1473+ return ( typeInfo->typeSys == this );
1474+ }
1475+
14651476 // THREAD-SAFE, because it establishes a write context.
14661477 inline void ReferenceTypeInfo( typeInfoBase *typeInfo )
14671478 {
--- unittests/src/dynamictypesystem.cpp (revision 440)
+++ unittests/src/dynamictypesystem.cpp (revision 441)
@@ -1,6 +1,7 @@
11 #include <sdk/MemoryUtils.h>
22 #include <sdk/MemoryUtils.stream.h>
33 #include <sdk/DynamicTypeSystem.h>
4+#include <sdk/PluginFactory.h>
45
56 #include <sdk/rwlist.hpp>
67 #include <sdk/OSUtils.memheap.h>
@@ -41,9 +42,13 @@
4142 decltype(dts1)::typeInfoBase *theType = dts1.RegisterStructType <obj> ( "obj" );
4243
4344 assert( theType != nullptr );
45+ assert( dts1.DoesTypeInfoBelongTo( theType ) == true );
4446
4547 DynamicTypeSystem <CRTHeapAllocator, void> dts2( std::move( dts1 ) );
4648
49+ assert( dts1.DoesTypeInfoBelongTo( theType ) == false );
50+ assert( dts2.DoesTypeInfoBelongTo( theType ) == true );
51+
4752 dts2.DeleteType( theType );
4853 }
4954 printf( "ok.\n" );
@@ -66,19 +71,250 @@
6671 }
6772 printf( "ok.\n" );
6873
74+ printf( "testing DTS GetTypeInfoFromTypeStruct..." );
75+ {
76+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
77+
78+ decltype(dts)::typeInfoBase *type = dts.RegisterStructType <int> ( "int" );
79+
80+ assert( type != nullptr );
81+
82+ GenericRTTI *obj = dts.Construct( nullptr, type, nullptr );
83+
84+ assert( obj != nullptr );
85+ assert( type == decltype(dts)::GetTypeInfoFromTypeStruct( obj ) );
86+
87+ dts.Destroy( nullptr, obj );
88+ }
89+ printf( "ok.\n" );
90+
91+ printf( "testing DTS GetTypeSystemFromTypeInfo..." );
92+ {
93+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
94+
95+ decltype(dts)::typeInfoBase *type = dts.RegisterStructType <int> ( "int" );
96+
97+ assert( type != nullptr );
98+ assert( decltype(dts)::GetTypeSystemFromTypeInfo( type ) == &dts );
99+ }
100+ printf( "ok.\n" );
101+
102+ printf( "testing DTS GetTypeInfoStructOffset..." );
103+ {
104+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
105+
106+ decltype(dts)::typeInfoBase *type = dts.RegisterStructType <int> ( "int" );
107+
108+ assert( type != nullptr );
109+
110+ struct alignas(char) basicplg
111+ {};
112+
113+ dts.RegisterStructPlugin <basicplg> ( type );
114+
115+ GenericRTTI *obj = dts.Construct( nullptr, type, nullptr );
116+
117+ assert( obj != nullptr );
118+
119+ size_t off = decltype(dts)::GetTypeInfoStructOffset( nullptr, obj, type );
120+
121+ assert( (char*)obj + off == (char*)decltype(dts)::GetObjectFromTypeStruct( obj, alignof(int) ) + sizeof(int) );
122+
123+ dts.Destroy( nullptr, obj );
124+ }
125+ printf( "ok.\n" );
126+
127+ printf( "testing DTS IsOffsetValid..." );
128+ {
129+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
130+
131+ assert( decltype(dts)::IsOffsetValid( decltype(dts)::INVALID_PLUGIN_OFFSET ) == false );
132+ assert( decltype(dts)::IsOffsetValid( 0 ) == true );
133+ }
134+ printf( "ok.\n" );
135+
136+ printf( "testing DTS RESOLVE_STRUCT..." );
137+ {
138+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
139+
140+ struct plg
141+ {
142+ char meow = 2;
143+ };
144+
145+ decltype(dts)::typeInfoBase *type = dts.RegisterStructType <int> ( "int" );
146+
147+ assert( type != nullptr );
148+
149+ decltype(dts)::pluginOffset_t plgoff = dts.RegisterStructPlugin <plg> ( type );
150+
151+ assert( decltype(dts)::IsOffsetValid( plgoff ) == true );
152+
153+ GenericRTTI *obj = dts.Construct( nullptr, type, nullptr );
154+
155+ assert( obj != nullptr );
156+ assert( decltype(dts)::RESOLVE_STRUCT <plg> ( nullptr, obj, type, plgoff ) != nullptr );
157+
158+ dts.Destroy( nullptr, obj );
159+ }
160+ printf( "ok.\n" );
161+
162+ printf( "testing DTS RegisterPlugin (minimal)..." );
163+ {
164+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
165+
166+ decltype(dts)::typeInfoBase *type = dts.RegisterStructType <int> ( "int" );
167+
168+ struct nullplg : decltype(dts)::pluginInterface
169+ {
170+ };
171+
172+ nullplg plginfo;
173+
174+ auto plgoff = dts.RegisterPlugin( 1, 1, type, &plginfo );
175+
176+ assert( decltype(dts)::IsOffsetValid( plgoff ) == true );
177+ }
178+ printf( "ok.\n" );
179+
180+ printf( "testing DTS RegisterCustomPlugin..." );
181+ {
182+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
183+
184+ decltype(dts)::typeInfoBase *type = dts.RegisterStructType <int> ( "int" );
185+
186+ struct nullplg : decltype(dts)::pluginInterface
187+ {};
188+
189+ auto plgoff = dts.RegisterCustomPlugin <nullplg> ( 1, 1, type );
190+
191+ assert( decltype(dts)::IsOffsetValid( plgoff ) == true );
192+ }
193+ printf( "ok.\n" );
194+
195+ printf( "testing DTS RegisterStructPlugin..." );
196+ {
197+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
198+
199+ decltype(dts)::typeInfoBase *type = dts.RegisterStructType <int> ( "int" );
200+
201+ assert( type != nullptr );
202+
203+ decltype(dts)::pluginOffset_t plgoff = dts.RegisterStructPlugin <bool> ( type );
204+
205+ assert( decltype(dts)::IsOffsetValid( plgoff ) == true );
206+ }
207+ printf( "ok.\n" );
208+
209+ printf( "testing DTS RegisterDependantStructPlugin..." );
210+ {
211+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
212+
213+ decltype(dts)::typeInfoBase *type = dts.RegisterStructType <int> ( "int" );
214+
215+ assert( type != nullptr );
216+
217+ struct depstruct
218+ {
219+ inline void Initialize( GenericRTTI *rtobj )
220+ {
221+ return;
222+ }
223+
224+ inline void Shutdown( GenericRTTI *rtobj )
225+ {
226+ return;
227+ }
228+ };
229+
230+ decltype(dts)::pluginOffset_t plgoff = dts.RegisterDependantStructPlugin <depstruct> ( type );
231+
232+ assert( decltype(dts)::IsOffsetValid( plgoff ) == true );
233+ }
234+ printf( "ok.\n" );
235+
236+ printf( "testing DTS RegisterAbstractType..." );
237+ {
238+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
239+
240+ decltype(dts)::typeInfoBase *type = dts.RegisterAbstractType <void> ( "void" );
241+
242+ assert( type != nullptr );
243+ }
244+ printf( "ok.\n" );
245+
246+ printf( "testing DTS RegisterStructType..." );
247+ {
248+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
249+
250+ decltype(dts)::typeInfoBase *type = dts.RegisterStructType <int> ( "int" );
251+
252+ assert( type != nullptr );
253+ }
254+ printf( "ok.\n" );
255+
256+ printf( "testing DTS StaticPluginRegistryRegisterTypeConstruction..." );
257+ {
258+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
259+
260+ decltype(dts)::typeInfoBase *type = dts.RegisterStructType <int> ( "int" );
261+
262+ StaticPluginClassFactory <int, CRTHeapAllocator> fact;
263+
264+ decltype(fact)::pluginOffset_t plgoff = dts.StaticPluginRegistryRegisterTypeConstruction <int> ( fact, type, nullptr, nullptr );
265+
266+ assert( decltype(fact)::IsOffsetValid( plgoff ) == true );
267+ }
268+ printf( "ok.\n" );
269+
270+ printf( "testing DTS RegisterDynamicStructType..." );
271+ {
272+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
273+
274+ struct dyntypeinfo : public decltype(dts)::structTypeMetaInfo
275+ {
276+ size_t GetTypeSize( void *sysPtr, void *cparams ) const noexcept override
277+ {
278+ return 1;
279+ }
280+
281+ size_t GetTypeSizeByObject( void *sysPtr, const void *obj ) const noexcept override
282+ {
283+ return 1;
284+ }
285+
286+ size_t GetTypeAlignment( void *sysPtr ) const noexcept override
287+ {
288+ return 1;
289+ }
290+ };
291+
292+ dyntypeinfo dinfo;
293+
294+ decltype(dts)::typeInfoBase *type = dts.RegisterDynamicStructType <int> ( "dyn_int", &dinfo, false );
295+
296+ assert( type != nullptr );
297+ }
298+ printf( "ok.\n" );
299+
69300 // Some object to test DTS with.
70301 struct testObject
71302 {
72- inline testObject( void *sysPtr, void *cparams )
303+ inline testObject( void *sysPtr, void *cparams ) noexcept
73304 {
74305 return;
75306 }
76307
77- inline testObject( const testObject& right )
308+ inline testObject( const testObject& right ) noexcept
78309 {
79310 this->copied = true;
80311 }
81312
313+ inline testObject( testObject&& right ) noexcept
314+ {
315+ this->moved = true;
316+ }
317+
82318 inline ~testObject( void )
83319 {
84320 return;
@@ -85,6 +321,7 @@
85321 }
86322
87323 bool copied = false;
324+ bool moved = false;
88325 };
89326
90327 printf( "testing DTS object register..." );
@@ -337,4 +574,77 @@
337574 dts.typeSystem.Destroy( nullptr, obj );
338575 }
339576 printf( "ok.\n" );
577+
578+ printf( "testing DTS type iteration..." );
579+ {
580+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
581+
582+ decltype( dts )::typeInfoBase *first = dts.RegisterStructType <int> ( "int" );
583+ decltype( dts )::typeInfoBase *second = dts.RegisterStructType <bool> ( "bool" );
584+ decltype( dts )::typeInfoBase *third = dts.RegisterStructType <float> ( "float" );
585+
586+ decltype(dts)::type_iterator iter = dts.GetTypeIterator();
587+
588+ size_t idx = 0;
589+
590+ while ( !iter.IsEnd() )
591+ {
592+ decltype(dts)::typeInfoBase *type = iter.Resolve();
593+
594+ if ( idx == 0 )
595+ {
596+ assert( type == first );
597+ }
598+ else if ( idx == 1 )
599+ {
600+ assert( type == second );
601+ }
602+ else if ( idx == 2 )
603+ {
604+ assert( type == third );
605+ }
606+ else
607+ {
608+ assert( 0 );
609+ }
610+
611+ idx++;
612+
613+ iter.Increment();
614+ }
615+ }
616+ printf( "ok.\n" );
617+
618+ printf( "testing DTS FindTypeInfo..." );
619+ {
620+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
621+
622+ decltype(dts)::typeInfoBase *type = dts.RegisterStructType <int> ( "int" );
623+
624+ assert( type != nullptr );
625+ assert( type == dts.FindTypeInfo( "int", nullptr ) );
626+ }
627+ printf( "ok.\n" );
628+
629+ printf( "testing DTS ResolveTypeInfo..." );
630+ {
631+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
632+
633+ decltype(dts)::typeInfoBase *type = dts.RegisterStructType <int> ( "int" );
634+
635+ assert( type != nullptr );
636+ assert( type == dts.ResolveTypeInfo( "int" ) );
637+ }
638+ printf( "ok.\n" );
639+
640+ printf( "testing DTS MakeTypeInfoFullName..." );
641+ {
642+ DynamicTypeSystem <CRTHeapAllocator, void> dts;
643+
644+ decltype(dts)::typeInfoBase *type = dts.RegisterStructType <int> ( "int" );
645+
646+ assert( type != nullptr );
647+ assert( dts.MakeTypeInfoFullName <CRTHeapAllocator> ( type ) == "int" );
648+ }
649+ printf( "ok.\n" );
340650 }
Show on old repository browser