using System; using System.Collections.Generic; namespace MoonTools.ECS { public abstract class System : EntityComponentReader { internal MessageDepot MessageDepot => World.MessageDepot; public System(World world) : base(world) { } public abstract void Update(TimeSpan delta); protected Entity CreateEntity() => World.CreateEntity(); protected void Set(in Entity entity, in TComponent component) where TComponent : unmanaged => World.Set(entity, component); protected void Remove(in Entity entity) where TComponent : unmanaged { if (EntityStorage.RemoveComponent(entity.ID, ComponentTypeIndices.GetIndex())) { // Run filter storage update first so that the entity state is still valid in the remove callback. FilterStorage.Check(entity.ID); ComponentDepot.Remove(entity.ID); } } protected void Set(in Template template, in TComponent component) where TComponent : unmanaged => World.Set(template, component); // This feature is EXPERIMENTAL. USe at your own risk!! protected Entity Instantiate(in Template template) => World.Instantiate(template); protected ReadOnlySpan ReadMessages() where TMessage : unmanaged { return MessageDepot.All(); } protected TMessage ReadMessage() where TMessage : unmanaged { return MessageDepot.First(); } protected bool SomeMessage() where TMessage : unmanaged { return MessageDepot.Some(); } protected ReverseSpanEnumerator ReadMessagesWithEntity(in Entity entity) where TMessage : unmanaged { return MessageDepot.WithEntity(entity.ID); } protected ref readonly TMessage ReadMessageWithEntity(in Entity entity) where TMessage : unmanaged { return ref MessageDepot.FirstWithEntity(entity.ID); } protected bool SomeMessageWithEntity(in Entity entity) where TMessage : unmanaged { return MessageDepot.SomeWithEntity(entity.ID); } protected void Send(in TMessage message) where TMessage : unmanaged { MessageDepot.Add(message); } protected void Send(in Entity entity, in TMessage message) where TMessage : unmanaged { MessageDepot.Add(entity.ID, message); } protected void Relate(in Entity entityA, in Entity entityB, TRelationKind relationData) where TRelationKind : unmanaged => World.Relate(entityA, entityB, relationData); protected void Unrelate(in Entity entityA, in Entity entityB) where TRelationKind : unmanaged { var (aEmpty, bEmpty) = RelationDepot.Remove(entityA, entityB); if (aEmpty) { EntityStorage.RemoveRelation(entityA.ID, RelationTypeIndices.GetIndex()); } if (bEmpty) { EntityStorage.RemoveRelation(entityB.ID, RelationTypeIndices.GetIndex()); } } protected void UnrelateAll(in Entity entity) where TRelationKind : unmanaged { RelationDepot.UnrelateAll(entity.ID); EntityStorage.RemoveRelation(entity.ID, RelationTypeIndices.GetIndex()); } protected void Destroy(in Entity entity) => World.Destroy(entity); } }