Added SystemBase
This commit is contained in:
@@ -153,7 +153,7 @@ internal unsafe struct Chunk : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
internal unsafe struct Archetype : IIdentifierType, IDisposable
|
||||
internal unsafe struct Archetype : IDisposable
|
||||
{
|
||||
internal struct ComponentMemoryLayout
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Ghost.Entities;
|
||||
|
||||
public readonly struct Time
|
||||
public readonly struct TimeData
|
||||
{
|
||||
public int FrameCount
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Ghost.Entities;
|
||||
|
||||
public interface IComponent : IIdentifierType
|
||||
public interface IComponent
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>()
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user