using System; namespace Svelto.ECS { public delegate void ExecuteOnAllEntitiesAction(T[] entities, ExclusiveGroup.ExclusiveGroupStruct group, uint count, IEntitiesDB db, ref W value); public interface IEntitiesDB { /////////////////////////////////////////////////// // Query entities // ECS systems are meant to work on a set of Entities. These methods allow to iterate over entity // structs inside a given group or an array of groups /////////////////////////////////////////////////// /// /// Fast and raw return of entities buffer. /// /// /// /// /// T[] QueryEntities(ExclusiveGroup.ExclusiveGroupStruct groupStruct, out uint count) where T : struct, IEntityStruct; (T1[], T2[]) QueryEntities(ExclusiveGroup.ExclusiveGroupStruct groupStruct, out uint count) where T1 : struct, IEntityStruct where T2 : struct, IEntityStruct; (T1[], T2[], T3[]) QueryEntities(ExclusiveGroup.ExclusiveGroupStruct groupStruct, out uint count) where T1 : struct, IEntityStruct where T2 : struct, IEntityStruct where T3 : struct, IEntityStruct; /// /// return entities that can be iterated through the EntityCollection iterator /// /// /// /// EntityCollection QueryEntities(ExclusiveGroup.ExclusiveGroupStruct groupStruct) where T : struct, IEntityStruct; EntityCollection QueryEntities(ExclusiveGroup.ExclusiveGroupStruct groupStruct) where T1 : struct, IEntityStruct where T2 : struct, IEntityStruct; EntityCollection QueryEntities(ExclusiveGroup.ExclusiveGroupStruct groupStruct) where T1 : struct, IEntityStruct where T2 : struct, IEntityStruct where T3 : struct, IEntityStruct; /// /// return entities found in multiple groups, that can be iterated through the EntityCollection iterator /// This method is useful to write abstracted engines /// /// /// EntityCollections QueryEntities(ExclusiveGroup[] groups) where T : struct, IEntityStruct; EntityCollections QueryEntities(ExclusiveGroup[] groups) where T1 : struct, IEntityStruct where T2 : struct, IEntityStruct; /////////////////////////////////////////////////// // Query entities regardless the group // these methods are necessary to create abstracted engines. Engines that can iterate over entities regardless // the group /////////////////////////////////////////////////// /// /// Execute an action on ALL the entities regardless the group. This function doesn't guarantee cache /// friendliness even if just EntityStructs are used. Safety checks are in place, /// /// /// void ExecuteOnAllEntities(Action action) where T : struct, IEntityStruct; /// /// same as above, but can pass some external data to avoid allocations /// /// /// /// /// void ExecuteOnAllEntities(ref W value, ExecuteOnAllEntitiesAction action) where T : struct, IEntityStruct; void ExecuteOnAllEntities(W value, Action action) where T : struct, IEntityStruct; /////////////////////////////////////////////////// // Query single entities // ECS systems are meant to work on a set of Entities. Working on a single entity is sometime necessary, hence // the following methods // However Because of the double hashing required to identify a specific entity, these function are slower than // other query methods when used multiple times! /////////////////////////////////////////////////// /// /// QueryUniqueEntity is a contract method that explicitly declare the intention to have just on entity in a /// specific group, usually used for GUI elements /// /// /// /// ref T QueryUniqueEntity(ExclusiveGroup.ExclusiveGroupStruct group) where T : struct, IEntityStruct; /// /// return a specific entity by reference. /// /// /// /// ref T QueryEntity(EGID entityGid) where T : struct, IEntityStruct; ref T QueryEntity(uint id, ExclusiveGroup.ExclusiveGroupStruct group) where T : struct, IEntityStruct; /// /// ///QueryEntitiesAndIndex is useful to optimize cases when multiple entity structs from the same entity must /// be queried. This is the use case: /// ///ref var ghostPosition = ref entitiesDB.QueryEntitiesAndIndex /// (MockupRenderingGroups.GhostCubeID, out var index)[index]; ///ref var ghostScaling = ref entitiesDB.QueryEntities /// (MockupRenderingGroups.GhostCubeID.groupID, out _)[index]; ///ref var ghostRotation = ref entitiesDB.QueryEntities /// (MockupRenderingGroups.GhostCubeID.groupID, out _)[index]; ///ref var ghostResource = ref entitiesDB.QueryEntities /// (MockupRenderingGroups.GhostCubeID.groupID, out _)[index]; /// /// /// /// /// /// T[] QueryEntitiesAndIndex(EGID entityGid, out uint index) where T : struct, IEntityStruct; T[] QueryEntitiesAndIndex(uint id, ExclusiveGroup.ExclusiveGroupStruct group, out uint index) where T : struct, IEntityStruct; /// /// Like QueryEntitiesAndIndex and only way to get an index only if exists /// /// /// /// /// bool TryQueryEntitiesAndIndex(EGID entityGid, out uint index, out T[] array) where T : struct, IEntityStruct; bool TryQueryEntitiesAndIndex (uint id, ExclusiveGroup.ExclusiveGroupStruct group, out uint index, out T[] array) where T : struct, IEntityStruct; /// /// this method returns a mapped version of the entity array so that is possible to work on multiple entities /// inside the group through their EGID. This version skip a level of indirection so it's a bit faster than /// using QueryEntity multiple times (with different EGIDs). /// However mapping can be slow so it must be used for not performance critical paths /// /// /// EGIDMapper QueryMappedEntities(ExclusiveGroup.ExclusiveGroupStruct groupStructId) where T : struct, IEntityStruct; bool TryQueryMappedEntities(ExclusiveGroup.ExclusiveGroupStruct groupStructId, out EGIDMapper mapper) where T : struct, IEntityStruct; /////////////////////////////////////////////////// // Utility methods /////////////////////////////////////////////////// /// /// check if a specific entity exists /// /// /// /// bool Exists(EGID egid) where T : struct, IEntityStruct; bool Exists(uint id, ExclusiveGroup.ExclusiveGroupStruct group) where T : struct, IEntityStruct; bool Exists(ExclusiveGroup.ExclusiveGroupStruct gid); /// /// know if there is any entity struct in a specific group /// /// /// /// bool HasAny(ExclusiveGroup.ExclusiveGroupStruct groupStruct) where T : struct, IEntityStruct; /// /// Count the number of entity structs in a specific group /// /// /// /// uint Count(ExclusiveGroup.ExclusiveGroupStruct groupStruct) where T : struct, IEntityStruct; /// /// /// /// void PublishEntityChange(EGID egid) where T : unmanaged, IEntityStruct; } }