You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
2.5 KiB
69 lines
2.5 KiB
using System; |
|
using System.Collections.Generic; |
|
using gaemstone.ECS.Utility; |
|
using static flecs_hub.flecs; |
|
|
|
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) |
|
=> LookupAlive(entity) ?? throw new EntityNotFoundException( |
|
$"Entity {entity} is not alive"); |
|
|
|
public EntityRef? LookupByPath(EntityPath path) |
|
=> LookupByPath(default, path); |
|
public EntityRef? LookupByPath(Entity parent, EntityPath path) |
|
=> EntityRef.CreateOrNull(this, EntityPath.Lookup(this, parent, path, false)); |
|
public EntityRef LookupByPathOrThrow(EntityPath path) |
|
=> LookupByPathOrThrow(default, path); |
|
public EntityRef LookupByPathOrThrow(Entity parent, EntityPath path) |
|
=> new(this, EntityPath.Lookup(this, parent, path, true)); |
|
|
|
public EntityRef? LookupBySymbol(string symbol) |
|
{ |
|
using var alloc = TempAllocator.Use(); |
|
var entity = ecs_lookup_symbol(this, alloc.AllocateCString(symbol), false); |
|
return EntityRef.CreateOrNull(this, new(entity)); |
|
} |
|
public EntityRef LookupBySymbolOrThrow(string symbol) |
|
=> LookupBySymbol(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<T>(this EntityRef entity) |
|
=> entity.CreateLookup(typeof(T)); |
|
public static EntityRef CreateLookup(this EntityRef entity, Type type) |
|
{ entity.World.AddLookupByType(type, entity); return entity; } |
|
}
|
|
|