37 lines
1.4 KiB
37 lines
1.4 KiB
using System; |
|
using System.Runtime.CompilerServices; |
|
using gaemstone.ECS.Utility; |
|
using static flecs_hub.flecs; |
|
|
|
namespace gaemstone.ECS; |
|
|
|
public unsafe partial struct Entity<TContext> |
|
{ |
|
public Entity<TContext> InitComponent<T>() |
|
{ |
|
if (typeof(T).IsPrimitive) throw new ArgumentException( |
|
"Must not be primitive"); |
|
if (typeof(T).IsValueType && RuntimeHelpers.IsReferenceOrContainsReferences<T>()) 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<T>() : 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<T>(); |
|
} |
|
}
|
|
|