|
|
|
using System;
|
|
|
|
using gaemstone.Utility;
|
|
|
|
using static flecs_hub.flecs;
|
|
|
|
|
|
|
|
namespace gaemstone.ECS;
|
|
|
|
|
|
|
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)]
|
|
|
|
public class ComponentAttribute : EntityAttribute
|
|
|
|
{
|
|
|
|
public ComponentAttribute() { }
|
|
|
|
public ComponentAttribute(params string[] path) : base(path) { }
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class ComponentExtensions
|
|
|
|
{
|
|
|
|
public unsafe static EntityRef CreateComponent<T>(this EntityRef entity)
|
|
|
|
=> entity.CreateComponent(typeof(T));
|
|
|
|
public unsafe static EntityRef CreateComponent(this EntityRef entity, Type type)
|
|
|
|
{
|
|
|
|
// TODO: Do some additional sanity checking for this type.
|
|
|
|
|
|
|
|
var typeInfo = default(ecs_type_info_t);
|
|
|
|
if (type.IsPrimitive) throw new ArgumentException(
|
|
|
|
"Must not be primitive", nameof(type));
|
|
|
|
var wrapper = TypeWrapper.For(type);
|
|
|
|
if (type.IsValueType && !wrapper.IsUnmanaged) throw new Exception(
|
|
|
|
"Struct component must satisfy the unmanaged constraint. " +
|
|
|
|
"Consider making it a class if you need to store references.");
|
|
|
|
typeInfo.size = wrapper.Size;
|
|
|
|
typeInfo.alignment = wrapper.Size;
|
|
|
|
|
|
|
|
var desc = new ecs_component_desc_t { entity = entity, type = typeInfo };
|
|
|
|
ecs_component_init(entity.Universe, &desc);
|
|
|
|
return entity.CreateLookup(type);
|
|
|
|
}
|
|
|
|
}
|