diff --git a/src/gaemstone/ECS/EntityBase.cs b/src/gaemstone/ECS/EntityBase.cs index 3935e2d..8e44624 100644 --- a/src/gaemstone/ECS/EntityBase.cs +++ b/src/gaemstone/ECS/EntityBase.cs @@ -13,7 +13,9 @@ public abstract class EntityBase public abstract T Get(); public abstract T? MaybeGet() where T : unmanaged; public abstract T? MaybeGet(T _ = null!) where T : class; - public abstract ref T GetRef() where T : unmanaged; + public abstract ref T GetMut() where T : unmanaged; + public abstract ref T GetRefOrNull() where T : unmanaged; + public abstract ref T GetRefOrThrow() where T : unmanaged; public abstract void Modified(); public abstract TReturn Set(in T value) where T : unmanaged; diff --git a/src/gaemstone/ECS/EntityBuilder.cs b/src/gaemstone/ECS/EntityBuilder.cs index bb1b715..13efe7b 100644 --- a/src/gaemstone/ECS/EntityBuilder.cs +++ b/src/gaemstone/ECS/EntityBuilder.cs @@ -70,7 +70,9 @@ public class EntityBuilder public override T Get() => throw new NotSupportedException(); public override T? MaybeGet() => throw new NotSupportedException(); public override T? MaybeGet(T _ = null!) where T : class => throw new NotSupportedException(); - public override ref T GetRef() => throw new NotSupportedException(); + public override ref T GetMut() => throw new NotSupportedException(); + public override ref T GetRefOrNull() => throw new NotSupportedException(); + public override ref T GetRefOrThrow() => throw new NotSupportedException(); public override void Modified() => throw new NotImplementedException(); public override EntityBuilder Set(in T value) diff --git a/src/gaemstone/ECS/EntityRef.cs b/src/gaemstone/ECS/EntityRef.cs index 0da0650..60a6ca1 100644 --- a/src/gaemstone/ECS/EntityRef.cs +++ b/src/gaemstone/ECS/EntityRef.cs @@ -81,11 +81,27 @@ public unsafe sealed class EntityRef return (ptr != null) ? (T)((GCHandle)Unsafe.Read(ptr)).Target! : null; } - public override ref T GetRef() + public override ref T GetRefOrNull() + { + var comp = Universe.LookupOrThrow(); + var @ref = ecs_ref_init_id(Universe, this, comp); + var ptr = ecs_ref_get_id(Universe, &@ref, comp); + return ref (ptr != null) ? ref Unsafe.AsRef(ptr) : ref Unsafe.NullRef(); + } + + public override ref T GetRefOrThrow() + { + ref var ptr = ref GetRefOrNull(); + if (Unsafe.IsNullRef(ref ptr)) throw new Exception( + $"Component {typeof(T)} not found on {this}"); + return ref ptr; + } + + public override ref T GetMut() { var comp = Universe.LookupOrThrow(); var ptr = ecs_get_mut_id(Universe, this, comp); - if (ptr == null) throw new Exception($"Component {typeof(T)} not found on {this}"); + // NOTE: Value is added if it doesn't exist on the entity. return ref Unsafe.AsRef(ptr); }