Remove LookupByType and related methods

wip/no-type-lookup
copygirl 2 years ago
parent e4f3020a87
commit dc776ace1f
  1. 7
      src/gaemstone.ECS/Component.cs
  2. 25
      src/gaemstone.ECS/EntityBase.cs
  3. 2
      src/gaemstone.ECS/EntityRef.cs
  4. 8
      src/gaemstone.ECS/IdRef.cs
  5. 5
      src/gaemstone.ECS/Iterator.cs
  6. 32
      src/gaemstone.ECS/World+Lookup.cs

@ -7,11 +7,6 @@ namespace gaemstone.ECS;
public static unsafe class ComponentExtensions
{
public static EntityRef InitComponent(this EntityRef entity, Type type)
=> (EntityRef)typeof(ComponentExtensions)
.GetMethod(nameof(InitComponent), new[] { typeof(EntityRef) })!
.MakeGenericMethod(type).Invoke(null, new[]{ entity })!;
public static EntityRef InitComponent<T>(this EntityRef entity)
{
if (typeof(T).IsPrimitive) throw new ArgumentException(
@ -37,7 +32,7 @@ public static unsafe class ComponentExtensions
ecs_set_hooks_id(entity.World, entity, &typeHooks);
}
return entity.CreateLookup(typeof(T));
return entity;
}
}

