using System; using System.Runtime.CompilerServices; using gaemstone.ECS.Utility; using static flecs_hub.flecs; namespace gaemstone.ECS; public unsafe partial struct Entity { public Entity InitComponent() { if (typeof(T).IsPrimitive) throw new ArgumentException( "Must not be primitive"); if (typeof(T).IsValueType && RuntimeHelpers.IsReferenceOrContainsReferences()) throw new ArgumentException( "Struct component must satisfy the unmanaged constraint. " + "Consider making it a class if you need to store references."); var size = typeof(T).IsValueType ? Unsafe.SizeOf() : sizeof(ReferenceHandle); var typeInfo = new ecs_type_info_t { size = size, alignment = size }; var componentDesc = new ecs_component_desc_t { entity = this, type = typeInfo }; ecs_component_init(World, &componentDesc); if (!typeof(T).IsValueType) { // Set up component hooks for proper freeing of GCHandles. // Without them, managed classes would never be garbage collected. var typeHooks = new ecs_type_hooks_t { ctor = new() { Data = new() { Pointer = &ReferenceHandle.Construct } }, dtor = new() { Data = new() { Pointer = &ReferenceHandle.Destruct } }, move = new() { Data = new() { Pointer = &ReferenceHandle.Move } }, copy = new() { Data = new() { Pointer = &ReferenceHandle.Copy } }, }; ecs_set_hooks_id(World, this, &typeHooks); } return CreateLookup(); } }