using System.Runtime.CompilerServices; using Svelto.DataStructures; using Svelto.ECS.Internal; //todo: once using native memory for unmanaged struct will be optional, this will need to be moved under the Native namespace namespace Svelto.ECS { public static class EntityNativeDBExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static NB QueryEntitiesAndIndex (this EntitiesDB entitiesDb, EGID entityGID, out uint index) where T : unmanaged, IEntityComponent { if (entitiesDb.QueryEntitiesAndIndexInternal(entityGID, out index, out NB array) == true) return array; throw new EntityNotFoundException(entityGID, typeof(T)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static NB QueryEntitiesAndIndex (this EntitiesDB entitiesDb, uint id, ExclusiveGroupStruct group, out uint index) where T : unmanaged, IEntityComponent { EGID entityGID = new EGID(id, group); if (entitiesDb.QueryEntitiesAndIndexInternal(entityGID, out index, out NB array) == true) return array; throw new EntityNotFoundException(entityGID, typeof(T)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryQueryEntitiesAndIndex (this EntitiesDB entitiesDb, EGID entityGID, out uint index, out NB array) where T : unmanaged, IEntityComponent { if (entitiesDb.QueryEntitiesAndIndexInternal(entityGID, out index, out array) == true) return true; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryQueryEntitiesAndIndex (this EntitiesDB entitiesDb, uint id, ExclusiveGroupStruct group, out uint index, out NB array) where T : unmanaged, IEntityComponent { if (entitiesDb.QueryEntitiesAndIndexInternal(new EGID(id, group), out index, out array) == true) return true; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetEntity(this EntitiesDB entitiesDb, uint entityID, ExclusiveGroupStruct @group, out T value) where T : unmanaged, IEntityComponent { if (TryQueryEntitiesAndIndex(entitiesDb, entityID, group, out var index, out var array)) { value = array[index]; return true; } value = default; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetEntity(this EntitiesDB entitiesDb, EGID egid, out T value) where T : unmanaged, IEntityComponent { return TryGetEntity(entitiesDb, egid.entityID, egid.groupID, out value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] static bool QueryEntitiesAndIndexInternal (this EntitiesDB entitiesDb, EGID entityGID, out uint index, out NB buffer) where T : unmanaged, IEntityComponent { index = 0; buffer = default; if (entitiesDb.SafeQueryEntityDictionary(entityGID.groupID, out var safeDictionary) == false) return false; if (safeDictionary.TryFindIndex(entityGID.entityID, out index) == false) return false; buffer = (NB) (safeDictionary as ITypeSafeDictionary).GetValues(out _); return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref T QueryEntity (this EntitiesDB entitiesDb, EGID entityGID) where T : unmanaged, IEntityComponent { var array = entitiesDb.QueryEntitiesAndIndex(entityGID, out var index); return ref array[(int) index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref T QueryEntity (this EntitiesDB entitiesDb, uint id, ExclusiveGroupStruct group) where T : unmanaged, IEntityComponent { return ref entitiesDb.QueryEntity(new EGID(id, group)); } /// /// Expects that only one entity of type T exists in the group /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref T QueryUniqueEntity (this EntitiesDB entitiesDb, ExclusiveGroupStruct group) where T : unmanaged, IEntityComponent { var (entities, entitiescount) = entitiesDb.QueryEntities(@group); #if DEBUG && !PROFILE_SVELTO if (entitiescount == 0) throw new ECSException("Unique entity not found '".FastConcat(typeof(T).ToString()).FastConcat("'")); if (entitiescount != 1) throw new ECSException("Unique entities must be unique! '".FastConcat(typeof(T).ToString()) .FastConcat("'")); #endif return ref entities[0]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static NB GetArrayAndEntityIndex (this EGIDMapper mapper, uint entityID, out uint index) where T : unmanaged, IEntityComponent { if (mapper._map.TryFindIndex(entityID, out index)) { return (NB) mapper._map.GetValues(out _); } throw new ECSException("Entity not found"); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetArrayAndEntityIndex (this EGIDMapper mapper, uint entityID, out uint index, out NB array) where T : unmanaged, IEntityComponent { index = default; if (mapper._map != null && mapper._map.TryFindIndex(entityID, out index)) { array = (NB) mapper._map.GetValues(out _); return true; } array = default; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AllGroupsEnumerable QueryEntities(this EntitiesDB db) where T1 :unmanaged, IEntityComponent { return new AllGroupsEnumerable(db); } } }