@ -5,29 +5,18 @@ public abstract class EntityBase<TReturn>
{
public abstract World World { get; }
public abstract TReturn Add(Id id);
public abstract TReturn Remove(Id id);
public abstract bool Has(Id id);
public TReturn Add(string symbol) => Add(World.LookupBySymbolOrThrow(symbol));
public TReturn Add<T>() => Add(World.LookupByTypeOrThrow(typeof(T)));
public TReturn Add(Entity relation, Entity target) => Add(Id.Pair(relation, target));
public TReturn Add<TRelation>(Entity target) => Add(World.LookupByTypeOrThrow<TRelation>(), target);
public TReturn Add<TRelation, TTarget>() => Add(World.LookupByTypeOrThrow<TRelation>(), World.LookupByTypeOrThrow<TTarget>());
public TReturn Remove(string symbol) => Remove(World.LookupBySymbolOrThrow(symbol));
public TReturn Remove<T>() => Remove(World.LookupByTypeOrThrow(typeof(T)));
public TReturn Remove(Entity relation, Entity target) => Remove(Id.Pair(relation, target));
public TReturn Remove<TRelation>(Entity target) => Remove(World.LookupByTypeOrThrow<TRelation>(), target);
public TReturn Remove<TRelation, TTarget>() => Remove(World.LookupByTypeOrThrow<TRelation>(), World.LookupByTypeOrThrow<TTarget>());
public bool Has(string symbol) => Has(World.LookupBySymbolOrThrow(symbol));
public bool Has<T>() => Has(World.LookupByTypeOrThrow(typeof(T)));
public bool Has(Entity relation, Entity target) => Has(Id.Pair(relation, target));
public bool Has<TRelation>(Entity target) => Has(World.LookupByTypeOrThrow<TRelation>(), target);
public bool Has<TRelation, TTarget>() => Has(World.LookupByTypeOrThrow<TRelation>(), World.LookupByTypeOrThrow<TTarget>());
public abstract T? GetOrNull<T>(Id id) where T : unmanaged;
public abstract T? GetOrNull<T>(Id id, T _ = null!) where T : class;
@ -37,24 +26,10 @@ public abstract class EntityBase<TReturn>
public abstract ref T GetRefOrThrow<T>(Id id) where T : unmanaged;
public abstract void Modified<T>(Id id);
public T? GetOrNull<T>() where T : unmanaged => GetOrNull<T>(World.LookupByTypeOrThrow<T>());
public T? GetOrNull<T>(T _ = null!) where T : class => GetOrNull<T>(World.LookupByTypeOrThrow<T>());
public T GetOrThrow<T>() => GetOrThrow<T>(World.LookupByTypeOrThrow<T>());
public ref T GetMut<T>() where T : unmanaged => ref GetMut<T>(World.LookupByTypeOrThrow<T>());
public ref T GetRefOrNull<T>() where T : unmanaged => ref GetRefOrNull<T>(World.LookupByTypeOrThrow<T>());
public ref T GetRefOrThrow<T>() where T : unmanaged => ref GetRefOrThrow<T>(World.LookupByTypeOrThrow<T>());
public void Modified<T>() => Modified<T>(World.LookupByTypeOrThrow<T>());
public abstract TReturn Set<T>(Id id, in T value) where T : unmanaged;
public abstract TReturn Set<T>(Id id, T obj) where T : class;
public TReturn Set<T>(in T value) where T : unmanaged => Set(World.LookupByTypeOrThrow<T>(), value);
public TReturn Set<T>(T obj) where T : class => Set(World.LookupByTypeOrThrow<T>(), obj);
public TReturn ChildOf(Entity parent) => Add(World.ChildOf, parent);
public TReturn ChildOf<TParent>() => Add(World.ChildOf, World.LookupByTypeOrThrow<TParent>());
public TReturn Disable() => Add(World.Disabled);
public TReturn Enable() => Remove(World.Disabled);

@ -152,8 +152,6 @@ public unsafe class EntityRef
{ var index = 0; while (GetTarget(relation, index++) is EntityRef target) yield return target; }
public IEnumerable<EntityRef> GetTargets(string symbol)
=> GetTargets(World.LookupBySymbolOrThrow(symbol));
public IEnumerable<EntityRef> GetTargets<T>()
=> GetTargets(World.LookupByTypeOrThrow(typeof(T)));
public bool Equals(EntityRef? other) => (other is not null) && (World == other.World) && (Entity == other.Entity);
public override bool Equals(object? obj) => Equals(obj as EntityRef);

@ -33,14 +33,6 @@ public unsafe class IdRef
public static IdRef Pair(EntityRef relation, EntityRef target)
=> Pair(relation.World, relation, target);
public static IdRef Pair<TRelation>(World world, Entity target)
=> Pair(world, world.LookupByTypeOrThrow<TRelation>(), target);
public static IdRef Pair<TRelation>(EntityRef target)
=> Pair(target.World.LookupByTypeOrThrow<TRelation>(), target);
public static IdRef Pair<TRelation, TTarget>(World world)
=> Pair(world, world.LookupByTypeOrThrow<TRelation>(),
world.LookupByTypeOrThrow<TTarget>());
public EntityRef? AsEntity()
=> (Flags == default) ? World.LookupAlive(new Entity(new() { Data = Id })) : null;
public (EntityRef Relation, EntityRef Target)? AsPair()

@ -83,11 +83,6 @@ public unsafe class Iterator
return ecs_field_id(ptr, index) == id.Value;
}
// TODO: Potentially misleading, doesn't check the field's backing data type.
// The id might be "(Identifier, Name)", but its data type "Identifier".
public bool FieldIs<T>(int index)
=> FieldIs(index, World.LookupByType<T>());
public IdRef FieldId(int index)
{
fixed (ecs_iter_t* ptr = &Value)

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using gaemstone.Utility;
using static flecs_hub.flecs;
@ -7,29 +6,6 @@ namespace gaemstone.ECS;
public unsafe partial class World
{
private readonly Dictionary<Type, Entity> _lookupByType = new();
public void AddLookupByType(Type type, Entity entity)
{
// If an existing lookup already exists with the same entity, don't throw an exception.
if (_lookupByType.TryGetValue(type, out var existing) && (existing == entity)) return;
_lookupByType.Add(type, entity);
}
public void RemoveLookupByType(Type type)
{ if (!_lookupByType.Remove(type)) throw new InvalidOperationException(
$"Lookup for {type} does not exist"); }
public EntityRef? LookupByType<T>()
=> LookupByType(typeof(T));
public EntityRef? LookupByType(Type type)
=> LookupAlive(_lookupByType.GetValueOrDefault(type));
public EntityRef LookupByTypeOrThrow<T>()
=> LookupByTypeOrThrow(typeof(T));
public EntityRef LookupByTypeOrThrow(Type type)
=> LookupByType(type) ?? throw new EntityNotFoundException(
$"Entity of type {type} not found");
public EntityRef? LookupAlive(Entity value)
=> EntityRef.CreateOrNull(this, new(ecs_get_alive(this, value)));
public EntityRef LookupAliveOrThrow(Entity entity)
@ -61,11 +37,3 @@ public unsafe partial class World
public class EntityNotFoundException : Exception
{ public EntityNotFoundException(string message) : base(message) { } }
}
public static class LookupExtensions
{
public static EntityRef CreateLookup<T>(this EntityRef entity)
=> entity.CreateLookup(typeof(T));
public static EntityRef CreateLookup(this EntityRef entity, Type type)
{ entity.World.AddLookupByType(type, entity); return entity; }
}

Loading…
Cancel
Save