Alternative managed wrapper around flecs-cs bindings for using the ECS framework Flecs in modern .NET.
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

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; }
}