diff --git a/Ghost.Engine/Component.cs b/Ghost.Engine/Component.cs deleted file mode 100644 index 344f180..0000000 --- a/Ghost.Engine/Component.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Ghost.Engine; - -public abstract class Component -{ - public virtual void Start() - { - } - - public virtual void Update() - { - } - - public virtual void LateUpdate() - { - } - - public virtual void FixedUpdate() - { - } - - public virtual void OnDestroy() - { - } -} \ No newline at end of file diff --git a/Ghost.Engine/Components/Transform.cs b/Ghost.Engine/Components/Transform.cs index 07be4af..647950a 100644 --- a/Ghost.Engine/Components/Transform.cs +++ b/Ghost.Engine/Components/Transform.cs @@ -1,12 +1,14 @@ using Ghost.Engine.Helpers; +using Ghost.Entities; using System.Numerics; +using System.Runtime.CompilerServices; namespace Ghost.Engine.Components; -public class Transform : Component +public struct Transform : IComponentData { private Vector3 _position = Vector3.Zero; - public Vector3 position + public Vector3 Position { get => _position; set @@ -41,22 +43,35 @@ public class Transform : Component } } - public bool hasChanged = true; + public bool hasChanged; - private Matrix4x4 _localToWorldMatrix = Matrix4x4.Identity; - private Matrix4x4 _worldToLocalMatrix = Matrix4x4.Identity; + private Matrix4x4 _localToWorldMatrix; + private Matrix4x4 _worldToLocalMatrix; - public Matrix4x4 LocalToWorldMatrix => _localToWorldMatrix; - public Matrix4x4 WorldToLocalMatrix => _worldToLocalMatrix; + public readonly Matrix4x4 LocalToWorldMatrix => _localToWorldMatrix; + public readonly Matrix4x4 WorldToLocalMatrix => _worldToLocalMatrix; + + public static Transform Default + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => new(Vector3.Zero, Quaternion.Identity, Vector3.One); + } + + public Transform(Vector3 position, Quaternion rotation, Vector3 scale) + { + _position = position; + _rotation = rotation; + _scale = scale; + hasChanged = false; + _localToWorldMatrix = Matrix4x4.Identity; + _worldToLocalMatrix = Matrix4x4.Identity; + + UpdateMatrices(); + } private void UpdateMatrices() { _localToWorldMatrix = MatrixHelpers.CreateTRS(_position, _rotation, _scale); Matrix4x4.Invert(_localToWorldMatrix, out _worldToLocalMatrix); } - - public override void Start() - { - UpdateMatrices(); - } } \ No newline at end of file diff --git a/Ghost.Engine/GameObject.cs b/Ghost.Engine/GameObject.cs index 33ca292..214a8c4 100644 --- a/Ghost.Engine/GameObject.cs +++ b/Ghost.Engine/GameObject.cs @@ -1,96 +1,190 @@ -using Ghost.Engine.Components; -using Ghost.Engine.Services; -using System.Collections.ObjectModel; +using Ghost.Engine.Models; +using Ghost.Entities; +using System.ComponentModel; namespace Ghost.Engine; -public class GameObject +public unsafe class GameObject : INotifyPropertyChanged { - private readonly ObservableCollection _components = new(); + private readonly Dictionary _components = new(); + private readonly List _children = new(); - public string name = string.Empty; - public bool isActive = true; + public event PropertyChangedEventHandler? PropertyChanged; - public Transform Transform { get; } = new(); - - private GameObject() + public Entity Entity { - AddComponent(Transform); + get; } - public static GameObject Create(string name = "") + public Scene Scene { - var gameObject = new GameObject + get; + internal set; + } + + public GameObject? Parent + { + get; + internal set; + } + + public string Name + { + get; + set; + } + + public bool IsActive + { + get; + set; + } + + public IEnumerable Components => _components.Values; + public IEnumerable Children => _children; + + public GameObject(Scene scene, string name) + { + // TODO: Initialize Entity properly + //Entity = + Scene = scene; + Name = name; + IsActive = true; + } + + public void AddComponent(T component) + where T : ScriptComponent + { + _components.Add(typeof(T), component); + component.Owner = Entity; + + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Components))); + } + + public void RemoveComponent() + where T : ScriptComponent + { + var key = typeof(T); + if (_components.Remove(key, out var component)) { - name = name - }; - - GameLoopService.RegisterGameObject(gameObject); - return gameObject; + component.OnDestroy(); + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Components))); + } } - public void AddComponent(Component component) + public T? GetComponent() + where T : ScriptComponent { - _components.Add(component); - } - - public void RemoveComponent(Component component) - { - _components.Remove(component); - } - - public T? GetComponent() where T : Component - { - foreach (var component in _components) + if (_components.TryGetValue(typeof(T), out var component)) { - if (component is T t) - { - return t; - } + return (T)component; } return null; } + public void AddChild(GameObject child) + { + if (child.Scene != Scene) + { + throw new InvalidOperationException("Child GameObject must belong to the same Scene."); + } + + _children.Add(child); + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Children))); + } + + public void RemoveChild(GameObject child) + { + if (_children.Remove(child)) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Children))); + } + } + + internal void OnEnable() + { + foreach (var component in Components) + { + if (!component.Enable) + { + continue; + } + component.OnEnable(); + } + + foreach (var child in _children) + { + child.OnEnable(); + } + } + internal void Start() { - foreach (var component in _components) + foreach (var component in Components) { + if (!component.Enable) + { + continue; + } component.Start(); } } internal void Update() { - foreach (var component in _components) + foreach (var component in Components) { + if (!component.Enable) + { + continue; + } component.Update(); } } internal void LateUpdate() { - foreach (var component in _components) + foreach (var component in Components) { + if (!component.Enable) + { + continue; + } component.LateUpdate(); } } internal void FixedUpdate() { - foreach (var component in _components) + foreach (var component in Components) { + if (!component.Enable) + { + continue; + } component.FixedUpdate(); } } public void Destroy() { - foreach (var component in _components) + foreach (var component in Components) { + if (!component.Enable) + { + continue; + } component.OnDestroy(); } - GameLoopService.UnregisterGameObject(this); + foreach (var child in _children) + { + child.Destroy(); + } + + _children.Clear(); + _components.Clear(); + Parent?._children.Remove(this); } } \ No newline at end of file diff --git a/Ghost.Engine/Ghost.Engine.csproj b/Ghost.Engine/Ghost.Engine.csproj index 2820cf2..34f82da 100644 --- a/Ghost.Engine/Ghost.Engine.csproj +++ b/Ghost.Engine/Ghost.Engine.csproj @@ -4,6 +4,7 @@ net9.0 enable enable + True @@ -14,4 +15,8 @@ True + + + + diff --git a/Ghost.Engine/Models/Scene.cs b/Ghost.Engine/Models/Scene.cs index 5bf47d7..0a372bd 100644 --- a/Ghost.Engine/Models/Scene.cs +++ b/Ghost.Engine/Models/Scene.cs @@ -2,7 +2,29 @@ public class Scene { + private readonly HashSet _rootObjects = new(); + + public IEnumerable RootObjects => _rootObjects; + internal Scene() { } + + internal void Load() + { + foreach (var gameObject in _rootObjects) + { + gameObject.Start(); + } + } + + internal void Unload() + { + foreach (var gameObject in _rootObjects) + { + gameObject.Destroy(); + } + + _rootObjects.Clear(); + } } \ No newline at end of file diff --git a/Ghost.Engine/Services/GameLoopService.cs b/Ghost.Engine/Services/PlayerLoopService.cs similarity index 50% rename from Ghost.Engine/Services/GameLoopService.cs rename to Ghost.Engine/Services/PlayerLoopService.cs index 7eb1f8f..adb76b1 100644 --- a/Ghost.Engine/Services/GameLoopService.cs +++ b/Ghost.Engine/Services/PlayerLoopService.cs @@ -1,26 +1,13 @@ - -namespace Ghost.Engine.Services; +namespace Ghost.Engine.Services; -internal static class GameLoopService +internal static class PlayerLoopService { - private readonly static HashSet _gameObjects = new(); - private static Timer? _timer; private static bool _isRunning = false; // TODO: Implement the actual time system public static float fixedDeltaTime = 0.02f; - public static void RegisterGameObject(GameObject gameObject) - { - _gameObjects.Add(gameObject); - } - - public static void UnregisterGameObject(GameObject gameObject) - { - _gameObjects.Remove(gameObject); - } - public static void Start() { if (_isRunning) @@ -28,13 +15,8 @@ internal static class GameLoopService return; } - foreach (var gameObject in _gameObjects) + foreach (var gameObject in SceneManager.QueryRootGameObjects()) { - if (!gameObject.isActive) - { - continue; - } - gameObject.Start(); } @@ -48,27 +30,21 @@ internal static class GameLoopService private static void Update() { - foreach (var gameObject in _gameObjects) + foreach (var gameObject in SceneManager.QueryRootGameObjects()) { - if (!gameObject.isActive) - { - continue; - } - gameObject.Update(); + } + + foreach (var gameObject in SceneManager.QueryRootGameObjects()) + { gameObject.LateUpdate(); } } private static void FixedUpdate(object? state) { - foreach (var gameObject in _gameObjects) + foreach (var gameObject in SceneManager.QueryRootGameObjects()) { - if (!gameObject.isActive) - { - continue; - } - gameObject.FixedUpdate(); } } diff --git a/Ghost.Engine/Services/SceneManager.cs b/Ghost.Engine/Services/SceneManager.cs new file mode 100644 index 0000000..8087048 --- /dev/null +++ b/Ghost.Engine/Services/SceneManager.cs @@ -0,0 +1,50 @@ +using Ghost.Engine.Models; + +namespace Ghost.Engine.Services; + +public enum SceneLoadMode +{ + Single, + Additive +} + +public static class SceneManager +{ + private readonly static HashSet _activeScenes = new(); + + internal static IEnumerable QueryRootGameObjects() + { + foreach (var scene in _activeScenes) + { + foreach (var gameObject in scene.RootObjects) + { + if (!gameObject.IsActive) + { + continue; + } + + yield return gameObject; + } + } + } + + public static void LoadScene(Scene scene, SceneLoadMode loadMode) + { + if (loadMode == SceneLoadMode.Single) + { + foreach (var activeScene in _activeScenes) + { + activeScene.Unload(); + } + _activeScenes.Clear(); + } + + _activeScenes.Add(scene); + scene.Load(); + } + + public static Task LoadSceneAsync(Scene scene, SceneLoadMode loadMode) + { + return Task.Run(() => LoadScene(scene, loadMode)); + } +} \ No newline at end of file diff --git a/Ghost.Entities/AssemblyInfo.cs b/Ghost.Entities/AssemblyInfo.cs index 9718d31..b9f7d98 100644 --- a/Ghost.Entities/AssemblyInfo.cs +++ b/Ghost.Entities/AssemblyInfo.cs @@ -4,4 +4,5 @@ global using WorldID = System.UInt16; using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("Ghost.Engine")] \ No newline at end of file +[assembly: InternalsVisibleTo("Ghost.Engine")] +[assembly: InternalsVisibleTo("Ghost.Test")] \ No newline at end of file diff --git a/Ghost.Entities/Component.cs b/Ghost.Entities/Component.cs index 051873b..47eff32 100644 --- a/Ghost.Entities/Component.cs +++ b/Ghost.Entities/Component.cs @@ -1,12 +1,39 @@ -namespace Ghost.Entities; +using Ghost.Entities.Utilities; +using Misaki.HighPerformance.Unsafe.Collections; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; -public interface IComponent +namespace Ghost.Entities; + +public interface IComponentData { } -internal class ComponentPool : IDisposable - where T : struct, IComponent +internal static class SingletonContainer + where T : struct, IComponentData +{ + public static readonly Dictionary container = new(); +} + +internal interface IComponentPool : IDisposable +{ + public EntityID Count + { + get; + } + + public void Remove(Entity entity); + public bool Has(Entity entity); +} + +internal interface IComponentPool : IComponentPool +{ + public void Add(Entity entity, T Component); +} + +internal class ComponentPool : IComponentPool + where T : struct, IComponentData { private struct ComponentData { @@ -20,6 +47,8 @@ internal class ComponentPool : IDisposable private ComponentData[] _components; private EntityID[] _lookup; + public EntityID Count => _nextId; + public ComponentPool(int initialSize = 16) { _nextId = 0; @@ -31,26 +60,34 @@ internal class ComponentPool : IDisposable _lookup.AsSpan().Fill(Entity.INVALID_ID); } - public EntityID Count => _nextId; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static EntityID GetLookupIndex(Entity entity) + { + return entity.ID; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private EntityID GetComponentIndex(Entity entity) { - return _lookup[entity.ID]; + return _lookup[GetLookupIndex(entity)]; } public void Add(Entity entity, T component) { - if (entity.ID >= _lookup.Length) + if (!entity.IsValid) { - _lookup.AsSpan(_nextId, entity.ID - _lookup.Length + 1).Fill(Entity.INVALID_ID); + return; } - if (_lookup[entity.ID] != Entity.INVALID_ID) + var lookupIndex = GetLookupIndex(entity); + var componentIndex = GetComponentIndex(entity); + + if (componentIndex != Entity.INVALID_ID) { // Overwrite the old data if generation is larger - if (entity.Generation > _components[_lookup[entity.ID]].owner.Generation) + if (entity.Generation > _components[componentIndex].owner.Generation) { - var index = _lookup[entity.ID]; + var index = _lookup[lookupIndex]; _components[index].data = component; _components[index].owner = entity; } @@ -68,19 +105,29 @@ internal class ComponentPool : IDisposable _capacity = newCapacity; } + _lookup[lookupIndex] = _nextId; _components[_nextId] = new ComponentData { data = component, owner = entity }; - _lookup[entity.ID] = _nextId; _nextId++; } + public void Remove(Entity entity) + { + } + public ref T GetRef(Entity entity) { - return ref _components[_lookup[entity.ID]].data; + if (!entity.IsValid) + { + return ref Unsafe.NullRef(); + } + + var index = GetComponentIndex(entity); + return ref _components[index].data; } public bool Has(Entity entity) @@ -96,17 +143,235 @@ internal class ComponentPool : IDisposable public void Set(Entity entity, T component) { - if (entity.ID >= _lookup.Length || _lookup[entity.ID] == Entity.INVALID_ID) + if (!entity.IsValid || entity.ID >= _lookup.Length || GetComponentIndex(entity) == Entity.INVALID_ID) { return; } - var index = _lookup[entity.ID]; + var index = GetComponentIndex(entity); _components[index].data = component; _components[index].owner = entity; } public void Dispose() { + _components = Array.Empty(); + _lookup = Array.Empty(); + _nextId = 0; + _capacity = 0; + } +} + +internal class ScriptComponentPool : IComponentPool +{ + private Dictionary>? _scriptComponents; + private List? _executionList; + + internal Dictionary>? ScriptComponents => _scriptComponents; + internal List? ExecutionList => _executionList; + + public bool IsInitialized => _scriptComponents != null; + public int Count => _scriptComponents?.Keys.Count ?? 0; + + internal void Initialize(int capacity = 16) + { + _scriptComponents ??= new(capacity); + } + + internal void RebuildExecutionList() + { + if (_scriptComponents == null) + { + return; + } + + _executionList ??= new List(_scriptComponents.Count); + _executionList.Clear(); + + foreach (var kvp in _scriptComponents) + { + _executionList.AddRange(kvp.Value); + } + + _executionList.Sort((a, b) => a.ExecutionOrder.CompareTo(b.ExecutionOrder)); + } + + public void Add(Entity entity, ScriptComponent component) + { + if (!IsInitialized) + { + Initialize(); + } + + if (!_scriptComponents!.TryGetValue(entity, out var scriptList)) + { + scriptList = new(); + _scriptComponents[entity] = scriptList; + } + + scriptList.Add(component); + component.Owner = entity; + } + + public void Remove(Entity entity) + { + if (!Has(entity) + || !_scriptComponents!.TryGetValue(entity, out var scriptList) + || scriptList == null) + { + return; + } + + foreach (var script in scriptList) + { + script.OnDestroy(); + } + + _scriptComponents.Remove(entity); + } + + public bool Has(Entity entity) + { + return _scriptComponents?.ContainsKey(entity) ?? false; + } + + public List? Get(Entity entity) + { + if (_scriptComponents == null + || !_scriptComponents.TryGetValue(entity, out var scriptList)) + { + return null; + } + + return scriptList; + } + + public void Dispose() + { + if (_scriptComponents != null) + { + if (_executionList != null) + { + foreach (var script in _executionList) + { + script.OnDestroy(); + } + + _executionList.Clear(); + } + else + { + foreach (var scriptList in _scriptComponents.Values) + { + if (scriptList == null) + { + continue; + } + + foreach (var script in scriptList) + { + script.OnDestroy(); + } + } + + } + + _scriptComponents.Clear(); + } + } +} + +internal class ComponentStorage : IDisposable +{ + private readonly Dictionary _componentPools = new(); + private readonly Dictionary _componentEntityMasks = new(); + private readonly ScriptComponentPool _scriptComponentPool = new(); + + internal Dictionary ComponentPools => _componentPools; + internal ScriptComponentPool ScriptComponentPool => _scriptComponentPool; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetPool(nint typeHandle, [MaybeNullWhen(false)] out IComponentPool pool) + { + return _componentPools.TryGetValue(typeHandle, out pool); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetPool(Type type, [MaybeNullWhen(false)] out IComponentPool pool) + { + return TryGetPool(type.TypeHandle.Value, out pool); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetPool([MaybeNullWhen(false)] out ComponentPool pool) + where T : struct, IComponentData + { + var result = TryGetPool(TypeHandle.Value, out var obj); + pool = (ComponentPool?)obj; + return result; + } + + public ComponentPool GetOrCreateComponentPool() + where T : struct, IComponentData + { + var key = TypeHandle.Value; + if (!_componentPools.TryGetValue(key, out var obj)) + { + var pool = new ComponentPool(); + _componentPools[key] = pool; + return pool; + } + + return (ComponentPool)obj; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetMask(nint typeHandle, [MaybeNullWhen(false)] out BitSet bitSet) + { + return _componentEntityMasks.TryGetValue(typeHandle, out bitSet); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetMask(Type type, [MaybeNullWhen(false)] out BitSet bitSet) + { + return TryGetMask(type.TypeHandle.Value, out bitSet); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetMask([MaybeNullWhen(false)] out BitSet bitSet) + where T : struct, IComponentData + { + return TryGetMask(TypeHandle.Value, out bitSet); + } + + public BitSet GetOrCreateMask(nint typeHandle) + { + if (!_componentEntityMasks.TryGetValue(typeHandle, out var mask)) + { + mask = new BitSet(); + _componentEntityMasks[typeHandle] = mask; + } + return mask; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RebuildExecutionList() + { + _scriptComponentPool.RebuildExecutionList(); + } + + public void Remove(Entity entity) + { + _scriptComponentPool.Remove(entity); + } + + public void Dispose() + { + foreach (var pool in _componentPools.Values) + { + pool.Dispose(); + } + _componentPools.Clear(); + _scriptComponentPool.Dispose(); } } \ No newline at end of file diff --git a/Ghost.Entities/Entity.cs b/Ghost.Entities/Entity.cs index 82f9b3b..08a8ac9 100644 --- a/Ghost.Entities/Entity.cs +++ b/Ghost.Entities/Entity.cs @@ -1,17 +1,20 @@ -using System.Runtime.CompilerServices; +using Ghost.Entities.Query; +using Ghost.Entities.Utilities; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace Ghost.Entities; [SkipLocalsInit] public struct Entity : IEquatable, IComparable { - private const int _WORLD_INDEX_BITS = 4; - private const int _GENERATION_BITS = 8; - private const int _INDEX_BITS = sizeof(EntityID) * 8 - _WORLD_INDEX_BITS - _GENERATION_BITS; + public const int WORLD_INDEX_BITS = 4; + public const int GENERATION_BITS = 8; + public const int INDEX_BITS = sizeof(EntityID) * 8 - WORLD_INDEX_BITS - GENERATION_BITS; - private const int _WORLD_INDEX_MASK = (1 << _WORLD_INDEX_BITS) - 1; - private const int _GENERATION_MASK = (1 << _GENERATION_BITS) - 1; - private const int _INDEX_MASK = (1 << _INDEX_BITS) - 1; + private const int _WORLD_INDEX_MASK = (1 << WORLD_INDEX_BITS) - 1; + private const int _GENERATION_MASK = (1 << GENERATION_BITS) - 1; + private const int _INDEX_MASK = (1 << INDEX_BITS) - 1; public const EntityID INVALID_ID = -1; @@ -32,13 +35,24 @@ public struct Entity : IEquatable, IComparable public readonly GenerationID Generation { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => (GenerationID)(_id >> _INDEX_BITS & _GENERATION_MASK); + get => (GenerationID)(_id >> INDEX_BITS & _GENERATION_MASK); } - public readonly WorldID WorldIndex + public readonly WorldID WorldID { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => (WorldID)(_id >> (_INDEX_BITS + _GENERATION_BITS) & _WORLD_INDEX_MASK); + get => (WorldID)(_id >> (INDEX_BITS + GENERATION_BITS) & _WORLD_INDEX_MASK); + } + + public static Entity Invalid + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => new(INVALID_ID, 0, 0); + } + + internal Entity(EntityID id, GenerationID generation, WorldID worldID) + { + _id = worldID << (INDEX_BITS + GENERATION_BITS) | generation << INDEX_BITS | id; } public void IncrementGeneration() @@ -49,12 +63,7 @@ public struct Entity : IEquatable, IComparable throw new InvalidOperationException("Generation overflow"); } - _id = _id & ~(_GENERATION_MASK << _INDEX_BITS) | generation << _INDEX_BITS; - } - - internal Entity(EntityID index, EntityID generation, EntityID worldIndex) - { - _id = worldIndex << (_INDEX_BITS + _GENERATION_BITS) | generation << _INDEX_BITS | index; + _id = _id & ~(_GENERATION_MASK << INDEX_BITS) | generation << INDEX_BITS; } public readonly bool Equals(Entity other) @@ -89,6 +98,219 @@ public struct Entity : IEquatable, IComparable public override readonly string ToString() { - return $"Entity {{ Index: {ID}, Generation: {Generation}, WorldIndex: {WorldIndex} }}"; + return $"Entity {{ Index: {ID}, Generation: {Generation}, WorldIndex: {WorldID} }}"; + } +} + +public class EntityManager : IDisposable +{ + private readonly List _entities; + private readonly Queue _freeEntitySlots; + + private readonly World _world; + + public int EntityCount => _entities.Count; + public ReadOnlySpan Entities => CollectionsMarshal.AsSpan(_entities); + + internal EntityManager(World world, int initialCapacity) + { + _entities = new(initialCapacity); + _freeEntitySlots = new(initialCapacity); + _world = world; + } + + /// + /// Adds a new to the world. + /// + /// The created . + public Entity CreateEntity() + { + if (_freeEntitySlots.TryDequeue(out var id)) + { + return _entities[id]; + } + else + { + id = _entities.Count; + var entity = new Entity(id, 0, _world.ID); + _entities.Add(entity); + return entity; + } + } + + /// + /// Removes the specified from the world. + /// + /// + public void RemoveEntity(ref Entity entity) + { + if (entity.ID >= _entities.Count || _entities[entity.ID].Generation != entity.Generation) + { + return; + } + + _world._componentStorage.Remove(entity); + + var slot = _entities[entity.ID]; + slot.IncrementGeneration(); + _entities[entity.ID] = slot; + _freeEntitySlots.Enqueue(entity.ID); + + entity = Entity.Invalid; + } + + /// + /// Checks if the given is valid and belongs to this . + /// + /// The entity to check. + /// True if the entity is valid and belongs to this world; otherwise, false. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool HasEntity(Entity entity) + { + if (!entity.IsValid + || entity.WorldID != _world.ID + || entity.ID >= _entities.Count) + { + return false; + } + + return _entities[entity.ID].Generation == entity.Generation; + } + + /// + /// Adds a component of type to the given . + /// + /// The type of the component to set. + /// The entity for which the component is to be add. + /// The component value to add. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddComponent(Entity entity, T component) + where T : struct, IComponentData + { + _world._componentStorage.GetOrCreateComponentPool().Add(entity, component); + _world._componentStorage.GetOrCreateMask(TypeHandle.Value).SetBit(entity.ID); + } + + /// + /// Removes a component of type from the given . + /// + /// The type of the component to remove. + /// The entity for which the component is to be remove. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RemoveComponent(Entity entity) + where T : struct, IComponentData + { + if (_world._componentStorage.TryGetPool(out var pool) && pool.Has(entity)) + { + pool.Remove(entity); + _world._componentStorage.GetOrCreateMask(TypeHandle.Value).ClearBit(entity.ID); + } + } + + /// + /// Sets a component of type for the given . + /// + /// The type of the component to set. + /// The entity for which the component is to be set. + /// The component value to set. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetComponent(Entity entity, T component) + where T : struct, IComponentData + { + _world._componentStorage.GetOrCreateComponentPool().Set(entity, component); + } + + /// + /// Checks if the given has a component of the specified type. + /// + /// The entity to check. + /// The handle of the component type. + /// True if the entity has the component; otherwise, false. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool HasComponent(Entity entity, nint typeHandle) + { + return _world._componentStorage.TryGetMask(typeHandle, out var bitSet) && bitSet.IsSet(entity.ID); + } + + /// + /// Retrieves a reference to a component of type associated with the given . + /// + /// The type of the component to retrieve. + /// The entity whose component is to be retrieved. + /// A to the component, or a null reference if the component does not exist. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Ref GetComponent(Entity entity) + where T : struct, IComponentData + { + if (_world._componentStorage.TryGetPool(out var pool) && pool.Has(entity)) + { + return new Ref(ref pool.GetRef(entity)); + } + else + { + return new Ref(ref Unsafe.NullRef(), false); + } + } + + /// + /// Adds a script of type to the given . + /// + /// The type of the script to add. + /// The entity to which the script is to be added. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddScript(Entity entity) + where T : ScriptComponent, new() + { + _world._componentStorage.ScriptComponentPool.Add(entity, new T()); + } + + /// + /// Adds a script of the specified type to the given . + /// + /// The entity to which the script is to be added. + /// The type of the script to add. + /// Thrown if the specified type does not inherit from . + /// Thrown if the script instance could not be created. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddScript(Entity entity, Type type) + { + if (!typeof(ScriptComponent).IsAssignableFrom(type)) + { + throw new ArgumentException($"Type {type} must inherit from ScriptComponent.", nameof(type)); + } + + var instance = (ScriptComponent?)Activator.CreateInstance(type) ?? throw new InvalidOperationException($"Failed to create instance of {type}."); + _world._componentStorage.ScriptComponentPool.Add(entity, instance); + } + + /// + /// Retrieves the first script of type associated with the given . + /// + /// The type of the script to retrieve. + /// The entity whose script is to be retrieved. + /// The script of type , or null if no such script exists. + public T? GetScript(Entity entity) + where T : ScriptComponent + { + return (T?)_world._componentStorage.ScriptComponentPool.Get(entity)? + .FirstOrDefault(script => script is T tScript); + } + + /// + /// Retrieves all scripts of type associated with the given . + /// + /// The type of the scripts to retrieve. + /// The entity whose scripts are to be retrieved. + /// An enumerable of scripts of type . + public IEnumerable GetScripts(Entity entity) + where T : ScriptComponent + { + return (IEnumerable?)_world._componentStorage.ScriptComponentPool.Get(entity)?.Where(script => script is T tScript) ?? Enumerable.Empty(); + } + + public void Dispose() + { + _entities.Clear(); + _freeEntitySlots.Clear(); } } \ No newline at end of file diff --git a/Ghost.Entities/Ghost.Entities.csproj b/Ghost.Entities/Ghost.Entities.csproj index b15dc76..32e2d87 100644 --- a/Ghost.Entities/Ghost.Entities.csproj +++ b/Ghost.Entities/Ghost.Entities.csproj @@ -8,6 +8,11 @@ + + True + True + QueryItem.tt + True True @@ -27,10 +32,18 @@ + + TextTemplatingFileGenerator + QueryEnumerable.cs + TextTemplatingFilePreprocessor Helpers.cs + + TextTemplatingFileGenerator + QueryItem.cs + TextTemplatingFileGenerator QueryRefComponent.cs @@ -51,6 +64,16 @@ True Helpers.tt + + True + True + QueryEnumerable.tt + + + True + True + QueryItem.tt + True True @@ -63,4 +86,8 @@ + + + + diff --git a/Ghost.Entities/Helpers/EntityHelpers.cs b/Ghost.Entities/Helpers/EntityHelpers.cs new file mode 100644 index 0000000..cd20742 --- /dev/null +++ b/Ghost.Entities/Helpers/EntityHelpers.cs @@ -0,0 +1,147 @@ +using Ghost.Entities.Query; +using System.Runtime.CompilerServices; + +namespace Ghost.Entities.Helpers; + +/// +/// Provides extension methods for working with entities in the Ghost framework. +/// +public static class EntityHelpers +{ + public static World GetWorld(this Entity entity) + { + return World.GetWorld(entity.WorldID); + } + + /// + /// Adds a component of type to the given . + /// + /// The type of the component to set. + /// The entity for which the component is to be add. + /// The component value to add. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AddComponent(this Entity entity, T component) + where T : struct, IComponentData + { + var world = entity.GetWorld(); + world.EntityManager.AddComponent(entity, component); + } + + /// + /// Removes a component of type from the given . + /// + /// The type of the component to remove. + /// The entity for which the component is to be remove. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void RemoveComponent(this Entity entity) + where T : struct, IComponentData + { + var world = entity.GetWorld(); + world.EntityManager.RemoveComponent(entity); + } + + /// + /// Sets a component of type for the given . + /// + /// The type of the component to set. + /// The entity for which the component is to be set. + /// The component value to set. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SetComponent(this Entity entity, T component) + where T : struct, IComponentData + { + var world = entity.GetWorld(); + world.EntityManager.SetComponent(entity, component); + } + + /// + /// Checks if the given has a component of the specified type. + /// + /// The entity to check. + /// The handle of the component type. + /// True if the entity has the component; otherwise, false. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool HasComponent(this Entity entity, nint typeHandle) + { + var world = entity.GetWorld(); + return world.EntityManager.HasComponent(entity, typeHandle); + } + + /// + /// Retrieves a reference to a component of type associated with the given . + /// + /// The type of the component to retrieve. + /// The entity whose component is to be retrieved. + /// A to the component, or a null reference if the component does not exist. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Ref GetComponent(this Entity entity) + where T : struct, IComponentData + { + var world = entity.GetWorld(); + return world.EntityManager.GetComponent(entity); + } + + /// + /// Adds a script of type to the given . + /// + /// The type of the script to add. + /// The entity to which the script is to be added. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AddScript(this Entity entity) + where T : ScriptComponent, new() + { + var world = entity.GetWorld(); + world.EntityManager.AddScript(entity); + } + + /// + /// Adds a script of the specified type to the given . + /// + /// The entity to which the script is to be added. + /// The type of the script to add. + /// Thrown if the specified type does not inherit from . + /// Thrown if the script instance could not be created. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AddScript(this Entity entity, Type type) + { + var world = entity.GetWorld(); + world.EntityManager.AddScript(entity, type); + } + + /// + /// Retrieves the first script of type associated with the given . + /// + /// The type of the script to retrieve. + /// The entity whose script is to be retrieved. + /// The script of type , or null if no such script exists. + public static T? GetScript(this Entity entity) + where T : ScriptComponent + { + var world = entity.GetWorld(); + return world.EntityManager.GetScript(entity); + } + + /// + /// Retrieves all scripts of type associated with the given . + /// + /// The type of the scripts to retrieve. + /// The entity whose scripts are to be retrieved. + /// An enumerable of scripts of type . + public static IEnumerable GetScripts(this Entity entity) + where T : ScriptComponent + { + var world = entity.GetWorld(); + return world.EntityManager.GetScripts(entity); + } + + /// + /// Destroys the given by removing it from its associated . + /// + /// The entity to destroy. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Destroy(this Entity entity) + { + var world = entity.GetWorld(); + world.EntityManager.RemoveEntity(ref entity); + } +} \ No newline at end of file diff --git a/Ghost.Entities/Query/QueryFilter.cs b/Ghost.Entities/Query/QueryFilter.cs new file mode 100644 index 0000000..9078d98 --- /dev/null +++ b/Ghost.Entities/Query/QueryFilter.cs @@ -0,0 +1,98 @@ +using Misaki.HighPerformance.Unsafe.Collections; + +namespace Ghost.Entities.Query; + +[Flags] +internal enum FilterMode +{ + All = 1 << 0, + Any = 1 << 1, + Absent = 1 << 2, + Disabled = 1 << 3, +} + +internal readonly struct FilterEntry(nint id, FilterMode mode) +{ + public readonly nint typeHandle = id; + public readonly FilterMode mode = mode; +} + +internal struct QueryFilter() +{ + internal List _all = new(6); + internal List _any = new(6); + internal List _absent = new(6); + internal List _disabled = new(6); + + public readonly void ComputeFilterBitMask(World world, ref BitSet result) + { + BitSet allMask = default; + BitSet anyMask = default; + BitSet absentMask = default; + + var hasAll = false; + var hasAny = false; + var hasAbsent = false; + + // Compute All mask (intersection) + foreach (var typeHandle in _all) + { + var mask = world._componentStorage.GetOrCreateMask(typeHandle); + + if (!hasAll) + { + allMask = new BitSet(mask.Length); + allMask.SetAll(); + hasAll = true; + } + + allMask &= mask; + } + + // Compute Any mask (union) + foreach (var typeHandle in _any) + { + var mask = world._componentStorage.GetOrCreateMask(typeHandle); + + if (!hasAny) + { + anyMask = new BitSet(mask.Length); + hasAny = true; + } + + anyMask |= mask; + } + + // Compute Absent mask (union for exclusion) + foreach (var typeHandle in _absent) + { + var mask = world._componentStorage.GetOrCreateMask(typeHandle); + + if (!hasAbsent) + { + absentMask = new BitSet(mask.Length); + hasAbsent = true; + } + + absentMask |= mask; + } + + result = new BitSet(world.EntityManager.EntityCount); + result.SetAll(); + + if (hasAll) + { + result &= allMask; + } + + if (hasAny) + { + result &= anyMask; + } + + if (hasAbsent) + { + result &= ~absentMask; + } + } +} \ No newline at end of file diff --git a/Ghost.Entities/Query/QueryTypeParameter.cs b/Ghost.Entities/Query/QueryTypeParameter.cs new file mode 100644 index 0000000..182bf44 --- /dev/null +++ b/Ghost.Entities/Query/QueryTypeParameter.cs @@ -0,0 +1,41 @@ +using System.Runtime.CompilerServices; + +namespace Ghost.Entities.Query; + +public interface IQueryTypeParameter +{ +} + +public ref struct Ref : IQueryTypeParameter + where T : IComponentData +{ + internal ref T _value; + + public ref T ValueRW + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => ref _value; + } + + public readonly ref T ValueRO + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => ref _value; + } + + public readonly bool IsValid + { + get; + init; + } + + public Ref(ref T value, bool isValid) + { + _value = ref value; + IsValid = isValid; + } + + public Ref(ref T value) : this(ref value, true) + { + } +} \ No newline at end of file diff --git a/Ghost.Entities/ScriptComponent.cs b/Ghost.Entities/ScriptComponent.cs new file mode 100644 index 0000000..5339f05 --- /dev/null +++ b/Ghost.Entities/ScriptComponent.cs @@ -0,0 +1,78 @@ +namespace Ghost.Entities; + +public abstract class ScriptComponent : IComponentData +{ + /// + /// Gets or sets a value indicating whether this script component is enabled. + /// + public bool Enable + { + get; + set; + } = true; + + /// + /// Gets the entity that owns this script component. + /// + public Entity Owner + { + get; + internal set; + } + + /// + /// Gets or sets the priority of the script component. + /// Change this during runtime does not affect the execution order. + /// + public virtual int ExecutionOrder => 0; + + /// + /// Called when the script component is enabled. + /// + public virtual void OnEnable() + { + } + + /// + /// Called when the script component is disabled. + /// + public virtual void OnDisable() + { + } + + /// + /// Called when the script component is started. + /// + public virtual void Start() + { + } + + /// + /// Called every frame. + /// + public virtual void Update() + { + } + + /// + /// Called every frame after all Update methods have been called. + /// + public virtual void LateUpdate() + { + } + + /// + /// Called at a fixed interval. + /// This method is called at a fixed time step, independent of the frame rate. + /// + public virtual void FixedUpdate() + { + } + + /// + /// Called when the script component is destroyed. + /// + public virtual void OnDestroy() + { + } +} \ No newline at end of file diff --git a/Ghost.Entities/System.cs b/Ghost.Entities/System.cs new file mode 100644 index 0000000..4ebfe09 --- /dev/null +++ b/Ghost.Entities/System.cs @@ -0,0 +1,89 @@ +namespace Ghost.Entities; + +public abstract class SystemBase +{ + public virtual int ExecutionOrder => 0; + + public virtual bool Enable + { + get; + set; + } = true; + + public World World + { + get; + init; + } = null!; + + public virtual void OnCreate() + { + } + + public virtual void OnUpdate() + { + } + + public virtual void OnDestroy() + { + } +} + +internal class SystemStorage : IDisposable +{ + private readonly List _systems = new(); + private readonly List _executionList = new(); + + public void AddSystem(T system) + where T : SystemBase + { + _systems.Add(system); + if (system.Enable) + { + system.OnCreate(); + } + } + + public void RemoveSystem(T system) + where T : SystemBase + { + _systems.Remove(system); + if (system.Enable) + { + system.OnDestroy(); + } + } + + public void RebuildExecutionList() + { + _executionList.Clear(); + _executionList.AddRange(_systems.OrderBy(s => s.ExecutionOrder)); + } + + public void UpdateSystems() + { + foreach (var system in _systems) + { + if (!system.Enable) + { + continue; + } + system.OnUpdate(); + } + } + + public void Dispose() + { + foreach (var system in _systems) + { + if (!system.Enable) + { + continue; + } + system.OnDestroy(); + } + + _systems.Clear(); + _executionList.Clear(); + } +} \ No newline at end of file diff --git a/Ghost.Entities/Template/Helpers.ttinclude b/Ghost.Entities/Template/Helpers.ttinclude index 54d8b3b..0759a28 100644 --- a/Ghost.Entities/Template/Helpers.ttinclude +++ b/Ghost.Entities/Template/Helpers.ttinclude @@ -2,8 +2,8 @@ <#@ import namespace="System.Collections.Generic" #> <#+ - public int Amount = 25; - + public int Amount = 8; + public int ExtensionAmount = 3; public string Indent(StringBuilder sb, int spaces) { @@ -11,17 +11,22 @@ return sb.ToString().Replace("\n", "\n" + indent); } - string AppendGenerics(int amount) + string AppendGenerics(int amount, string template) { var sb = new StringBuilder(); for (var i = 0; i < amount; i++) { if (i > 0) sb.Append(", "); - sb.Append($"T{i}"); + sb.Append($"{template}{i}"); } return sb.ToString(); } + string AppendGenerics(int amount) + { + return AppendGenerics(amount, "T"); + } + public StringBuilder AppendGenericRefParameters(int amount) { var sb = new StringBuilder(); @@ -46,12 +51,12 @@ return sb; } - public StringBuilder AppendGenericRestrictions(int amount, string template) + public StringBuilder AppendGenericRestrictions(int amount, string Ttemplate, string template) { var sb = new StringBuilder(); for (var localIndex = 0; localIndex < amount; localIndex++) { - sb.Append($"where T{localIndex} : {template}"); + sb.Append($"where {Ttemplate}{localIndex} : {template}"); if (localIndex < amount - 1) { sb.Append(' '); @@ -60,12 +65,17 @@ return sb; } + public StringBuilder AppendGenericRestrictions(int amount, string template) + { + return AppendGenericRestrictions(amount, "T", template); + } + public StringBuilder TryGetComponentPools(int amount) { var sb = new StringBuilder(); for (var localIndex = 0; localIndex < amount; localIndex++) { - sb.Append($"TryGetPool(out var pool{localIndex})"); + sb.Append($"_componentStorage.TryGetPool(out var pool{localIndex})"); if (localIndex < amount - 1) { sb.Append(" && "); diff --git a/Ghost.Entities/Template/QueryEnumerable.cs b/Ghost.Entities/Template/QueryEnumerable.cs new file mode 100644 index 0000000..247406d --- /dev/null +++ b/Ghost.Entities/Template/QueryEnumerable.cs @@ -0,0 +1,1484 @@ + + +using Ghost.Entities.Query; +using Ghost.Entities.Utilities; +using Misaki.HighPerformance.Unsafe.Collections; + +namespace Ghost.Entities; + +public struct QueryEnumerable + where T0 : struct, IComponentData +{ + private readonly World _world; + + private readonly ComponentPool _pool0; + private readonly int _count; + + private QueryFilter _filters; + internal readonly QueryFilter Filters => _filters; + + internal QueryEnumerable(World world, ComponentPool pool0, int count) + { + _world = world; + + _pool0 = pool0; + + _count = count; + + _filters = new(); + _filters._all.Add(TypeHandle.Value); + } + + public Enumerator GetEnumerator() => new Enumerator(_world, _pool0, _count, _filters); + + public ref struct Enumerator + { + private readonly World _world; + private readonly ReadOnlySpan _entities; + + private readonly ComponentPool _pool0; + + private int _index; + private readonly int _count; + + private BitSet _filterMask; + + public QueryItem Current + { + get; + private set; + } + + internal Enumerator(World world, ComponentPool pool0, int count, QueryFilter filters) + { + _world = world; + _entities = _world.EntityManager.Entities; + + _pool0 = pool0; + + _count = count; + _index = -1; + filters.ComputeFilterBitMask(_world, ref _filterMask); + + Current = default; + } + + public bool MoveNext() + { + _index = _filterMask.NextSetBit(_index + 1); + if (_index < 0 || _index >= _world.EntityManager.EntityCount) + { + return false; + } + + Current = new QueryItem(_entities[_index], _pool0); + return true; + } + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } +} + +public struct QueryEnumerable + where T0 : struct, IComponentData where T1 : struct, IComponentData +{ + private readonly World _world; + + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly int _count; + + private QueryFilter _filters; + internal readonly QueryFilter Filters => _filters; + + internal QueryEnumerable(World world, ComponentPool pool0, ComponentPool pool1, int count) + { + _world = world; + + _pool0 = pool0; + _pool1 = pool1; + + _count = count; + + _filters = new(); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + } + + public Enumerator GetEnumerator() => new Enumerator(_world, _pool0, _pool1, _count, _filters); + + public ref struct Enumerator + { + private readonly World _world; + private readonly ReadOnlySpan _entities; + + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + + private int _index; + private readonly int _count; + + private BitSet _filterMask; + + public QueryItem Current + { + get; + private set; + } + + internal Enumerator(World world, ComponentPool pool0, ComponentPool pool1, int count, QueryFilter filters) + { + _world = world; + _entities = _world.EntityManager.Entities; + + _pool0 = pool0; + _pool1 = pool1; + + _count = count; + _index = -1; + filters.ComputeFilterBitMask(_world, ref _filterMask); + + Current = default; + } + + public bool MoveNext() + { + _index = _filterMask.NextSetBit(_index + 1); + if (_index < 0 || _index >= _world.EntityManager.EntityCount) + { + return false; + } + + Current = new QueryItem(_entities[_index], _pool0, _pool1); + return true; + } + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } +} + +public struct QueryEnumerable + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData +{ + private readonly World _world; + + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly int _count; + + private QueryFilter _filters; + internal readonly QueryFilter Filters => _filters; + + internal QueryEnumerable(World world, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, int count) + { + _world = world; + + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + + _count = count; + + _filters = new(); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + } + + public Enumerator GetEnumerator() => new Enumerator(_world, _pool0, _pool1, _pool2, _count, _filters); + + public ref struct Enumerator + { + private readonly World _world; + private readonly ReadOnlySpan _entities; + + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + + private int _index; + private readonly int _count; + + private BitSet _filterMask; + + public QueryItem Current + { + get; + private set; + } + + internal Enumerator(World world, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, int count, QueryFilter filters) + { + _world = world; + _entities = _world.EntityManager.Entities; + + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + + _count = count; + _index = -1; + filters.ComputeFilterBitMask(_world, ref _filterMask); + + Current = default; + } + + public bool MoveNext() + { + _index = _filterMask.NextSetBit(_index + 1); + if (_index < 0 || _index >= _world.EntityManager.EntityCount) + { + return false; + } + + Current = new QueryItem(_entities[_index], _pool0, _pool1, _pool2); + return true; + } + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } +} + +public struct QueryEnumerable + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData +{ + private readonly World _world; + + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + private readonly int _count; + + private QueryFilter _filters; + internal readonly QueryFilter Filters => _filters; + + internal QueryEnumerable(World world, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3, int count) + { + _world = world; + + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + + _count = count; + + _filters = new(); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + } + + public Enumerator GetEnumerator() => new Enumerator(_world, _pool0, _pool1, _pool2, _pool3, _count, _filters); + + public ref struct Enumerator + { + private readonly World _world; + private readonly ReadOnlySpan _entities; + + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + + private int _index; + private readonly int _count; + + private BitSet _filterMask; + + public QueryItem Current + { + get; + private set; + } + + internal Enumerator(World world, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3, int count, QueryFilter filters) + { + _world = world; + _entities = _world.EntityManager.Entities; + + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + + _count = count; + _index = -1; + filters.ComputeFilterBitMask(_world, ref _filterMask); + + Current = default; + } + + public bool MoveNext() + { + _index = _filterMask.NextSetBit(_index + 1); + if (_index < 0 || _index >= _world.EntityManager.EntityCount) + { + return false; + } + + Current = new QueryItem(_entities[_index], _pool0, _pool1, _pool2, _pool3); + return true; + } + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } +} + +public struct QueryEnumerable + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData +{ + private readonly World _world; + + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + private readonly ComponentPool _pool4; + private readonly int _count; + + private QueryFilter _filters; + internal readonly QueryFilter Filters => _filters; + + internal QueryEnumerable(World world, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3, ComponentPool pool4, int count) + { + _world = world; + + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + _pool4 = pool4; + + _count = count; + + _filters = new(); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + } + + public Enumerator GetEnumerator() => new Enumerator(_world, _pool0, _pool1, _pool2, _pool3, _pool4, _count, _filters); + + public ref struct Enumerator + { + private readonly World _world; + private readonly ReadOnlySpan _entities; + + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + private readonly ComponentPool _pool4; + + private int _index; + private readonly int _count; + + private BitSet _filterMask; + + public QueryItem Current + { + get; + private set; + } + + internal Enumerator(World world, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3, ComponentPool pool4, int count, QueryFilter filters) + { + _world = world; + _entities = _world.EntityManager.Entities; + + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + _pool4 = pool4; + + _count = count; + _index = -1; + filters.ComputeFilterBitMask(_world, ref _filterMask); + + Current = default; + } + + public bool MoveNext() + { + _index = _filterMask.NextSetBit(_index + 1); + if (_index < 0 || _index >= _world.EntityManager.EntityCount) + { + return false; + } + + Current = new QueryItem(_entities[_index], _pool0, _pool1, _pool2, _pool3, _pool4); + return true; + } + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } +} + +public struct QueryEnumerable + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData where T5 : struct, IComponentData +{ + private readonly World _world; + + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + private readonly ComponentPool _pool4; + private readonly ComponentPool _pool5; + private readonly int _count; + + private QueryFilter _filters; + internal readonly QueryFilter Filters => _filters; + + internal QueryEnumerable(World world, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3, ComponentPool pool4, ComponentPool pool5, int count) + { + _world = world; + + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + _pool4 = pool4; + _pool5 = pool5; + + _count = count; + + _filters = new(); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + } + + public Enumerator GetEnumerator() => new Enumerator(_world, _pool0, _pool1, _pool2, _pool3, _pool4, _pool5, _count, _filters); + + public ref struct Enumerator + { + private readonly World _world; + private readonly ReadOnlySpan _entities; + + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + private readonly ComponentPool _pool4; + private readonly ComponentPool _pool5; + + private int _index; + private readonly int _count; + + private BitSet _filterMask; + + public QueryItem Current + { + get; + private set; + } + + internal Enumerator(World world, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3, ComponentPool pool4, ComponentPool pool5, int count, QueryFilter filters) + { + _world = world; + _entities = _world.EntityManager.Entities; + + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + _pool4 = pool4; + _pool5 = pool5; + + _count = count; + _index = -1; + filters.ComputeFilterBitMask(_world, ref _filterMask); + + Current = default; + } + + public bool MoveNext() + { + _index = _filterMask.NextSetBit(_index + 1); + if (_index < 0 || _index >= _world.EntityManager.EntityCount) + { + return false; + } + + Current = new QueryItem(_entities[_index], _pool0, _pool1, _pool2, _pool3, _pool4, _pool5); + return true; + } + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } +} + +public struct QueryEnumerable + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData where T5 : struct, IComponentData where T6 : struct, IComponentData +{ + private readonly World _world; + + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + private readonly ComponentPool _pool4; + private readonly ComponentPool _pool5; + private readonly ComponentPool _pool6; + private readonly int _count; + + private QueryFilter _filters; + internal readonly QueryFilter Filters => _filters; + + internal QueryEnumerable(World world, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3, ComponentPool pool4, ComponentPool pool5, ComponentPool pool6, int count) + { + _world = world; + + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + _pool4 = pool4; + _pool5 = pool5; + _pool6 = pool6; + + _count = count; + + _filters = new(); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + } + + public Enumerator GetEnumerator() => new Enumerator(_world, _pool0, _pool1, _pool2, _pool3, _pool4, _pool5, _pool6, _count, _filters); + + public ref struct Enumerator + { + private readonly World _world; + private readonly ReadOnlySpan _entities; + + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + private readonly ComponentPool _pool4; + private readonly ComponentPool _pool5; + private readonly ComponentPool _pool6; + + private int _index; + private readonly int _count; + + private BitSet _filterMask; + + public QueryItem Current + { + get; + private set; + } + + internal Enumerator(World world, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3, ComponentPool pool4, ComponentPool pool5, ComponentPool pool6, int count, QueryFilter filters) + { + _world = world; + _entities = _world.EntityManager.Entities; + + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + _pool4 = pool4; + _pool5 = pool5; + _pool6 = pool6; + + _count = count; + _index = -1; + filters.ComputeFilterBitMask(_world, ref _filterMask); + + Current = default; + } + + public bool MoveNext() + { + _index = _filterMask.NextSetBit(_index + 1); + if (_index < 0 || _index >= _world.EntityManager.EntityCount) + { + return false; + } + + Current = new QueryItem(_entities[_index], _pool0, _pool1, _pool2, _pool3, _pool4, _pool5, _pool6); + return true; + } + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } +} + +public struct QueryEnumerable + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData where T5 : struct, IComponentData where T6 : struct, IComponentData where T7 : struct, IComponentData +{ + private readonly World _world; + + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + private readonly ComponentPool _pool4; + private readonly ComponentPool _pool5; + private readonly ComponentPool _pool6; + private readonly ComponentPool _pool7; + private readonly int _count; + + private QueryFilter _filters; + internal readonly QueryFilter Filters => _filters; + + internal QueryEnumerable(World world, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3, ComponentPool pool4, ComponentPool pool5, ComponentPool pool6, ComponentPool pool7, int count) + { + _world = world; + + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + _pool4 = pool4; + _pool5 = pool5; + _pool6 = pool6; + _pool7 = pool7; + + _count = count; + + _filters = new(); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + } + + public Enumerator GetEnumerator() => new Enumerator(_world, _pool0, _pool1, _pool2, _pool3, _pool4, _pool5, _pool6, _pool7, _count, _filters); + + public ref struct Enumerator + { + private readonly World _world; + private readonly ReadOnlySpan _entities; + + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + private readonly ComponentPool _pool4; + private readonly ComponentPool _pool5; + private readonly ComponentPool _pool6; + private readonly ComponentPool _pool7; + + private int _index; + private readonly int _count; + + private BitSet _filterMask; + + public QueryItem Current + { + get; + private set; + } + + internal Enumerator(World world, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3, ComponentPool pool4, ComponentPool pool5, ComponentPool pool6, ComponentPool pool7, int count, QueryFilter filters) + { + _world = world; + _entities = _world.EntityManager.Entities; + + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + _pool4 = pool4; + _pool5 = pool5; + _pool6 = pool6; + _pool7 = pool7; + + _count = count; + _index = -1; + filters.ComputeFilterBitMask(_world, ref _filterMask); + + Current = default; + } + + public bool MoveNext() + { + _index = _filterMask.NextSetBit(_index + 1); + if (_index < 0 || _index >= _world.EntityManager.EntityCount) + { + return false; + } + + Current = new QueryItem(_entities[_index], _pool0, _pool1, _pool2, _pool3, _pool4, _pool5, _pool6, _pool7); + return true; + } + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAll() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + _filters._all.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAny() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + _filters._any.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithAbsent() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + _filters._absent.Add(TypeHandle.Value); + return this; + } + + public readonly QueryEnumerable WithDisabled() + where TComponent0 : struct, IComponentData where TComponent1 : struct, IComponentData where TComponent2 : struct, IComponentData + { + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + _filters._disabled.Add(TypeHandle.Value); + return this; + } +} + diff --git a/Ghost.Entities/Template/QueryEnumerable.tt b/Ghost.Entities/Template/QueryEnumerable.tt new file mode 100644 index 0000000..26913ad --- /dev/null +++ b/Ghost.Entities/Template/QueryEnumerable.tt @@ -0,0 +1,147 @@ +<#@ template language="C#" #> +<#@ output extension=".cs" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Linq" #> +<#@ include file="Helpers.ttinclude" #> + +using Ghost.Entities.Query; +using Ghost.Entities.Utilities; +using Misaki.HighPerformance.Unsafe.Collections; + +namespace Ghost.Entities; + +<# for (int arity = 1; arity <= Amount; arity++) { +var generics = AppendGenerics(arity); +var restrictions = AppendGenericRestrictions(arity, "struct, IComponentData"); +var poolParams = Enumerable.Range(0, arity) + .Select(i => $"ComponentPool pool{i}") + .Aggregate((a, b) => a + ", " + b); +var constructorParams = Enumerable.Range(0, arity) + .Select(i => $"_pool{i}") + .Aggregate((a, b) => a + ", " + b); + +#> +public struct QueryEnumerable<<#= generics #>> + <#= restrictions #> +{ + private readonly World _world; + +<# for (int i = 0; i < arity; i++){ #> + private readonly ComponentPool> _pool<#= i #>; +<# } #> + private readonly int _count; + + private QueryFilter _filters; + internal readonly QueryFilter Filters => _filters; + + internal QueryEnumerable(World world, <#= poolParams #>, int count) + { + _world = world; + +<# for (int i = 0; i < arity; i++) { #> + _pool<#= i #> = pool<#= i #>; +<# } #> + + _count = count; + + _filters = new(); +<# for (int i = 0; i < arity; i++) {#> + _filters._all.Add(TypeHandle>.Value); +<# } #> + } + + public Enumerator GetEnumerator() => new Enumerator(_world, <#= constructorParams #>, _count, _filters); + + public ref struct Enumerator + { + private readonly World _world; + private readonly ReadOnlySpan _entities; + +<# for (int i = 0; i < arity; i++){ #> + private readonly ComponentPool> _pool<#= i #>; +<# } #> + + private int _index; + private readonly int _count; + + private BitSet _filterMask; + + public QueryItem<<#= generics #>> Current + { + get; + private set; + } + + internal Enumerator(World world, <#= poolParams #>, int count, QueryFilter filters) + { + _world = world; + _entities = _world.EntityManager.Entities; + +<# for (int i = 0; i < arity; i++){ #> + _pool<#= i #> = pool<#= i #>; +<# } #> + + _count = count; + _index = -1; + filters.ComputeFilterBitMask(_world, ref _filterMask); + + Current = default; + } + + public bool MoveNext() + { + _index = _filterMask.NextSetBit(_index + 1); + if (_index < 0 || _index >= _world.EntityManager.EntityCount) + { + return false; + } + + Current = new QueryItem<<#= generics #>>(_entities[_index], <#= constructorParams #>); + return true; + } + } +<# for (int i = 1; i <= ExtensionAmount; i++) { +var compGenerics = AppendGenerics(i, "TComponent"); +var compRestrictions = AppendGenericRestrictions(i, "TComponent", "struct, IComponentData"); +#> + + public readonly QueryEnumerable<<#= generics #>> WithAll<<#= compGenerics #>>() + <#= compRestrictions #> + { +<# for (int j = 0; j < i; j++) {#> + _filters._all.Add(TypeHandle>.Value); +<# } #> + return this; + } + + public readonly QueryEnumerable<<#= generics #>> WithAny<<#= compGenerics #>>() + <#= compRestrictions #> + { +<# for (int j = 0; j < i; j++) {#> + _filters._any.Add(TypeHandle>.Value); +<# } #> + return this; + } + + public readonly QueryEnumerable<<#= generics #>> WithAbsent<<#= compGenerics #>>() + <#= compRestrictions #> + { +<# for (int j = 0; j < i; j++) {#> + _filters._absent.Add(TypeHandle>.Value); +<# } #> + return this; + } + + public readonly QueryEnumerable<<#= generics #>> WithDisabled<<#= compGenerics #>>() + <#= compRestrictions #> + { +<# for (int j = 0; j < i; j++) {#> + _filters._disabled.Add(TypeHandle>.Value); +<# } #> + return this; + } +<# } #> +} + +<# } #> \ No newline at end of file diff --git a/Ghost.Entities/Template/QueryItem.cs b/Ghost.Entities/Template/QueryItem.cs new file mode 100644 index 0000000..87b0053 --- /dev/null +++ b/Ghost.Entities/Template/QueryItem.cs @@ -0,0 +1,282 @@ + + +using Ghost.Entities.Query; + +namespace Ghost.Entities; + +public readonly struct QueryItem + where T0 : struct, IComponentData +{ + private readonly Entity _entity; + private readonly ComponentPool _pool0; + + internal QueryItem(Entity entity, ComponentPool pool0) + { + _entity = entity; + _pool0 = pool0; + } + + public Entity Entity => _entity; + + public ref T0 Component0 => ref _pool0.GetRef(_entity); + + // Deconstruct into tuple-like values + public void Deconstruct(out Entity entity, out Ref c0) + { + entity = _entity; + c0 = new (ref _pool0.GetRef(_entity)); + } +} + +public readonly struct QueryItem + where T0 : struct, IComponentData where T1 : struct, IComponentData +{ + private readonly Entity _entity; + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + + internal QueryItem(Entity entity, ComponentPool pool0, ComponentPool pool1) + { + _entity = entity; + _pool0 = pool0; + _pool1 = pool1; + } + + public Entity Entity => _entity; + + public ref T0 Component0 => ref _pool0.GetRef(_entity); + public ref T1 Component1 => ref _pool1.GetRef(_entity); + + // Deconstruct into tuple-like values + public void Deconstruct(out Entity entity, out Ref c0, out Ref c1) + { + entity = _entity; + c0 = new (ref _pool0.GetRef(_entity));c1 = new (ref _pool1.GetRef(_entity)); + } +} + +public readonly struct QueryItem + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData +{ + private readonly Entity _entity; + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + + internal QueryItem(Entity entity, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2) + { + _entity = entity; + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + } + + public Entity Entity => _entity; + + public ref T0 Component0 => ref _pool0.GetRef(_entity); + public ref T1 Component1 => ref _pool1.GetRef(_entity); + public ref T2 Component2 => ref _pool2.GetRef(_entity); + + // Deconstruct into tuple-like values + public void Deconstruct(out Entity entity, out Ref c0, out Ref c1, out Ref c2) + { + entity = _entity; + c0 = new (ref _pool0.GetRef(_entity));c1 = new (ref _pool1.GetRef(_entity));c2 = new (ref _pool2.GetRef(_entity)); + } +} + +public readonly struct QueryItem + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData +{ + private readonly Entity _entity; + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + + internal QueryItem(Entity entity, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3) + { + _entity = entity; + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + } + + public Entity Entity => _entity; + + public ref T0 Component0 => ref _pool0.GetRef(_entity); + public ref T1 Component1 => ref _pool1.GetRef(_entity); + public ref T2 Component2 => ref _pool2.GetRef(_entity); + public ref T3 Component3 => ref _pool3.GetRef(_entity); + + // Deconstruct into tuple-like values + public void Deconstruct(out Entity entity, out Ref c0, out Ref c1, out Ref c2, out Ref c3) + { + entity = _entity; + c0 = new (ref _pool0.GetRef(_entity));c1 = new (ref _pool1.GetRef(_entity));c2 = new (ref _pool2.GetRef(_entity));c3 = new (ref _pool3.GetRef(_entity)); + } +} + +public readonly struct QueryItem + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData +{ + private readonly Entity _entity; + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + private readonly ComponentPool _pool4; + + internal QueryItem(Entity entity, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3, ComponentPool pool4) + { + _entity = entity; + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + _pool4 = pool4; + } + + public Entity Entity => _entity; + + public ref T0 Component0 => ref _pool0.GetRef(_entity); + public ref T1 Component1 => ref _pool1.GetRef(_entity); + public ref T2 Component2 => ref _pool2.GetRef(_entity); + public ref T3 Component3 => ref _pool3.GetRef(_entity); + public ref T4 Component4 => ref _pool4.GetRef(_entity); + + // Deconstruct into tuple-like values + public void Deconstruct(out Entity entity, out Ref c0, out Ref c1, out Ref c2, out Ref c3, out Ref c4) + { + entity = _entity; + c0 = new (ref _pool0.GetRef(_entity));c1 = new (ref _pool1.GetRef(_entity));c2 = new (ref _pool2.GetRef(_entity));c3 = new (ref _pool3.GetRef(_entity));c4 = new (ref _pool4.GetRef(_entity)); + } +} + +public readonly struct QueryItem + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData where T5 : struct, IComponentData +{ + private readonly Entity _entity; + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + private readonly ComponentPool _pool4; + private readonly ComponentPool _pool5; + + internal QueryItem(Entity entity, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3, ComponentPool pool4, ComponentPool pool5) + { + _entity = entity; + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + _pool4 = pool4; + _pool5 = pool5; + } + + public Entity Entity => _entity; + + public ref T0 Component0 => ref _pool0.GetRef(_entity); + public ref T1 Component1 => ref _pool1.GetRef(_entity); + public ref T2 Component2 => ref _pool2.GetRef(_entity); + public ref T3 Component3 => ref _pool3.GetRef(_entity); + public ref T4 Component4 => ref _pool4.GetRef(_entity); + public ref T5 Component5 => ref _pool5.GetRef(_entity); + + // Deconstruct into tuple-like values + public void Deconstruct(out Entity entity, out Ref c0, out Ref c1, out Ref c2, out Ref c3, out Ref c4, out Ref c5) + { + entity = _entity; + c0 = new (ref _pool0.GetRef(_entity));c1 = new (ref _pool1.GetRef(_entity));c2 = new (ref _pool2.GetRef(_entity));c3 = new (ref _pool3.GetRef(_entity));c4 = new (ref _pool4.GetRef(_entity));c5 = new (ref _pool5.GetRef(_entity)); + } +} + +public readonly struct QueryItem + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData where T5 : struct, IComponentData where T6 : struct, IComponentData +{ + private readonly Entity _entity; + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + private readonly ComponentPool _pool4; + private readonly ComponentPool _pool5; + private readonly ComponentPool _pool6; + + internal QueryItem(Entity entity, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3, ComponentPool pool4, ComponentPool pool5, ComponentPool pool6) + { + _entity = entity; + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + _pool4 = pool4; + _pool5 = pool5; + _pool6 = pool6; + } + + public Entity Entity => _entity; + + public ref T0 Component0 => ref _pool0.GetRef(_entity); + public ref T1 Component1 => ref _pool1.GetRef(_entity); + public ref T2 Component2 => ref _pool2.GetRef(_entity); + public ref T3 Component3 => ref _pool3.GetRef(_entity); + public ref T4 Component4 => ref _pool4.GetRef(_entity); + public ref T5 Component5 => ref _pool5.GetRef(_entity); + public ref T6 Component6 => ref _pool6.GetRef(_entity); + + // Deconstruct into tuple-like values + public void Deconstruct(out Entity entity, out Ref c0, out Ref c1, out Ref c2, out Ref c3, out Ref c4, out Ref c5, out Ref c6) + { + entity = _entity; + c0 = new (ref _pool0.GetRef(_entity));c1 = new (ref _pool1.GetRef(_entity));c2 = new (ref _pool2.GetRef(_entity));c3 = new (ref _pool3.GetRef(_entity));c4 = new (ref _pool4.GetRef(_entity));c5 = new (ref _pool5.GetRef(_entity));c6 = new (ref _pool6.GetRef(_entity)); + } +} + +public readonly struct QueryItem + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData where T5 : struct, IComponentData where T6 : struct, IComponentData where T7 : struct, IComponentData +{ + private readonly Entity _entity; + private readonly ComponentPool _pool0; + private readonly ComponentPool _pool1; + private readonly ComponentPool _pool2; + private readonly ComponentPool _pool3; + private readonly ComponentPool _pool4; + private readonly ComponentPool _pool5; + private readonly ComponentPool _pool6; + private readonly ComponentPool _pool7; + + internal QueryItem(Entity entity, ComponentPool pool0, ComponentPool pool1, ComponentPool pool2, ComponentPool pool3, ComponentPool pool4, ComponentPool pool5, ComponentPool pool6, ComponentPool pool7) + { + _entity = entity; + _pool0 = pool0; + _pool1 = pool1; + _pool2 = pool2; + _pool3 = pool3; + _pool4 = pool4; + _pool5 = pool5; + _pool6 = pool6; + _pool7 = pool7; + } + + public Entity Entity => _entity; + + public ref T0 Component0 => ref _pool0.GetRef(_entity); + public ref T1 Component1 => ref _pool1.GetRef(_entity); + public ref T2 Component2 => ref _pool2.GetRef(_entity); + public ref T3 Component3 => ref _pool3.GetRef(_entity); + public ref T4 Component4 => ref _pool4.GetRef(_entity); + public ref T5 Component5 => ref _pool5.GetRef(_entity); + public ref T6 Component6 => ref _pool6.GetRef(_entity); + public ref T7 Component7 => ref _pool7.GetRef(_entity); + + // Deconstruct into tuple-like values + public void Deconstruct(out Entity entity, out Ref c0, out Ref c1, out Ref c2, out Ref c3, out Ref c4, out Ref c5, out Ref c6, out Ref c7) + { + entity = _entity; + c0 = new (ref _pool0.GetRef(_entity));c1 = new (ref _pool1.GetRef(_entity));c2 = new (ref _pool2.GetRef(_entity));c3 = new (ref _pool3.GetRef(_entity));c4 = new (ref _pool4.GetRef(_entity));c5 = new (ref _pool5.GetRef(_entity));c6 = new (ref _pool6.GetRef(_entity));c7 = new (ref _pool7.GetRef(_entity)); + } +} + diff --git a/Ghost.Entities/Template/QueryItem.tt b/Ghost.Entities/Template/QueryItem.tt new file mode 100644 index 0000000..5f01192 --- /dev/null +++ b/Ghost.Entities/Template/QueryItem.tt @@ -0,0 +1,63 @@ +<#@ template language="C#" debug="false" hostspecific="true" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ include file="Helpers.ttinclude" #> +<#@ output extension=".cs" #> + +using Ghost.Entities.Query; + +namespace Ghost.Entities; + +<# for (int arity = 1; arity <= Amount; arity++) +{ +var generics = AppendGenerics(arity); +var restrictions = AppendGenericRestrictions(arity, "struct, IComponentData"); +var constructorParams = Enumerable.Range(0, arity) + .Select(i => $"ComponentPool pool{i}") + .Aggregate((a, b) => a + ", " + b); +var deconstructParams = Enumerable.Range(0, arity) + .Select(i => { + var name = $"c{i}"; + return arity == 1 + ? $"out Ref {name}" + : $"out Ref {name}"; + }) + .Aggregate((a, b) => a + ", " + b); +var deconstructAssigns = Enumerable.Range(0, arity) + .Select(i => { + var name = $"c{i}"; + return $"{name} = new (ref _pool{i}.GetRef(_entity));"; + }) + .Aggregate((a, b) => a + b); +#> +public readonly struct QueryItem<<#= generics #>> + <#= restrictions #> +{ + private readonly Entity _entity; +<# for (int i = 0; i < arity; i++){ #> + private readonly ComponentPool> _pool<#= i #>; +<# } #> + + internal QueryItem(Entity entity, <#= constructorParams #>) + { + _entity = entity; +<# for (int i = 0; i < arity; i++){ #> + _pool<#= i #> = pool<#= i #>; +<# } #> + } + + public Entity Entity => _entity; + +<# for (int i = 0; i < arity; i++){ #> + public ref T<#= i #> Component<#= i #> => ref _pool<#= i #>.GetRef(_entity); +<# } #> + + // Deconstruct into tuple-like values + public void Deconstruct(out Entity entity, <#= deconstructParams #>) + { + entity = _entity; + <#= deconstructAssigns #> + } +} + +<# } #> diff --git a/Ghost.Entities/Template/QueryRefComponent.cs b/Ghost.Entities/Template/QueryRefComponent.cs index 3f6e9da..397c77f 100644 --- a/Ghost.Entities/Template/QueryRefComponent.cs +++ b/Ghost.Entities/Template/QueryRefComponent.cs @@ -3,52 +3,18 @@ namespace Ghost.Entities; public delegate void QueryRefComponent(Entity entity, ref T0 t0Component) - where T0 : struct, IComponent; + where T0 : struct, IComponentData; public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component) - where T0 : struct, IComponent where T1 : struct, IComponent; + where T0 : struct, IComponentData where T1 : struct, IComponentData; public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent; + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData; public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent; + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData; public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent; + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData; public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent; + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData where T5 : struct, IComponentData; public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent; + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData where T5 : struct, IComponentData where T6 : struct, IComponentData; public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component,ref T11 t11Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component,ref T11 t11Component,ref T12 t12Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component,ref T11 t11Component,ref T12 t12Component,ref T13 t13Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component,ref T11 t11Component,ref T12 t12Component,ref T13 t13Component,ref T14 t14Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component,ref T11 t11Component,ref T12 t12Component,ref T13 t13Component,ref T14 t14Component,ref T15 t15Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component,ref T11 t11Component,ref T12 t12Component,ref T13 t13Component,ref T14 t14Component,ref T15 t15Component,ref T16 t16Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component,ref T11 t11Component,ref T12 t12Component,ref T13 t13Component,ref T14 t14Component,ref T15 t15Component,ref T16 t16Component,ref T17 t17Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component,ref T11 t11Component,ref T12 t12Component,ref T13 t13Component,ref T14 t14Component,ref T15 t15Component,ref T16 t16Component,ref T17 t17Component,ref T18 t18Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent where T18 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component,ref T11 t11Component,ref T12 t12Component,ref T13 t13Component,ref T14 t14Component,ref T15 t15Component,ref T16 t16Component,ref T17 t17Component,ref T18 t18Component,ref T19 t19Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent where T18 : struct, IComponent where T19 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component,ref T11 t11Component,ref T12 t12Component,ref T13 t13Component,ref T14 t14Component,ref T15 t15Component,ref T16 t16Component,ref T17 t17Component,ref T18 t18Component,ref T19 t19Component,ref T20 t20Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent where T18 : struct, IComponent where T19 : struct, IComponent where T20 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component,ref T11 t11Component,ref T12 t12Component,ref T13 t13Component,ref T14 t14Component,ref T15 t15Component,ref T16 t16Component,ref T17 t17Component,ref T18 t18Component,ref T19 t19Component,ref T20 t20Component,ref T21 t21Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent where T18 : struct, IComponent where T19 : struct, IComponent where T20 : struct, IComponent where T21 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component,ref T11 t11Component,ref T12 t12Component,ref T13 t13Component,ref T14 t14Component,ref T15 t15Component,ref T16 t16Component,ref T17 t17Component,ref T18 t18Component,ref T19 t19Component,ref T20 t20Component,ref T21 t21Component,ref T22 t22Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent where T18 : struct, IComponent where T19 : struct, IComponent where T20 : struct, IComponent where T21 : struct, IComponent where T22 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component,ref T11 t11Component,ref T12 t12Component,ref T13 t13Component,ref T14 t14Component,ref T15 t15Component,ref T16 t16Component,ref T17 t17Component,ref T18 t18Component,ref T19 t19Component,ref T20 t20Component,ref T21 t21Component,ref T22 t22Component,ref T23 t23Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent where T18 : struct, IComponent where T19 : struct, IComponent where T20 : struct, IComponent where T21 : struct, IComponent where T22 : struct, IComponent where T23 : struct, IComponent; -public delegate void QueryRefComponent(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component,ref T8 t8Component,ref T9 t9Component,ref T10 t10Component,ref T11 t11Component,ref T12 t12Component,ref T13 t13Component,ref T14 t14Component,ref T15 t15Component,ref T16 t16Component,ref T17 t17Component,ref T18 t18Component,ref T19 t19Component,ref T20 t20Component,ref T21 t21Component,ref T22 t22Component,ref T23 t23Component,ref T24 t24Component) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent where T18 : struct, IComponent where T19 : struct, IComponent where T20 : struct, IComponent where T21 : struct, IComponent where T22 : struct, IComponent where T23 : struct, IComponent where T24 : struct, IComponent; + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData where T5 : struct, IComponentData where T6 : struct, IComponentData where T7 : struct, IComponentData; diff --git a/Ghost.Entities/Template/QueryRefComponent.tt b/Ghost.Entities/Template/QueryRefComponent.tt index 1b49ef5..2efa1ef 100644 --- a/Ghost.Entities/Template/QueryRefComponent.tt +++ b/Ghost.Entities/Template/QueryRefComponent.tt @@ -10,7 +10,7 @@ for (var index = 1; index <= Amount; index++) { var generics = AppendGenerics(index); var parameters = AppendGenericRefParameters(index); - var restrictions = AppendGenericRestrictions(index, "struct, IComponent"); + var restrictions = AppendGenericRestrictions(index, "struct, IComponentData"); #> public delegate void QueryRefComponent<<#= generics #>>(Entity entity, <#= parameters.ToString() #>) <#= restrictions.ToString() #>; diff --git a/Ghost.Entities/Template/World.Query.cs b/Ghost.Entities/Template/World.Query.cs index 69cdad0..ea7a192 100644 --- a/Ghost.Entities/Template/World.Query.cs +++ b/Ghost.Entities/Template/World.Query.cs @@ -2,501 +2,102 @@ namespace Ghost.Entities; -public partial struct World +public partial class World { - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent + public QueryEnumerable Query() + where T0 : struct, IComponentData { - if (!(TryGetPool(out var pool0))) - { - return; - } + if (!(_componentStorage.TryGetPool(out var pool0))) + return default; - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - callback(entity, ref pool0.GetRef(entity)); - } + return new QueryEnumerable( + this, + pool0, + pool0.Count); } - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent + public QueryEnumerable Query() + where T0 : struct, IComponentData where T1 : struct, IComponentData { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1))) - { - return; - } + if (!(_componentStorage.TryGetPool(out var pool0) && _componentStorage.TryGetPool(out var pool1))) + return default; - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity)); - } + return new QueryEnumerable( + this, + pool0, pool1, + pool0.Count); } - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent + public QueryEnumerable Query() + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2))) - { - return; - } + if (!(_componentStorage.TryGetPool(out var pool0) && _componentStorage.TryGetPool(out var pool1) && _componentStorage.TryGetPool(out var pool2))) + return default; - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity)); - } + return new QueryEnumerable( + this, + pool0, pool1, pool2, + pool0.Count); } - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent + public QueryEnumerable Query() + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3))) - { - return; - } + if (!(_componentStorage.TryGetPool(out var pool0) && _componentStorage.TryGetPool(out var pool1) && _componentStorage.TryGetPool(out var pool2) && _componentStorage.TryGetPool(out var pool3))) + return default; - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity)); - } + return new QueryEnumerable( + this, + pool0, pool1, pool2, pool3, + pool0.Count); } - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent + public QueryEnumerable Query() + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4))) - { - return; - } + if (!(_componentStorage.TryGetPool(out var pool0) && _componentStorage.TryGetPool(out var pool1) && _componentStorage.TryGetPool(out var pool2) && _componentStorage.TryGetPool(out var pool3) && _componentStorage.TryGetPool(out var pool4))) + return default; - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity)); - } + return new QueryEnumerable( + this, + pool0, pool1, pool2, pool3, pool4, + pool0.Count); } - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent + public QueryEnumerable Query() + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData where T5 : struct, IComponentData { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5))) - { - return; - } + if (!(_componentStorage.TryGetPool(out var pool0) && _componentStorage.TryGetPool(out var pool1) && _componentStorage.TryGetPool(out var pool2) && _componentStorage.TryGetPool(out var pool3) && _componentStorage.TryGetPool(out var pool4) && _componentStorage.TryGetPool(out var pool5))) + return default; - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity)); - } + return new QueryEnumerable( + this, + pool0, pool1, pool2, pool3, pool4, pool5, + pool0.Count); } - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent + public QueryEnumerable Query() + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData where T5 : struct, IComponentData where T6 : struct, IComponentData { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6))) - { - return; - } + if (!(_componentStorage.TryGetPool(out var pool0) && _componentStorage.TryGetPool(out var pool1) && _componentStorage.TryGetPool(out var pool2) && _componentStorage.TryGetPool(out var pool3) && _componentStorage.TryGetPool(out var pool4) && _componentStorage.TryGetPool(out var pool5) && _componentStorage.TryGetPool(out var pool6))) + return default; - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity)); - } + return new QueryEnumerable( + this, + pool0, pool1, pool2, pool3, pool4, pool5, pool6, + pool0.Count); } - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent + public QueryEnumerable Query() + where T0 : struct, IComponentData where T1 : struct, IComponentData where T2 : struct, IComponentData where T3 : struct, IComponentData where T4 : struct, IComponentData where T5 : struct, IComponentData where T6 : struct, IComponentData where T7 : struct, IComponentData { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7))) - { - return; - } + if (!(_componentStorage.TryGetPool(out var pool0) && _componentStorage.TryGetPool(out var pool1) && _componentStorage.TryGetPool(out var pool2) && _componentStorage.TryGetPool(out var pool3) && _componentStorage.TryGetPool(out var pool4) && _componentStorage.TryGetPool(out var pool5) && _componentStorage.TryGetPool(out var pool6) && _componentStorage.TryGetPool(out var pool7))) + return default; - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10) && TryGetPool(out var pool11))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity) && pool11.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity), ref pool11.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10) && TryGetPool(out var pool11) && TryGetPool(out var pool12))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity) && pool11.Has(entity) && pool12.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity), ref pool11.GetRef(entity), ref pool12.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10) && TryGetPool(out var pool11) && TryGetPool(out var pool12) && TryGetPool(out var pool13))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity) && pool11.Has(entity) && pool12.Has(entity) && pool13.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity), ref pool11.GetRef(entity), ref pool12.GetRef(entity), ref pool13.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10) && TryGetPool(out var pool11) && TryGetPool(out var pool12) && TryGetPool(out var pool13) && TryGetPool(out var pool14))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity) && pool11.Has(entity) && pool12.Has(entity) && pool13.Has(entity) && pool14.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity), ref pool11.GetRef(entity), ref pool12.GetRef(entity), ref pool13.GetRef(entity), ref pool14.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10) && TryGetPool(out var pool11) && TryGetPool(out var pool12) && TryGetPool(out var pool13) && TryGetPool(out var pool14) && TryGetPool(out var pool15))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity) && pool11.Has(entity) && pool12.Has(entity) && pool13.Has(entity) && pool14.Has(entity) && pool15.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity), ref pool11.GetRef(entity), ref pool12.GetRef(entity), ref pool13.GetRef(entity), ref pool14.GetRef(entity), ref pool15.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10) && TryGetPool(out var pool11) && TryGetPool(out var pool12) && TryGetPool(out var pool13) && TryGetPool(out var pool14) && TryGetPool(out var pool15) && TryGetPool(out var pool16))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity) && pool11.Has(entity) && pool12.Has(entity) && pool13.Has(entity) && pool14.Has(entity) && pool15.Has(entity) && pool16.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity), ref pool11.GetRef(entity), ref pool12.GetRef(entity), ref pool13.GetRef(entity), ref pool14.GetRef(entity), ref pool15.GetRef(entity), ref pool16.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10) && TryGetPool(out var pool11) && TryGetPool(out var pool12) && TryGetPool(out var pool13) && TryGetPool(out var pool14) && TryGetPool(out var pool15) && TryGetPool(out var pool16) && TryGetPool(out var pool17))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity) && pool11.Has(entity) && pool12.Has(entity) && pool13.Has(entity) && pool14.Has(entity) && pool15.Has(entity) && pool16.Has(entity) && pool17.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity), ref pool11.GetRef(entity), ref pool12.GetRef(entity), ref pool13.GetRef(entity), ref pool14.GetRef(entity), ref pool15.GetRef(entity), ref pool16.GetRef(entity), ref pool17.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent where T18 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10) && TryGetPool(out var pool11) && TryGetPool(out var pool12) && TryGetPool(out var pool13) && TryGetPool(out var pool14) && TryGetPool(out var pool15) && TryGetPool(out var pool16) && TryGetPool(out var pool17) && TryGetPool(out var pool18))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity) && pool11.Has(entity) && pool12.Has(entity) && pool13.Has(entity) && pool14.Has(entity) && pool15.Has(entity) && pool16.Has(entity) && pool17.Has(entity) && pool18.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity), ref pool11.GetRef(entity), ref pool12.GetRef(entity), ref pool13.GetRef(entity), ref pool14.GetRef(entity), ref pool15.GetRef(entity), ref pool16.GetRef(entity), ref pool17.GetRef(entity), ref pool18.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent where T18 : struct, IComponent where T19 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10) && TryGetPool(out var pool11) && TryGetPool(out var pool12) && TryGetPool(out var pool13) && TryGetPool(out var pool14) && TryGetPool(out var pool15) && TryGetPool(out var pool16) && TryGetPool(out var pool17) && TryGetPool(out var pool18) && TryGetPool(out var pool19))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity) && pool11.Has(entity) && pool12.Has(entity) && pool13.Has(entity) && pool14.Has(entity) && pool15.Has(entity) && pool16.Has(entity) && pool17.Has(entity) && pool18.Has(entity) && pool19.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity), ref pool11.GetRef(entity), ref pool12.GetRef(entity), ref pool13.GetRef(entity), ref pool14.GetRef(entity), ref pool15.GetRef(entity), ref pool16.GetRef(entity), ref pool17.GetRef(entity), ref pool18.GetRef(entity), ref pool19.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent where T18 : struct, IComponent where T19 : struct, IComponent where T20 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10) && TryGetPool(out var pool11) && TryGetPool(out var pool12) && TryGetPool(out var pool13) && TryGetPool(out var pool14) && TryGetPool(out var pool15) && TryGetPool(out var pool16) && TryGetPool(out var pool17) && TryGetPool(out var pool18) && TryGetPool(out var pool19) && TryGetPool(out var pool20))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity) && pool11.Has(entity) && pool12.Has(entity) && pool13.Has(entity) && pool14.Has(entity) && pool15.Has(entity) && pool16.Has(entity) && pool17.Has(entity) && pool18.Has(entity) && pool19.Has(entity) && pool20.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity), ref pool11.GetRef(entity), ref pool12.GetRef(entity), ref pool13.GetRef(entity), ref pool14.GetRef(entity), ref pool15.GetRef(entity), ref pool16.GetRef(entity), ref pool17.GetRef(entity), ref pool18.GetRef(entity), ref pool19.GetRef(entity), ref pool20.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent where T18 : struct, IComponent where T19 : struct, IComponent where T20 : struct, IComponent where T21 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10) && TryGetPool(out var pool11) && TryGetPool(out var pool12) && TryGetPool(out var pool13) && TryGetPool(out var pool14) && TryGetPool(out var pool15) && TryGetPool(out var pool16) && TryGetPool(out var pool17) && TryGetPool(out var pool18) && TryGetPool(out var pool19) && TryGetPool(out var pool20) && TryGetPool(out var pool21))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity) && pool11.Has(entity) && pool12.Has(entity) && pool13.Has(entity) && pool14.Has(entity) && pool15.Has(entity) && pool16.Has(entity) && pool17.Has(entity) && pool18.Has(entity) && pool19.Has(entity) && pool20.Has(entity) && pool21.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity), ref pool11.GetRef(entity), ref pool12.GetRef(entity), ref pool13.GetRef(entity), ref pool14.GetRef(entity), ref pool15.GetRef(entity), ref pool16.GetRef(entity), ref pool17.GetRef(entity), ref pool18.GetRef(entity), ref pool19.GetRef(entity), ref pool20.GetRef(entity), ref pool21.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent where T18 : struct, IComponent where T19 : struct, IComponent where T20 : struct, IComponent where T21 : struct, IComponent where T22 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10) && TryGetPool(out var pool11) && TryGetPool(out var pool12) && TryGetPool(out var pool13) && TryGetPool(out var pool14) && TryGetPool(out var pool15) && TryGetPool(out var pool16) && TryGetPool(out var pool17) && TryGetPool(out var pool18) && TryGetPool(out var pool19) && TryGetPool(out var pool20) && TryGetPool(out var pool21) && TryGetPool(out var pool22))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity) && pool11.Has(entity) && pool12.Has(entity) && pool13.Has(entity) && pool14.Has(entity) && pool15.Has(entity) && pool16.Has(entity) && pool17.Has(entity) && pool18.Has(entity) && pool19.Has(entity) && pool20.Has(entity) && pool21.Has(entity) && pool22.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity), ref pool11.GetRef(entity), ref pool12.GetRef(entity), ref pool13.GetRef(entity), ref pool14.GetRef(entity), ref pool15.GetRef(entity), ref pool16.GetRef(entity), ref pool17.GetRef(entity), ref pool18.GetRef(entity), ref pool19.GetRef(entity), ref pool20.GetRef(entity), ref pool21.GetRef(entity), ref pool22.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent where T18 : struct, IComponent where T19 : struct, IComponent where T20 : struct, IComponent where T21 : struct, IComponent where T22 : struct, IComponent where T23 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10) && TryGetPool(out var pool11) && TryGetPool(out var pool12) && TryGetPool(out var pool13) && TryGetPool(out var pool14) && TryGetPool(out var pool15) && TryGetPool(out var pool16) && TryGetPool(out var pool17) && TryGetPool(out var pool18) && TryGetPool(out var pool19) && TryGetPool(out var pool20) && TryGetPool(out var pool21) && TryGetPool(out var pool22) && TryGetPool(out var pool23))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity) && pool11.Has(entity) && pool12.Has(entity) && pool13.Has(entity) && pool14.Has(entity) && pool15.Has(entity) && pool16.Has(entity) && pool17.Has(entity) && pool18.Has(entity) && pool19.Has(entity) && pool20.Has(entity) && pool21.Has(entity) && pool22.Has(entity) && pool23.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity), ref pool11.GetRef(entity), ref pool12.GetRef(entity), ref pool13.GetRef(entity), ref pool14.GetRef(entity), ref pool15.GetRef(entity), ref pool16.GetRef(entity), ref pool17.GetRef(entity), ref pool18.GetRef(entity), ref pool19.GetRef(entity), ref pool20.GetRef(entity), ref pool21.GetRef(entity), ref pool22.GetRef(entity), ref pool23.GetRef(entity)); - } - } - - public readonly void Query(QueryRefComponent callback) - where T0 : struct, IComponent where T1 : struct, IComponent where T2 : struct, IComponent where T3 : struct, IComponent where T4 : struct, IComponent where T5 : struct, IComponent where T6 : struct, IComponent where T7 : struct, IComponent where T8 : struct, IComponent where T9 : struct, IComponent where T10 : struct, IComponent where T11 : struct, IComponent where T12 : struct, IComponent where T13 : struct, IComponent where T14 : struct, IComponent where T15 : struct, IComponent where T16 : struct, IComponent where T17 : struct, IComponent where T18 : struct, IComponent where T19 : struct, IComponent where T20 : struct, IComponent where T21 : struct, IComponent where T22 : struct, IComponent where T23 : struct, IComponent where T24 : struct, IComponent - { - if (!(TryGetPool(out var pool0) && TryGetPool(out var pool1) && TryGetPool(out var pool2) && TryGetPool(out var pool3) && TryGetPool(out var pool4) && TryGetPool(out var pool5) && TryGetPool(out var pool6) && TryGetPool(out var pool7) && TryGetPool(out var pool8) && TryGetPool(out var pool9) && TryGetPool(out var pool10) && TryGetPool(out var pool11) && TryGetPool(out var pool12) && TryGetPool(out var pool13) && TryGetPool(out var pool14) && TryGetPool(out var pool15) && TryGetPool(out var pool16) && TryGetPool(out var pool17) && TryGetPool(out var pool18) && TryGetPool(out var pool19) && TryGetPool(out var pool20) && TryGetPool(out var pool21) && TryGetPool(out var pool22) && TryGetPool(out var pool23) && TryGetPool(out var pool24))) - { - return; - } - - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; - if (!(pool1.Has(entity) && pool2.Has(entity) && pool3.Has(entity) && pool4.Has(entity) && pool5.Has(entity) && pool6.Has(entity) && pool7.Has(entity) && pool8.Has(entity) && pool9.Has(entity) && pool10.Has(entity) && pool11.Has(entity) && pool12.Has(entity) && pool13.Has(entity) && pool14.Has(entity) && pool15.Has(entity) && pool16.Has(entity) && pool17.Has(entity) && pool18.Has(entity) && pool19.Has(entity) && pool20.Has(entity) && pool21.Has(entity) && pool22.Has(entity) && pool23.Has(entity) && pool24.Has(entity))) - { - continue; - } - - callback(entity, ref pool0.GetRef(entity), ref pool1.GetRef(entity), ref pool2.GetRef(entity), ref pool3.GetRef(entity), ref pool4.GetRef(entity), ref pool5.GetRef(entity), ref pool6.GetRef(entity), ref pool7.GetRef(entity), ref pool8.GetRef(entity), ref pool9.GetRef(entity), ref pool10.GetRef(entity), ref pool11.GetRef(entity), ref pool12.GetRef(entity), ref pool13.GetRef(entity), ref pool14.GetRef(entity), ref pool15.GetRef(entity), ref pool16.GetRef(entity), ref pool17.GetRef(entity), ref pool18.GetRef(entity), ref pool19.GetRef(entity), ref pool20.GetRef(entity), ref pool21.GetRef(entity), ref pool22.GetRef(entity), ref pool23.GetRef(entity), ref pool24.GetRef(entity)); - } + return new QueryEnumerable( + this, + pool0, pool1, pool2, pool3, pool4, pool5, pool6, pool7, + pool0.Count); } } \ No newline at end of file diff --git a/Ghost.Entities/Template/World.Query.tt b/Ghost.Entities/Template/World.Query.tt index 0ff2f13..238e07e 100644 --- a/Ghost.Entities/Template/World.Query.tt +++ b/Ghost.Entities/Template/World.Query.tt @@ -1,48 +1,34 @@ <#@ template language="C#" #> <#@ output extension=".cs" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ include file="Helpers.ttinclude" #> namespace Ghost.Entities; -public partial struct World +public partial class World { -<# - for (var index = 1; index <= Amount; index++) +<# for (var index = 1; index <= Amount; index++) { + var generics = AppendGenerics(index); + var restrictions = AppendGenericRestrictions(index, "struct, IComponentData"); + var tryGetPools = TryGetComponentPools(index); + var poolParams = Enumerable.Range(0, index) + .Select(i => $"pool{i}") + .Aggregate((a,b)=> a + ", " + b); + var countSource = "pool0.Count"; +#> + public QueryEnumerable<<#= generics #>> Query<<#= generics #>>() + <#= restrictions #> { - var generics = AppendGenerics(index); - var restrictions = AppendGenericRestrictions(index, "struct, IComponent"); - var getPools = TryGetComponentPools(index); - var hasEntity = HasEntity(index); -#> - public readonly void Query<<#= generics #>>(QueryRefComponent<<#= generics #>> callback) - <#= restrictions.ToString() #> - { - if (!(<#=getPools.ToString()#>)) - { - return; - } + if (!(<#= tryGetPools #>)) + return default; - for (var i = 0; i < pool0.Count; i++) - { - var entity = _entities[i]; -<# - if (index > 1) - { -#> - if (!(<#=hasEntity.ToString()#>)) - { - continue; - } - -<# - } -#> - callback(entity, <#= GetComponentRef(index).ToString() #>); - } + return new QueryEnumerable<<#= generics #>>( + this, + <#= poolParams #>, + <#= countSource #>); } -<# - } -#> +<# } #> } \ No newline at end of file diff --git a/Ghost.Entities/Utilities/Box.cs b/Ghost.Entities/Utilities/Box.cs new file mode 100644 index 0000000..0e45025 --- /dev/null +++ b/Ghost.Entities/Utilities/Box.cs @@ -0,0 +1,19 @@ +namespace Ghost.Entities.Utilities; + +internal class Box + where T : struct +{ + public T Value + { + get; + set; + } + + public Box(T value) + { + Value = value; + } + + public static implicit operator T(Box box) => box.Value; + public static implicit operator Box(T value) => new(value); +} \ No newline at end of file diff --git a/Ghost.Entities/Utilities/ComponentMask.cs b/Ghost.Entities/Utilities/ComponentMask.cs new file mode 100644 index 0000000..90c1d78 --- /dev/null +++ b/Ghost.Entities/Utilities/ComponentMask.cs @@ -0,0 +1,64 @@ +using System.Numerics; + +namespace Ghost.Entities.Utilities; + +internal readonly struct ComponentMask +{ + private readonly ulong[] _words; + + public ComponentMask(int entityCapacity) + { + _words = new ulong[(entityCapacity + 63) / 64]; + } + + public void Set(int entityIndex) + => _words[entityIndex >> 6] |= 1UL << (entityIndex & 63); + + public void Clear(int entityIndex) + => _words[entityIndex >> 6] &= ~(1UL << (entityIndex & 63)); + + public bool Get(int entityIndex) + => ((_words[entityIndex >> 6] >> (entityIndex & 63)) & 1) != 0; + + // Bitwise AND + public ComponentMask And(in ComponentMask other) + { + var result = new ComponentMask(_words.Length * 64); + for (var i = 0; i < _words.Length; i++) + result._words[i] = _words[i] & other._words[i]; + return result; + } + + // Bitwise OR + public ComponentMask Or(in ComponentMask other) + { + var result = new ComponentMask(_words.Length * 64); + for (var i = 0; i < _words.Length; i++) + result._words[i] = _words[i] | other._words[i]; + return result; + } + + // Bitwise NOT + public ComponentMask Not() + { + var result = new ComponentMask(_words.Length * 64); + for (var i = 0; i < _words.Length; i++) + result._words[i] = ~_words[i]; + return result; + } + + // Iterate set bits (fast scan) + public IEnumerable GetEntityIndices() + { + for (var word = 0; word < _words.Length; word++) + { + var bits = _words[word]; + while (bits != 0) + { + var lowBit = BitOperations.TrailingZeroCount(bits); + yield return (word << 6) + lowBit; + bits &= bits - 1; // clear lowest set bit + } + } + } +} diff --git a/Ghost.Entities/Utilities/TypeHandle.cs b/Ghost.Entities/Utilities/TypeHandle.cs new file mode 100644 index 0000000..6544b4c --- /dev/null +++ b/Ghost.Entities/Utilities/TypeHandle.cs @@ -0,0 +1,6 @@ +namespace Ghost.Entities.Utilities; + +internal static class TypeHandle +{ + public static nint Value => typeof(T).TypeHandle.Value; +} \ No newline at end of file diff --git a/Ghost.Entities/World.cs b/Ghost.Entities/World.cs index b3b72b2..4a354cf 100644 --- a/Ghost.Entities/World.cs +++ b/Ghost.Entities/World.cs @@ -1,103 +1,103 @@ -using System.Diagnostics.CodeAnalysis; +using Ghost.Entities.Query; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace Ghost.Entities; -public partial struct World : IDisposable +// TODO: Archetype system for better performance +public partial class World { - private static int _nextWorldIndex = 0; + private static List s_worlds = new(2); + private static Queue s_freeWorldSlots = new(); - private readonly int _worldIndex; + private static int s_maxWorldCount = (int)MathF.Pow(2, Entity.WORLD_INDEX_BITS); - private List _entities; - private readonly Stack _freeSlots; - private readonly Dictionary _pools; - - public World() + public static World Create(int entityCapacity = 16) { - _worldIndex = _nextWorldIndex++; - - _entities = new List(); - _freeSlots = new Stack(); - _pools = new(); - } - - public readonly Entity CreateEntity() - { - if (_freeSlots.Count > 0) + lock (s_worlds) { - var index = _freeSlots.Pop(); - return _entities[index]; - } - else - { - var index = _entities.Count; - var entity = new Entity(index, 0, _worldIndex); - _entities.Add(entity); - return entity; - } - } - - public readonly void RemoveEntity(Entity e) - { - if (e.ID >= _entities.Count || _entities[e.ID].Generation != e.Generation) - { - return; - } - - var entity = _entities[e.ID]; - entity.IncrementGeneration(); - _entities[e.ID] = entity; - _freeSlots.Push(e.ID); - } - - public void AddComponent(Entity entity, T component) where T : struct, IComponent - => GetOrCreatePool().Add(entity, component); - - public void SetComponent(Entity entity, T component) where T : struct, IComponent - => GetOrCreatePool().Set(entity, component); - - public bool HasComponent(Entity entity) where T : struct, IComponent - => GetOrCreatePool().Has(entity); - - private readonly bool TryGetPool([MaybeNullWhen(false)] out ComponentPool pool) - where T : struct, IComponent - { - var type = typeof(T); - if (_pools.TryGetValue(type, out var obj)) - { - pool = (ComponentPool)obj; - return true; - } - - pool = null; - return false; - } - - private readonly ComponentPool GetOrCreatePool() - where T : struct, IComponent - { - var type = typeof(T); - if (!_pools.TryGetValue(type, out var obj)) - { - var pool = new ComponentPool(); - _pools[type] = pool; - return pool; - } - - return (ComponentPool)obj; - } - - public readonly void Dispose() - { - foreach (var pool in _pools.Values) - { - if (pool is IDisposable disposablePool) + if (s_freeWorldSlots.TryDequeue(out var index)) { - disposablePool.Dispose(); + s_worlds[index] = new World(index, entityCapacity); } + else + { + if (s_worlds.Count >= s_maxWorldCount) + { + throw new InvalidOperationException("Maximum number of worlds reached"); + } + + index = (WorldID)s_worlds.Count; + s_worlds.Add(new World(index, entityCapacity)); + } + + return s_worlds[index]; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static World GetWorld(int index) + { + return s_worlds[index]; + } +} + +public partial class World : IDisposable +{ + private readonly WorldID _id; + private readonly EntityManager _entityManager; + + internal readonly ComponentStorage _componentStorage; + internal readonly SystemStorage _systemStorage; + + public WorldID ID => _id; + public EntityManager EntityManager => _entityManager; + + private World(WorldID id, int entityCapacity) + { + _id = id; + _entityManager = new EntityManager(this, entityCapacity); + _componentStorage = new ComponentStorage(); + _systemStorage = new SystemStorage(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddSystem() + where T : SystemBase, new() + { + var instance = new T + { + World = this + }; + + _systemStorage.AddSystem(instance); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Ref GetSingleton() + where T : struct, IComponentData + { + ref var component = ref CollectionsMarshal.GetValueRefOrAddDefault(SingletonContainer.container, _id, out _); + return new Ref(ref component); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public IEnumerable QueryScript() + { + if (_componentStorage.ScriptComponentPool.IsInitialized) + { + return _componentStorage.ScriptComponentPool.ExecutionList!; } - _pools.Clear(); - _freeSlots.Clear(); + return Enumerable.Empty(); + } + + public void Dispose() + { + _entityManager.Dispose(); + _componentStorage.Dispose(); + _systemStorage.Dispose(); + + s_freeWorldSlots.Enqueue(_id); } } \ No newline at end of file diff --git a/Ghost.Test/Ghost.Test.csproj b/Ghost.Test/Ghost.Test.csproj index 723f523..85cad08 100644 --- a/Ghost.Test/Ghost.Test.csproj +++ b/Ghost.Test/Ghost.Test.csproj @@ -13,4 +13,10 @@ + + + ..\..\Class\Misaki.HighPerformance\Misaki.HighPerformance.Unsafe\bin\Release\net9.0\Misaki.HighPerformance.Unsafe.dll + + + diff --git a/Ghost.Test/Program.cs b/Ghost.Test/Program.cs index 2d6830d..f66dfab 100644 --- a/Ghost.Test/Program.cs +++ b/Ghost.Test/Program.cs @@ -1,48 +1,167 @@ using Ghost.Entities; +using Ghost.Entities.Helpers; using System.Numerics; -var world = new World(); +var t = new Test(); +t.Run(); -var entity1 = world.CreateEntity(); -var entity2 = world.CreateEntity(); -var entity3 = world.CreateEntity(); - -world.AddComponent(entity1, new Transform { position = new Vector3(1, 2, 3) }); -world.AddComponent(entity1, new Mesh { index = 42 }); -world.AddComponent(entity2, new Transform { position = new Vector3(4, 5, 6) }); -world.AddComponent(entity2, new Mesh { index = 43 }); -world.AddComponent(entity3, new Transform { position = new Vector3(7, 8, 9) }); - -world.Query((Entity entity, ref Transform transform) => +public partial class Test { - transform.position += new Vector3(1, 1, 1); -}); + public void Run() + { + var world = World.Create(); -world.Query((Entity entity, ref Mesh mesh) => + var entity1 = world.EntityManager.CreateEntity(); + var entity2 = world.EntityManager.CreateEntity(); + var entity3 = world.EntityManager.CreateEntity(); + + entity1.AddComponent(new Transform { position = new Vector3(1, 2, 3) }); + entity1.AddComponent(new Mesh { index = 42 }); + entity1.AddScript(); + entity1.AddScript(); + + entity2.AddComponent(new Transform { position = new Vector3(4, 5, 6) }); + entity2.AddComponent(new Mesh { index = 43 }); + entity2.AddScript(); + + entity3.AddComponent(new Transform { position = new Vector3(7, 8, 9) }); + entity3.AddScript(); + + foreach (var (_, transform) in world.Query()) + { + transform.ValueRW.position += new Vector3(1, 1, 1); + } + + foreach (var (_, mesh) in world.Query()) + { + mesh.ValueRW.index += 1; + } + + world.EntityManager.RemoveEntity(ref entity2); + + var entity4 = world.EntityManager.CreateEntity(); + entity4.AddComponent(new Transform { position = new Vector3(10, 11, 12) }); + entity4.AddComponent(new Mesh { index = 44 }); + entity4.AddScript(); + + world.AddSystem(); + world._systemStorage.UpdateSystems(); + + //world.SystemStorage.RebuildExecutionList(); + //world.ComponentStorage.RebuildExecutionList(); + + //Console.WriteLine(); + //Console.WriteLine("Starting scripts..."); + //foreach (var component in world.QueryScript()) + //{ + // if (!component.Enable) + // { + // continue; + // } + // component.Start(); + //} + + //Console.WriteLine(); + //Console.WriteLine("Updating scripts..."); + //foreach (var component in world.QueryScript()) + //{ + // if (!component.Enable) + // { + // continue; + // } + // component.Update(); + //} + + //Console.WriteLine(); + //Console.WriteLine("LateUpdating scripts..."); + //foreach (var component in world.QueryScript()) + //{ + // if (!component.Enable) + // { + // continue; + // } + // component.LateUpdate(); + //} + + world.Dispose(); + } +} + +public class TestSystem : SystemBase { - mesh.index += 1; -}); + public override void OnUpdate() + { + foreach (var (entity, transform) in World.Query().WithAny()) + { + Console.WriteLine($"Entity {entity.ID}: Transform Position = {transform.ValueRO.position}"); + } + } +} -world.RemoveEntity(entity2); -var entity4 = world.CreateEntity(); -world.AddComponent(entity4, new Transform { position = new Vector3(10, 11, 12) }); -world.AddComponent(entity4, new Mesh { index = 44 }); - -world.Query((Entity entity, ref Transform transform, ref Mesh mesh) => -{ - Console.WriteLine($"Entity {entity.ID}: Transform Position = {transform.position}, Mesh Index = {mesh.index}"); -}); - -world.Dispose(); - -public struct Transform : IComponent +public struct Transform : IComponentData { public Vector3 position; public Quaternion rotation; public Vector3 scale; } -public struct Mesh : IComponent +public struct Mesh : IComponentData { public uint index; +} + +public class UserScript : ScriptComponent +{ + public override int ExecutionOrder => -1; + + public override void Start() + { + Console.WriteLine("UserScript started for entity: " + Owner.ID); + } + + public override void Update() + { + Console.WriteLine("UserScript updating for entity: " + Owner.ID); + } + + public override void OnDestroy() + { + Console.WriteLine("UserScript destroyed for entity: " + Owner.ID); + } +} + +public class UIManager : ScriptComponent +{ + public override void Start() + { + Console.WriteLine("UIManager started for entity: " + Owner.ID); + } + + public override void Update() + { + Console.WriteLine("UIManager updating for entity: " + Owner.ID); + } + + public override void OnDestroy() + { + Console.WriteLine("UIManager destroyed for entity: " + Owner.ID); + } +} + +public class EventManager : ScriptComponent +{ + public override void Start() + { + Console.WriteLine("EventManager started for entity: " + Owner.ID); + } + + public override void Update() + { + Console.WriteLine("EventManager updating for entity: " + Owner.ID); + } + + public override void OnDestroy() + { + Console.WriteLine("EventManager destroyed for entity: " + Owner.ID); + } } \ No newline at end of file