using System; using System.Collections.Generic; using gaemstone.Utility; using static flecs_hub.flecs; namespace gaemstone.ECS; public unsafe partial class Universe { private readonly Dictionary _lookupByType = new(); public void AddLookupByType(Type type, Entity entity) => _lookupByType.Add(type, entity); public void RemoveLookupByType(Type type) { if (!_lookupByType.Remove(type)) throw new InvalidOperationException( $"Lookup for {type} does not exist"); } private EntityRef? CreateOrNull(Entity entity) => EntityRef.CreateOrNull(this, entity); public EntityRef? Lookup() => Lookup(typeof(T)); public EntityRef? Lookup(Type type) => Lookup(_lookupByType.GetValueOrDefault(type)); public EntityRef? Lookup(Entity value) => CreateOrNull(new(ecs_get_alive(this, value))); public EntityRef? Lookup(EntityPath path) => Lookup(default, path); public EntityRef? Lookup(Entity parent, EntityPath path) => CreateOrNull(EntityPath.Lookup(this, parent, path)); public EntityRef? LookupSymbol(string symbol) { using var alloc = TempAllocator.Use(); return CreateOrNull(new(ecs_lookup_symbol(this, alloc.AllocateCString(symbol), false))); } public EntityRef LookupOrThrow() => LookupOrThrow(typeof(T)); public EntityRef LookupOrThrow(Type type) => Lookup(type) ?? throw new EntityNotFoundException($"Entity of type {type} not found"); public EntityRef LookupOrThrow(Entity entity) => Lookup(entity) ?? throw new EntityNotFoundException($"Entity {entity} not alive"); public EntityRef LookupOrThrow(EntityPath path) => Lookup(default, path) ?? throw new EntityNotFoundException($"Entity '{path}' not found"); public EntityRef LookupOrThrow(Entity parent, EntityPath path) => Lookup(parent, path) ?? throw new EntityNotFoundException($"Child entity of {parent} '{path}' not found"); public EntityRef LookupSymbolOrThrow(string symbol) => LookupSymbol(symbol) ?? throw new EntityNotFoundException($"Entity with symbol '{symbol}' not found"); public class EntityNotFoundException : Exception { public EntityNotFoundException(string message) : base(message) { } } } public static class LookupExtensions { public static EntityRef CreateLookup(this EntityRef entity) => entity.CreateLookup(typeof(T)); public static EntityRef CreateLookup(this EntityRef entity, Type type) { entity.Universe.AddLookupByType(type, entity); return entity; } }