forked from Misaki/GhostEngine
Refactor entity-component system and related classes
Changed the `Component` class to an interface `IComponentData` to support a data-oriented design. Changed the `Transform` class from a class to a struct, implementing `IComponentData` and updating properties. Changed the `GameObject` class to use a dictionary for components and added properties for state management. Changed the `PlayerLoopService` class to `GameLoopService` and updated methods to integrate with the new `SceneManager`. Changed the `World` class to manage multiple worlds and enhance entity management with new querying methods. Added the `Scene` class to manage root game objects and their lifecycle. Added new utility classes like `ComponentMask`, `Box<T>`, and `TypeHandle<T>` for better component management. Added the `ScriptComponent` class to allow for modular scriptable components attached to entities. Added the `QueryEnumerable` class to facilitate flexible querying of entities with specific components. Updated the `Test` class in `Program.cs` to demonstrate the new entity and component management system. Updated project files to include new references and settings supporting the changes made in the codebase.
This commit is contained in:
147
Ghost.Entities/Template/QueryEnumerable.tt
Normal file
147
Ghost.Entities/Template/QueryEnumerable.tt
Normal file
@@ -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<T{i}> 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<T<#= i #>> _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<T<#= i #>>.Value);
|
||||
<# } #>
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator() => new Enumerator(_world, <#= constructorParams #>, _count, _filters);
|
||||
|
||||
public ref struct Enumerator
|
||||
{
|
||||
private readonly World _world;
|
||||
private readonly ReadOnlySpan<Entity> _entities;
|
||||
|
||||
<# for (int i = 0; i < arity; i++){ #>
|
||||
private readonly ComponentPool<T<#= i #>> _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<TComponent<#= j #>>.Value);
|
||||
<# } #>
|
||||
return this;
|
||||
}
|
||||
|
||||
public readonly QueryEnumerable<<#= generics #>> WithAny<<#= compGenerics #>>()
|
||||
<#= compRestrictions #>
|
||||
{
|
||||
<# for (int j = 0; j < i; j++) {#>
|
||||
_filters._any.Add(TypeHandle<TComponent<#= j #>>.Value);
|
||||
<# } #>
|
||||
return this;
|
||||
}
|
||||
|
||||
public readonly QueryEnumerable<<#= generics #>> WithAbsent<<#= compGenerics #>>()
|
||||
<#= compRestrictions #>
|
||||
{
|
||||
<# for (int j = 0; j < i; j++) {#>
|
||||
_filters._absent.Add(TypeHandle<TComponent<#= j #>>.Value);
|
||||
<# } #>
|
||||
return this;
|
||||
}
|
||||
|
||||
public readonly QueryEnumerable<<#= generics #>> WithDisabled<<#= compGenerics #>>()
|
||||
<#= compRestrictions #>
|
||||
{
|
||||
<# for (int j = 0; j < i; j++) {#>
|
||||
_filters._disabled.Add(TypeHandle<TComponent<#= j #>>.Value);
|
||||
<# } #>
|
||||
return this;
|
||||
}
|
||||
<# } #>
|
||||
}
|
||||
|
||||
<# } #>
|
||||
Reference in New Issue
Block a user