Added SystemBase

This commit is contained in:
2025-12-16 15:05:42 +09:00
parent 7613b5087e
commit 756727dc06
8 changed files with 203 additions and 47 deletions

View File

@@ -153,7 +153,7 @@ internal unsafe struct Chunk : IDisposable
}
}
internal unsafe struct Archetype : IIdentifierType, IDisposable
internal unsafe struct Archetype : IDisposable
{
internal struct ComponentMemoryLayout
{

View File

@@ -1,6 +1,6 @@
namespace Ghost.Entities;
public readonly struct Time
public readonly struct TimeData
{
public int FrameCount
{

View File

@@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
namespace Ghost.Entities;
public interface IComponent : IIdentifierType
public interface IComponent
{
}

View File

@@ -261,7 +261,7 @@ public readonly unsafe ref struct ChunkView
}
}
public unsafe partial struct EntityQuery : IIdentifierType, IDisposable
public unsafe partial struct EntityQuery : IDisposable
{
/// <summary>
/// Provides an enumerator for iterating over chunks of entities and their component data that match a set of archetypes within a world.
@@ -438,6 +438,31 @@ public unsafe partial struct EntityQuery : IIdentifierType, IDisposable
return new ChunkIterator(_matchingArchetypes.AsReadOnly(), world);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly int GetEntityCount()
{
var total = 0;
var r = World.GetWorld(_worldID);
if (r.IsFailure)
{
return 0;
}
var world = r.Value;
for(var i = 0; i < _matchingArchetypes.Count; i++)
{
var archetypeID = _matchingArchetypes[i];
ref var archetype = ref world.GetArchetypeReference(archetypeID);
for (var j = 0; j < archetype.ChunkCount; j++)
{
ref var chunk = ref archetype.GetChunkReference(j);
total += chunk._count;
}
}
return total;
}
public void Dispose()
{
_mask.Dispose();

View File

@@ -1,13 +1,10 @@
using Ghost.Core;
namespace Ghost.Entities;
public readonly ref struct SystemAPI
{
public World World
{
get; init;
}
public Time Time
public TimeData Time
{
get; init;
}
@@ -15,11 +12,107 @@ public readonly ref struct SystemAPI
public interface ISystem
{
World World
{
get; init;
}
void Initialize(ref readonly SystemAPI systemAPI);
void Update(ref readonly SystemAPI systemAPI);
void Cleanup(ref readonly SystemAPI systemAPI);
}
public abstract class SystemBase : ISystem
{
private List<int>? _requiredQueries;
public World World
{
get; init;
} = null!;
public int LastSystemVersion
{
get; internal set;
} = -2;
private bool ShouldUpdate()
{
if (_requiredQueries == null || _requiredQueries.Count == 0)
{
return true;
}
foreach (var queryID in _requiredQueries)
{
ref var query = ref World.GetEntityQueryReference(new Identifier<EntityQuery>(queryID));
if (query.GetEntityCount() == 0)
{
return false;
}
}
return true;
}
protected void RequireQueryForUpdate(Identifier<EntityQuery> queryID)
{
_requiredQueries ??= new List<int>(4);
_requiredQueries.Add(queryID.value);
}
public void Initialize(ref readonly SystemAPI systemAPI)
{
OnInitialize(in systemAPI);
}
public void Update(ref readonly SystemAPI systemAPI)
{
if (ShouldUpdate())
{
if (World.Version - LastSystemVersion > 1)
{
OnStartRunning();
}
OnUpdate(in systemAPI);
LastSystemVersion = World.Version;
}
else
{
if (World.Version - LastSystemVersion <= 1)
{
OnStopRunning();
}
}
}
public void Cleanup(ref readonly SystemAPI systemAPI)
{
OnCleanup(in systemAPI);
}
protected virtual void OnInitialize(ref readonly SystemAPI systemAPI)
{
}
protected virtual void OnUpdate(ref readonly SystemAPI systemAPI)
{
}
protected virtual void OnCleanup(ref readonly SystemAPI systemAPI)
{
}
protected virtual void OnStopRunning()
{
}
protected virtual void OnStartRunning()
{
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)]
public class UpdateAfterAttribute : Attribute
{
@@ -85,12 +178,17 @@ internal static partial class SystemGroupRegistry
public abstract class SystemGroup : ISystem
{
private readonly List<ISystem> _systems = new ();
private readonly List<ISystem> _systems = [];
private List<ISystem>? _sortedSystems;
private uint _version = 0;
private uint _sortedVersion = 0;
public World World
{
get; init;
} = null!;
// public SystemGroup()
// {
// _systems = SystemGroupRegistry.GetSystemsForGroup(GetType());
@@ -106,13 +204,17 @@ public abstract class SystemGroup : ISystem
foreach (var sys in systems)
{
var type = sys.GetType();
if (!dependencies.ContainsKey(type)) dependencies[type] = new HashSet<Type>();
if (!dependencies.TryGetValue(type, out HashSet<Type>? value))
{
value = [];
dependencies[type] = value;
}
// Handle [UpdateAfter(typeof(Other))] -> Other comes before This
foreach (var attr in type.GetCustomAttributes(typeof(UpdateAfterAttribute), true))
{
var depType = ((UpdateAfterAttribute)attr).SystemType;
dependencies[type].Add(depType);
value.Add(depType);
}
// Handle [UpdateBefore(typeof(Other))] -> This comes before Other
@@ -120,7 +222,7 @@ public abstract class SystemGroup : ISystem
foreach (var attr in type.GetCustomAttributes(typeof(UpdateBeforeAttribute), true))
{
var targetType = ((UpdateBeforeAttribute)attr).SystemType;
if (!dependencies.ContainsKey(targetType)) dependencies[targetType] = new HashSet<Type>();
if (!dependencies.ContainsKey(targetType)) dependencies[targetType] = [];
dependencies[targetType].Add(type);
}
}
@@ -175,7 +277,11 @@ public abstract class SystemGroup : ISystem
public void AddSystem<T>()
where T : ISystem, new()
{
_systems.Add(new T());
_systems.Add(new T()
{
World = World
});
_version++;
}
@@ -188,7 +294,7 @@ public abstract class SystemGroup : ISystem
if (_systems.Count == 0)
{
_sortedSystems = new List<ISystem>();
_sortedSystems = [];
_sortedVersion = _version;
return;
}
@@ -244,7 +350,7 @@ public class SystemManager
{
private readonly World _world;
private readonly List<ISystem> _systems = new ();
private readonly List<ISystem> _systems = [];
internal SystemManager(World world)
{
@@ -255,8 +361,10 @@ public class SystemManager
public void AddSystem<T>()
where T : ISystem, new()
{
var system = new T();
_systems.Add(system);
_systems.Add(new T()
{
World = _world
});
}
public T GetSystem<T>()

View File

@@ -76,7 +76,7 @@ public partial class World
}
}
public partial class World : IIdentifierType, IDisposable, IEquatable<World>
public partial class World : IDisposable, IEquatable<World>
{
private readonly Identifier<World> _id;
private readonly JobScheduler _jobScheduler;
@@ -289,21 +289,21 @@ public partial class World : IIdentifierType, IDisposable, IEquatable<World>
return;
}
foreach (var archetype in _archetypes)
foreach (ref var archetype in _archetypes)
{
archetype.Dispose();
}
foreach (var query in _entityQueries)
foreach (ref var query in _entityQueries)
{
query.Dispose();
}
_entityManager.Dispose();
_entityCommandBuffer.Dispose();
for (var i = 0; i < _threadLocalECBs.Length; i++)
foreach (var v in _threadLocalECBs)
{
_threadLocalECBs[i].Dispose();
v.Dispose();
}
_archetypes.Dispose();