mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2026-04-22 01:45:55 +08:00
Update WIP, remove Members, add Read/Write pool getter, add DI
This commit is contained in:
parent
980ed316e1
commit
dc2e0cd810
@ -1,22 +1,12 @@
|
|||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
public class DestroyProcessor : IEcsDo<_Run>
|
public class DestroyProcessor : IDo<_Run>
|
||||||
{
|
{
|
||||||
void IEcsDo<_Run>.Do(EcsSession session)
|
void IDo<_Run>.Do(EcsSession session)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DestroyedTable : EcsTable
|
public struct DestroyedTag { }
|
||||||
{
|
|
||||||
public readonly EcsPool<tag> isDestroyed;
|
|
||||||
|
|
||||||
public static mem<tag> isDestroyedMem = "isDestroyed";
|
|
||||||
|
|
||||||
public DestroyedTable(ref TableBuilder builder) : base(ref builder)
|
|
||||||
{
|
|
||||||
isDestroyed = builder.Inc(isDestroyedMem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/Builtin/FitersProcessor.cs
Normal file
15
src/Builtin/FitersProcessor.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public class FitersProcessor : IEcsGReceive<_OnComponentAdded>, IEcsGReceive<_OnComponentRemoved>
|
||||||
|
{
|
||||||
|
void IEcsGReceive<_OnComponentAdded>.Do<T>(EcsSession session, in _OnComponentAdded message, in T obj)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IEcsGReceive<_OnComponentRemoved>.Do<T>(EcsSession session, in _OnComponentRemoved message, in T obj)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: a21421fecdd5670448a3a10c804238f7
|
guid: db219c3a9acc0964f8808af51e32afc3
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
52
src/Builtin/InjectProcessor.cs
Normal file
52
src/Builtin/InjectProcessor.cs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public class InjectProcessor<T> : IDo<_PreInit>
|
||||||
|
{
|
||||||
|
private T _injectedData;
|
||||||
|
|
||||||
|
public InjectProcessor(T injectedData)
|
||||||
|
{
|
||||||
|
_injectedData = injectedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IDo<_PreInit>.Do(EcsSession session)
|
||||||
|
{
|
||||||
|
_OnInject<T> m = new _OnInject<T>(_injectedData);
|
||||||
|
session.GetMessenger<_OnInject<T>>().Send(in m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InjectProcessorExstensions
|
||||||
|
{
|
||||||
|
public static EcsSession Inject<T>(this EcsSession self, T data)
|
||||||
|
{
|
||||||
|
self.Add(new InjectProcessor<T>(data));
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EcsSession Inject<A, B>(this EcsSession self, A dataA, B dataB)
|
||||||
|
{
|
||||||
|
self.Inject(dataA).Inject(dataB);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EcsSession Inject<A, B, C, D>(this EcsSession self, A dataA, B dataB, C dataC, D dataD)
|
||||||
|
{
|
||||||
|
self.Inject(dataA).Inject(dataB).Inject(dataC).Inject(dataD);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EcsSession Inject<A, B, C, D, E>(this EcsSession self,
|
||||||
|
A dataA, B dataB, C dataC, D dataD, E dataE)
|
||||||
|
{
|
||||||
|
self.Inject(dataA).Inject(dataB).Inject(dataC).Inject(dataD).Inject(dataE);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/Code.cs
Normal file
16
src/Code.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public static class Code
|
||||||
|
{
|
||||||
|
public static readonly NilType nil = default;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public readonly struct NilType { }
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: b5af477721d789f498a0de809e753321
|
guid: fdfd15ed79cb9e04caf3fb0275900c72
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
@ -12,6 +12,32 @@ namespace DCFApixels.DragonECS
|
|||||||
public EcsWorld World { get; }
|
public EcsWorld World { get; }
|
||||||
public int EntitiesCount { get; }
|
public int EntitiesCount { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class MaskBase
|
||||||
|
{
|
||||||
|
protected internal static int _typeIDIncrement = 0;
|
||||||
|
}
|
||||||
|
public abstract class IncBase { }
|
||||||
|
public abstract class ExcBase { }
|
||||||
|
|
||||||
|
public sealed class Inc<A> : IncBase { }
|
||||||
|
public sealed class Inc<A, b> : IncBase { }
|
||||||
|
public sealed class Exc<A> : ExcBase { }
|
||||||
|
public sealed class Exc<A, B> : ExcBase { }
|
||||||
|
public sealed class Mask<TInc> : MaskBase
|
||||||
|
where TInc : IncBase
|
||||||
|
{
|
||||||
|
public static readonly int typeID = _typeIDIncrement++;
|
||||||
|
}
|
||||||
|
public sealed class Mask<TInc, TExc> : MaskBase
|
||||||
|
where TInc : IncBase
|
||||||
|
where TExc : ExcBase
|
||||||
|
{
|
||||||
|
public static readonly int typeID = _typeIDIncrement++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class EcsFilter : IEcsFilter
|
public class EcsFilter : IEcsFilter
|
||||||
{
|
{
|
||||||
private readonly EcsWorld _source;
|
private readonly EcsWorld _source;
|
||||||
@ -25,6 +51,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
public EcsWorld World => _source;
|
public EcsWorld World => _source;
|
||||||
|
public EcsWorld.Mask Mask => _mask;
|
||||||
public int EntitiesCount => _entities.Count;
|
public int EntitiesCount => _entities.Count;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -45,7 +72,7 @@ namespace DCFApixels.DragonECS
|
|||||||
if (isAdd)
|
if (isAdd)
|
||||||
Add(entityID);
|
Add(entityID);
|
||||||
else
|
else
|
||||||
Del(entityID);
|
Remove(entityID);
|
||||||
}
|
}
|
||||||
internal void Add(int entityID)
|
internal void Add(int entityID)
|
||||||
{
|
{
|
||||||
@ -54,7 +81,7 @@ namespace DCFApixels.DragonECS
|
|||||||
_entities.Add(entityID);
|
_entities.Add(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Del(int entityID)
|
internal void Remove(int entityID)
|
||||||
{
|
{
|
||||||
if (_lockCount > 0)
|
if (_lockCount > 0)
|
||||||
AddDelayedOp(entityID, false);
|
AddDelayedOp(entityID, false);
|
||||||
@ -67,9 +94,9 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
Array.Resize(ref _delayedOps, _delayedOps.Length << 1);
|
Array.Resize(ref _delayedOps, _delayedOps.Length << 1);
|
||||||
}
|
}
|
||||||
|
ref DelayedOp delayedOd = ref _delayedOps[_delayedOpsCount];
|
||||||
_delayedOps[_delayedOpsCount].Entity = entityID;
|
delayedOd.Entity = entityID;
|
||||||
_delayedOps[_delayedOpsCount].Added = isAdd;
|
delayedOd.Added = isAdd;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region GetEnumerator
|
#region GetEnumerator
|
||||||
@ -81,12 +108,19 @@ namespace DCFApixels.DragonECS
|
|||||||
throw new Exception($"Invalid lock-unlock balance for {nameof(EcsFilter)}.");
|
throw new Exception($"Invalid lock-unlock balance for {nameof(EcsFilter)}.");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
_lockCount--;
|
if (--_lockCount <= 0)
|
||||||
if (_lockCount <= 0)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _delayedOpsCount; i++)
|
for (int i = 0; i < _delayedOpsCount; i++)
|
||||||
{
|
{
|
||||||
|
ref DelayedOp op = ref _delayedOps[i];
|
||||||
|
if (op.Added)
|
||||||
|
{
|
||||||
|
Add(op.Entity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Remove(op.Entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,9 +134,9 @@ namespace DCFApixels.DragonECS
|
|||||||
#region Utils
|
#region Utils
|
||||||
public ref struct Enumerator
|
public ref struct Enumerator
|
||||||
{
|
{
|
||||||
readonly EcsFilter _source;
|
private readonly EcsFilter _source;
|
||||||
readonly SparseSet _entities;
|
private readonly SparseSet _entities;
|
||||||
int _index;
|
private int _index;
|
||||||
|
|
||||||
public Enumerator(EcsFilter filter)
|
public Enumerator(EcsFilter filter)
|
||||||
{
|
{
|
||||||
|
|||||||
143
src/EcsGroup.cs
Normal file
143
src/EcsGroup.cs
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public class EcsGroup
|
||||||
|
{
|
||||||
|
private EcsWorld _source;
|
||||||
|
private SparseSet _entities;
|
||||||
|
|
||||||
|
private DelayedOp[] _delayedOps;
|
||||||
|
private int _delayedOpsCount;
|
||||||
|
|
||||||
|
private int _lockCount;
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
public EcsWorld World => _source;
|
||||||
|
public int EntitiesCount => _entities.Count;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constrcutors
|
||||||
|
public EcsGroup(EcsWorld world, int entitiesCapacity, int delayedOpsCapacity = 128)
|
||||||
|
{
|
||||||
|
_source = world;
|
||||||
|
_entities = new SparseSet(entitiesCapacity);
|
||||||
|
_delayedOps = new DelayedOp[delayedOpsCapacity];
|
||||||
|
_lockCount = 0;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region add/remove
|
||||||
|
public void Add(int entityID)
|
||||||
|
{
|
||||||
|
if (_lockCount > 0)
|
||||||
|
AddDelayedOp(entityID, true);
|
||||||
|
_entities.Add(entityID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove(int entityID)
|
||||||
|
{
|
||||||
|
if (_lockCount > 0)
|
||||||
|
AddDelayedOp(entityID, false);
|
||||||
|
_entities.Remove(entityID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddDelayedOp(int entityID, bool isAdd)
|
||||||
|
{
|
||||||
|
if (_delayedOpsCount >= _delayedOps.Length)
|
||||||
|
{
|
||||||
|
Array.Resize(ref _delayedOps, _delayedOps.Length << 1);
|
||||||
|
}
|
||||||
|
ref DelayedOp delayedOd = ref _delayedOps[_delayedOpsCount];
|
||||||
|
delayedOd.Entity = entityID;
|
||||||
|
delayedOd.Added = isAdd;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region GetEnumerator
|
||||||
|
private void Unlock()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
if (_lockCount <= 0)
|
||||||
|
{
|
||||||
|
throw new Exception($"Invalid lock-unlock balance for {nameof(EcsFilter)}.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (--_lockCount <= 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _delayedOpsCount; i++)
|
||||||
|
{
|
||||||
|
ref DelayedOp op = ref _delayedOps[i];
|
||||||
|
if (op.Added)
|
||||||
|
{
|
||||||
|
Add(op.Entity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Remove(op.Entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Enumerator GetEnumerator()
|
||||||
|
{
|
||||||
|
_lockCount++;
|
||||||
|
return new Enumerator(this);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Utils
|
||||||
|
public ref struct Enumerator
|
||||||
|
{
|
||||||
|
private readonly EcsGroup _source;
|
||||||
|
private readonly SparseSet _entities;
|
||||||
|
private int _index;
|
||||||
|
private Entity _currentEntity;
|
||||||
|
|
||||||
|
public Enumerator(EcsGroup group)
|
||||||
|
{
|
||||||
|
_source = group;
|
||||||
|
_entities = group._entities;
|
||||||
|
_index = -1;
|
||||||
|
_currentEntity = new Entity(group.World, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Entity Current
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
_currentEntity.id = _entities[_index];
|
||||||
|
return _currentEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
return ++_index < _entities.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_source.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
_index = -1;
|
||||||
|
_currentEntity.id = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct DelayedOp
|
||||||
|
{
|
||||||
|
public bool Added;
|
||||||
|
public int Entity;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 73f5e1a2319dcb644818c9bd14dcbc5d
|
guid: 8c5769ac232a9c44cbf639847ec56b36
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
152
src/EcsMember.cs
152
src/EcsMember.cs
@ -1,152 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS.Reflection
|
|
||||||
{
|
|
||||||
public static class MemberDeclarator
|
|
||||||
{
|
|
||||||
private static Dictionary<string, EcsMemberBase> _nameMembersPairs = new Dictionary<string, EcsMemberBase>(1024);
|
|
||||||
private static EcsMemberBase[] _members = new EcsMemberBase[1024];
|
|
||||||
private static int _increment = 1; // 0 индекс всегда пустой, так как он используется в mem<T> для обозначения NULL mem<T>
|
|
||||||
|
|
||||||
public static int MembersCount => _increment - 1;
|
|
||||||
public static EcsMember<T> Declare<T>(string name)
|
|
||||||
where T : struct
|
|
||||||
{
|
|
||||||
name = $"{typeof(T).FullName}__{name}";
|
|
||||||
#if DEBUG && !DCFA_ECS_NO_SANITIZE_CHECKS
|
|
||||||
if (_increment < 0)
|
|
||||||
{
|
|
||||||
throw new EcsFrameworkException($"Maximum available members exceeded. The member of \"{name}\" was not declared");
|
|
||||||
}
|
|
||||||
if (_nameMembersPairs.ContainsKey(name))
|
|
||||||
{
|
|
||||||
throw new EcsFrameworkException($"The node with the name \"{name}\" has already been declared");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (_increment >= _members.Length)
|
|
||||||
{
|
|
||||||
Array.Resize(ref _members, _members.Length << 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
EcsMember<T> member = new EcsMember<T>(name, _increment);
|
|
||||||
_nameMembersPairs.Add(name, member);
|
|
||||||
_members[_increment++] = member;
|
|
||||||
|
|
||||||
return member;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EcsMember<T> GetOrDeclareMember<T>(string name)
|
|
||||||
where T : struct
|
|
||||||
{
|
|
||||||
if (_nameMembersPairs.TryGetValue(name, out EcsMemberBase memberBase))
|
|
||||||
{
|
|
||||||
return (EcsMember<T>)memberBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Declare<T>(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EcsMember<T> GetMemberInfo<T>(mem<T> member)
|
|
||||||
where T : struct
|
|
||||||
{
|
|
||||||
#if DEBUG && !DCFA_ECS_NO_SANITIZE_CHECKS
|
|
||||||
if (member.HasValue == false)
|
|
||||||
{
|
|
||||||
throw new ArgumentException($"The mem<{typeof(T).Name}> argument is empty");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (EcsMember<T>)_members[member.uniqueID];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class EcsMemberBase : IEquatable<EcsMemberBase>
|
|
||||||
{
|
|
||||||
protected const string TO_STRING_HEADER = "EcsMember:";
|
|
||||||
|
|
||||||
protected string _name;
|
|
||||||
protected int _uniqueID;
|
|
||||||
protected Type _type;
|
|
||||||
|
|
||||||
#region Propertiees
|
|
||||||
public int UniqueID
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
get => _uniqueID;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region GetHashCode/ToString
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public override int GetHashCode() => _uniqueID;
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public override string ToString() => TO_STRING_HEADER + _name;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Equals
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
return obj is EcsMemberBase key && _name == key._name;
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public bool Equals(EcsMemberBase other)
|
|
||||||
{
|
|
||||||
return _uniqueID == other._uniqueID;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region operators
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool operator ==(in EcsMemberBase left, in EcsMemberBase right) => left.Equals(right);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool operator !=(in EcsMemberBase left, in EcsMemberBase right) => !left.Equals(right);
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
public class EcsMember<T> : EcsMemberBase, IEquatable<EcsMember<T>>
|
|
||||||
where T : struct
|
|
||||||
{
|
|
||||||
#region Constructors
|
|
||||||
private EcsMember() { }
|
|
||||||
internal EcsMember(string name, int uniqueID)
|
|
||||||
{
|
|
||||||
_name = name;
|
|
||||||
_uniqueID = uniqueID;
|
|
||||||
_type = typeof(T);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Equals
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public override bool Equals(object obj) => obj is EcsMember<T> key && _uniqueID == key._uniqueID;
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public bool Equals(EcsMember<T> other) => _uniqueID == other._uniqueID;
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region GetHashCode/ToString
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public override int GetHashCode() => _uniqueID;
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public override string ToString() => TO_STRING_HEADER + _name;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region operators
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool operator ==(in EcsMember<T> left, in EcsMember<T> right) => left.Equals(right);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool operator !=(in EcsMember<T> left, in EcsMember<T> right) => !left.Equals(right);
|
|
||||||
|
|
||||||
|
|
||||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
//public static implicit operator EcsMember<T>(string name) => MemberDeclarator.Declare<T>(name);
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +1,5 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using DCFApixels.DragonECS.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using System;
|
using System;
|
||||||
@ -13,8 +12,6 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
public EcsWorld World { get; }
|
public EcsWorld World { get; }
|
||||||
public int ID { get; }
|
public int ID { get; }
|
||||||
public EcsMemberBase Type { get; }
|
|
||||||
public bool IsTagsPool { get; }
|
|
||||||
public bool Has(int index);
|
public bool Has(int index);
|
||||||
public void Add(int index);
|
public void Add(int index);
|
||||||
public void Del(int index);
|
public void Del(int index);
|
||||||
@ -23,72 +20,54 @@ namespace DCFApixels.DragonECS
|
|||||||
public class EcsPool<T> : IEcsPool
|
public class EcsPool<T> : IEcsPool
|
||||||
where T : struct
|
where T : struct
|
||||||
{
|
{
|
||||||
private int _id;
|
private readonly int _id;
|
||||||
private readonly EcsWorld _source;
|
private readonly EcsWorld _source;
|
||||||
private readonly EcsMember<T> _type;
|
|
||||||
private readonly SparseSet _sparseSet;
|
private readonly SparseSet _sparseSet;
|
||||||
private T[] _denseItems;
|
private T[] _denseItems;
|
||||||
|
|
||||||
private int _isTagsPoolMask;
|
|
||||||
|
|
||||||
#region Properites
|
#region Properites
|
||||||
public EcsWorld World => _source;
|
public EcsWorld World => _source;
|
||||||
public EcsMemberBase Type => _type;
|
public int ID => _id;
|
||||||
|
|
||||||
public int ID
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
get => _id;
|
|
||||||
}
|
|
||||||
public bool IsTagsPool
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
get => _isTagsPoolMask < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ref T this[int index]
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
get => ref _denseItems[_sparseSet[index] | _isTagsPoolMask];
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
public EcsPool(EcsWorld source, mem<T> type, int capacity)
|
public EcsPool(EcsWorld source, int capacity)
|
||||||
{
|
{
|
||||||
_source = source;
|
_source = source;
|
||||||
_type = MemberDeclarator.GetMemberInfo(type);
|
|
||||||
_sparseSet = new SparseSet(capacity);
|
_sparseSet = new SparseSet(capacity);
|
||||||
|
|
||||||
_isTagsPoolMask = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0 ? -1 : 0;
|
_denseItems =new T[capacity];
|
||||||
|
|
||||||
_denseItems = IsTagsPool ? new T[1] : new T[capacity];
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Add/Has/Get/Del
|
#region Read/Write/Has/Del
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public ref readonly T Read(int index)
|
||||||
|
{
|
||||||
|
return ref _denseItems[_sparseSet[index]];
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public ref T Write(int index)
|
||||||
|
{
|
||||||
|
return ref _denseItems[_sparseSet[index]];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ref T Add(int index)
|
public ref T Add(int index)
|
||||||
{
|
{
|
||||||
_sparseSet.Add(index);
|
_sparseSet.Add(index);
|
||||||
if(IsTagsPool)
|
_sparseSet.Normalize(ref _denseItems);
|
||||||
{
|
return ref _denseItems[_sparseSet.IndexOf(index)];
|
||||||
_sparseSet.Normalize(ref _denseItems);
|
|
||||||
return ref _denseItems[_sparseSet.IndexOf(index)];
|
|
||||||
}
|
|
||||||
return ref _denseItems[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Has(int index)
|
public bool Has(int index)
|
||||||
{
|
{
|
||||||
return _sparseSet.Contains(index);
|
return _sparseSet.Contains(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Del(int index)
|
public void Del(int index)
|
||||||
{
|
{
|
||||||
if (!IsTagsPool) { this[index] = default; }
|
|
||||||
_sparseSet.Remove(index);
|
_sparseSet.Remove(index);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -105,7 +84,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
return base.Equals(obj);
|
return base.Equals(obj);
|
||||||
}
|
}
|
||||||
public override int GetHashCode() => _type.GetHashCode();
|
public override int GetHashCode() => _source.GetHashCode() + ID;
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
@ -18,8 +19,6 @@ namespace DCFApixels.DragonECS
|
|||||||
private Dictionary<string, EcsWorld> _worldsDict = new Dictionary<string, EcsWorld>();
|
private Dictionary<string, EcsWorld> _worldsDict = new Dictionary<string, EcsWorld>();
|
||||||
private List<EcsWorld> _worlds = new List<EcsWorld>();
|
private List<EcsWorld> _worlds = new List<EcsWorld>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Dictionary<Type, IEcsProcessorsRunner> _runners;
|
private Dictionary<Type, IEcsProcessorsRunner> _runners;
|
||||||
private Dictionary<Type, IEcsProcessorsMessenger> _messengers;
|
private Dictionary<Type, IEcsProcessorsMessenger> _messengers;
|
||||||
private EcsProcessorsRunner<_Run> _runRunnerCache;
|
private EcsProcessorsRunner<_Run> _runRunnerCache;
|
||||||
@ -42,11 +41,20 @@ namespace DCFApixels.DragonECS
|
|||||||
_runners.Add(type, result);
|
_runners.Add(type, result);
|
||||||
return (EcsProcessorsRunner<TDoTag>)result;
|
return (EcsProcessorsRunner<TDoTag>)result;
|
||||||
}
|
}
|
||||||
|
internal void OnRunnerDetroyed<TDoTag>(EcsProcessorsRunner<TDoTag> target)
|
||||||
|
where TDoTag : IEcsDoTag
|
||||||
|
{
|
||||||
|
Type type = typeof(TDoTag);
|
||||||
|
if (_runners.ContainsKey(type))
|
||||||
|
{
|
||||||
|
_runners.Remove(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public EcsProcessorsMessenger<TMessege> GetMessenger<TMessege>()
|
public EcsProcessorsMessenger<TMessege> GetMessenger<TMessege>()
|
||||||
where TMessege : IEcsMessage
|
where TMessege : IEcsMessage
|
||||||
{
|
{
|
||||||
Type type = typeof(TMessege);
|
Type type = typeof(EcsProcessorsMessenger<TMessege>);
|
||||||
if (_messengers.TryGetValue(type, out IEcsProcessorsMessenger result))
|
if (_messengers.TryGetValue(type, out IEcsProcessorsMessenger result))
|
||||||
{
|
{
|
||||||
return (EcsProcessorsMessenger<TMessege>)result;
|
return (EcsProcessorsMessenger<TMessege>)result;
|
||||||
@ -55,6 +63,27 @@ namespace DCFApixels.DragonECS
|
|||||||
_messengers.Add(type, result);
|
_messengers.Add(type, result);
|
||||||
return (EcsProcessorsMessenger<TMessege>)result;
|
return (EcsProcessorsMessenger<TMessege>)result;
|
||||||
}
|
}
|
||||||
|
public EcsProcessorsGMessenger<TMessege> GetGMessenger<TMessege>()
|
||||||
|
where TMessege : IEcsMessage
|
||||||
|
{
|
||||||
|
Type type = typeof(EcsProcessorsGMessenger<TMessege>);
|
||||||
|
if (_messengers.TryGetValue(type, out IEcsProcessorsMessenger result))
|
||||||
|
{
|
||||||
|
return (EcsProcessorsGMessenger<TMessege>)result;
|
||||||
|
}
|
||||||
|
result = new EcsProcessorsMessenger<TMessege>(this);
|
||||||
|
_messengers.Add(type, result);
|
||||||
|
return (EcsProcessorsGMessenger<TMessege>)result;
|
||||||
|
}
|
||||||
|
internal void OnMessengerDetroyed<TMessege>(IEcsProcessorsMessenger<TMessege> target)
|
||||||
|
where TMessege : IEcsMessage
|
||||||
|
{
|
||||||
|
Type type = typeof(TMessege);
|
||||||
|
if (_messengers.ContainsKey(type))
|
||||||
|
{
|
||||||
|
_messengers.Remove(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Configuration
|
#region Configuration
|
||||||
@ -115,5 +144,20 @@ namespace DCFApixels.DragonECS
|
|||||||
throw new MethodAccessException($"Запрещено вызывать метод {methodName}, после уничтожения {nameof(EcsSession)}");
|
throw new MethodAccessException($"Запрещено вызывать метод {methodName}, после уничтожения {nameof(EcsSession)}");
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region EntityConvert
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public Entity ToEntity(in ent target)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
// return new Entity(null, target.id);
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public ent ToEnt(in Entity target)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
// return new ent(target.id, target.world._gens[target.id], -1000);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
147
src/EcsWorld.cs
147
src/EcsWorld.cs
@ -14,9 +14,10 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
private byte _id = DEAD_WORLD_ID;
|
private byte _id = DEAD_WORLD_ID;
|
||||||
|
|
||||||
private IEcsPool[] _pools;
|
private float _timeScale;//TODO реализовать собсвенныйтайм склей для разных миров
|
||||||
private SparseSet _memToPoolIDSet;
|
|
||||||
|
|
||||||
|
private IEcsPool[] _pools;
|
||||||
|
private SparseSet _componentIDToPoolID;
|
||||||
|
|
||||||
private SparseSet _entities = new SparseSet();
|
private SparseSet _entities = new SparseSet();
|
||||||
private short[] _gens;
|
private short[] _gens;
|
||||||
@ -34,32 +35,35 @@ namespace DCFApixels.DragonECS
|
|||||||
public EcsWorld()
|
public EcsWorld()
|
||||||
{
|
{
|
||||||
_pools = new IEcsPool[512];
|
_pools = new IEcsPool[512];
|
||||||
_entities = new SparseSet();
|
_entities = new SparseSet(512);
|
||||||
_memToPoolIDSet = new SparseSet(512);
|
_componentIDToPoolID = new SparseSet(512);
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ID
|
|
||||||
internal void SetId(byte id)
|
|
||||||
{
|
|
||||||
_id = id;
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GetPool
|
#region GetPool
|
||||||
public EcsPool<T> GetPool<T>(mem<T> member)
|
public EcsPool<T> GetPool<T>()
|
||||||
where T : struct
|
where T : struct
|
||||||
{
|
{
|
||||||
if(_memToPoolIDSet.Contains(member.uniqueID))
|
int uniqueID = ComponentType<T>.uniqueID;
|
||||||
|
int poolIndex = _componentIDToPoolID.IndexOf(uniqueID);
|
||||||
if (_pools.TryGetValue(type, out IEcsPool pool))
|
if (poolIndex >= 0)
|
||||||
{
|
{
|
||||||
return (EcsPool<T>)pool;
|
return (EcsPool<T>)_pools[poolIndex];
|
||||||
}
|
}
|
||||||
|
#if DEBUG
|
||||||
|
if (_componentIDToPoolID.Count >= ushort.MaxValue)
|
||||||
|
{
|
||||||
|
throw new EcsFrameworkException("No more room for new component into this world.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
var pool = new EcsPool<T>(this, 512);
|
||||||
|
_componentIDToPoolID.Add(uniqueID);
|
||||||
|
_componentIDToPoolID.Normalize(ref _pools);
|
||||||
|
_componentIDToPoolID.Normalize(ref _filtersByIncludedComponents);
|
||||||
|
_componentIDToPoolID.Normalize(ref _filtersByExcludedComponents);
|
||||||
|
|
||||||
pool = new EcsPool<T>(this, member, 512);//TODO сделать чтоб объем можно было указывать через конфиг
|
_pools[_componentIDToPoolID.IndexOf(poolIndex)] = pool;
|
||||||
_pools.Add(type, pool);
|
return pool;
|
||||||
return (EcsPool<T>)pool;
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -82,13 +86,77 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
internal void OnEntityFieldAdd(int entityID, int changedPool)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
internal bool IsMaskCompatible(Mask filterMask, int entity)
|
||||||
{
|
{
|
||||||
|
for (int i = 0, iMax = filterMask.includeCount; i < iMax; i++)
|
||||||
|
{
|
||||||
|
if (!_pools[filterMask.include[i]].Has(entity))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0, iMax = filterMask.excludeCount; i < iMax; i++)
|
||||||
|
{
|
||||||
|
if (_pools[filterMask.exclude[i]].Has(entity))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
internal bool IsMaskCompatibleWithout(Mask filterMask, int entity, int componentId)
|
||||||
|
{
|
||||||
|
for (int i = 0, iMax = filterMask.includeCount; i < iMax; i++)
|
||||||
|
{
|
||||||
|
var typeId = filterMask.include[i];
|
||||||
|
if (typeId == componentId || !_pools[typeId].Has(entity))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0, iMax = filterMask.excludeCount; i < iMax; i++)
|
||||||
|
{
|
||||||
|
var typeId = filterMask.exclude[i];
|
||||||
|
if (typeId != componentId && _pools[typeId].Has(entity))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void OnEntityComponentAdded(int entityID, int changedPoolID)
|
||||||
|
{
|
||||||
|
var includeList = _filtersByIncludedComponents[changedPoolID];
|
||||||
|
var excludeList = _filtersByExcludedComponents[changedPoolID];
|
||||||
|
|
||||||
|
if (includeList != null)
|
||||||
|
{
|
||||||
|
foreach (var filter in includeList)
|
||||||
|
{
|
||||||
|
if (IsMaskCompatible(filter.Mask, entityID))
|
||||||
|
{
|
||||||
|
filter.Add(entityID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (excludeList != null)
|
||||||
|
{
|
||||||
|
foreach (var filter in excludeList)
|
||||||
|
{
|
||||||
|
if (IsMaskCompatibleWithout(filter.Mask, entityID, changedPoolID))
|
||||||
|
{
|
||||||
|
filter.Remove(entityID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal void OnEntityFieldDel(int entityID, int changedPool)
|
internal void OnEntityComponentRemoved(int entityID, int changedPool)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -101,7 +169,7 @@ namespace DCFApixels.DragonECS
|
|||||||
internal int[] exclude;
|
internal int[] exclude;
|
||||||
internal int includeCount;
|
internal int includeCount;
|
||||||
internal int excludeCount;
|
internal int excludeCount;
|
||||||
internal int hash;
|
|
||||||
#if DEBUG && !DCFAECS_NO_SANITIZE_CHECKS
|
#if DEBUG && !DCFAECS_NO_SANITIZE_CHECKS
|
||||||
bool _built;
|
bool _built;
|
||||||
#endif
|
#endif
|
||||||
@ -119,16 +187,15 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
includeCount = 0;
|
includeCount = 0;
|
||||||
excludeCount = 0;
|
excludeCount = 0;
|
||||||
hash = 0;
|
|
||||||
#if DEBUG && !DCFAECS_NO_SANITIZE_CHECKS
|
#if DEBUG && !DCFAECS_NO_SANITIZE_CHECKS
|
||||||
_built = false;
|
_built = false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public Mask Inc<T>(mem<T> member) where T : struct
|
public Mask Inc<T>() where T : struct
|
||||||
{
|
{
|
||||||
var poolId = _world.GetPool(member).ID;
|
var poolId = _world.GetPool<T>().ID;
|
||||||
#if DEBUG && !DCFAECS_NO_SANITIZE_CHECKS
|
#if DEBUG && !DCFAECS_NO_SANITIZE_CHECKS
|
||||||
if (_built) { throw new Exception("Cant change built mask."); }
|
if (_built) { throw new Exception("Cant change built mask."); }
|
||||||
if (Array.IndexOf(include, poolId, 0, includeCount) != -1) { throw new Exception($"{typeof(T).Name} already in constraints list."); }
|
if (Array.IndexOf(include, poolId, 0, includeCount) != -1) { throw new Exception($"{typeof(T).Name} already in constraints list."); }
|
||||||
@ -140,9 +207,9 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public Mask Exc<T>(mem<T> member) where T : struct
|
public Mask Exc<T>() where T : struct
|
||||||
{
|
{
|
||||||
var poolId = _world.GetPool(member).ID;
|
var poolId = _world.GetPool<T>().ID;
|
||||||
#if DEBUG && !DCFAECS_NO_SANITIZE_CHECKS
|
#if DEBUG && !DCFAECS_NO_SANITIZE_CHECKS
|
||||||
if (_built) { throw new Exception("Cant change built mask."); }
|
if (_built) { throw new Exception("Cant change built mask."); }
|
||||||
if (Array.IndexOf(include, poolId, 0, includeCount) != -1) { throw new Exception($"{typeof(T).Name} already in constraints list."); }
|
if (Array.IndexOf(include, poolId, 0, includeCount) != -1) { throw new Exception($"{typeof(T).Name} already in constraints list."); }
|
||||||
@ -152,6 +219,32 @@ namespace DCFApixels.DragonECS
|
|||||||
exclude[excludeCount++] = poolId;
|
exclude[excludeCount++] = poolId;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public EcsFilter End(int capacity = 512)
|
||||||
|
{
|
||||||
|
#if DEBUG && !LEOECSLITE_NO_SANITIZE_CHECKS
|
||||||
|
if (_built) { throw new Exception("Cant change built mask."); }
|
||||||
|
_built = true;
|
||||||
|
#endif
|
||||||
|
Array.Sort(include, 0, includeCount);
|
||||||
|
Array.Sort(exclude, 0, excludeCount);
|
||||||
|
|
||||||
|
var (filter, isNew) = _world.GetFilterInternal(this, capacity);
|
||||||
|
if (!isNew) { Recycle(); }
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
void Recycle()
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
if (_world._masksCount == _world._masks.Length)
|
||||||
|
{
|
||||||
|
Array.Resize(ref _world._masks, _world._masksCount << 1);
|
||||||
|
}
|
||||||
|
_world._masks[_world._masksCount++] = this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 9478c808aeb8de24a883819991780c9b
|
guid: c53ca292f39cf9d48a0bb60a65fc1232
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
@ -5,10 +5,9 @@ namespace DCFApixels.DragonECS
|
|||||||
[Serializable]
|
[Serializable]
|
||||||
public class EcsFrameworkException : Exception
|
public class EcsFrameworkException : Exception
|
||||||
{
|
{
|
||||||
private const string MESSAGE_SUFFIX = "[DragonECS] ";
|
|
||||||
public EcsFrameworkException() { }
|
public EcsFrameworkException() { }
|
||||||
public EcsFrameworkException(string message) : base(MESSAGE_SUFFIX + message) { }
|
public EcsFrameworkException(string message) : base(Exceptions.MESSAGE_SUFFIX + message) { }
|
||||||
public EcsFrameworkException(string message, Exception inner) : base(MESSAGE_SUFFIX + message, inner) { }
|
public EcsFrameworkException(string message, Exception inner) : base(Exceptions.MESSAGE_SUFFIX + message, inner) { }
|
||||||
protected EcsFrameworkException(
|
protected EcsFrameworkException(
|
||||||
System.Runtime.Serialization.SerializationInfo info,
|
System.Runtime.Serialization.SerializationInfo info,
|
||||||
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
|
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
|
||||||
|
|||||||
15
src/Exceptions/EcsReactException.cs
Normal file
15
src/Exceptions/EcsReactException.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class EcsReactException : Exception
|
||||||
|
{
|
||||||
|
public EcsReactException() { }
|
||||||
|
public EcsReactException(string message) : base(Exceptions.MESSAGE_SUFFIX + message) { }
|
||||||
|
public EcsReactException(string message, Exception inner) : base(Exceptions.MESSAGE_SUFFIX + message, inner) { }
|
||||||
|
protected EcsReactException(
|
||||||
|
System.Runtime.Serialization.SerializationInfo info,
|
||||||
|
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/Exceptions/Exceptions.cs
Normal file
7
src/Exceptions/Exceptions.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
internal static class Exceptions
|
||||||
|
{
|
||||||
|
public const string MESSAGE_SUFFIX = "[DragonECS] ";
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/Interfaces/IEcsComponentReset.cs
Normal file
7
src/Interfaces/IEcsComponentReset.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public interface IEcsComponentReset<T>
|
||||||
|
{
|
||||||
|
public void Reset(ref T component);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,15 +8,15 @@
|
|||||||
public struct _Run : IEcsDoTag { }
|
public struct _Run : IEcsDoTag { }
|
||||||
public struct _Destroy : IEcsDoTag { }
|
public struct _Destroy : IEcsDoTag { }
|
||||||
public struct _PostDestroy : IEcsDoTag { }
|
public struct _PostDestroy : IEcsDoTag { }
|
||||||
public interface IEcsDo<TTag> : IEcsProcessor
|
public interface IDo<TTag> : IEcsProcessor
|
||||||
where TTag : IEcsDoTag
|
where TTag : IEcsDoTag
|
||||||
{
|
{
|
||||||
public void Do(EcsSession session);
|
public void Do(EcsSession session);
|
||||||
}
|
}
|
||||||
public interface IEcsSimpleCycleProcessor :
|
public interface IEcsSimpleCycleProcessor :
|
||||||
IEcsDo<_Init>,
|
IDo<_Init>,
|
||||||
IEcsDo<_Run>,
|
IDo<_Run>,
|
||||||
IEcsDo<_Destroy>
|
IDo<_Destroy>
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
@ -40,9 +40,32 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IEcsDoMessege<TMessage> : IEcsProcessor
|
public readonly struct _OnInject<T> : IEcsMessage
|
||||||
|
{
|
||||||
|
public readonly T data;
|
||||||
|
public _OnInject(T data)
|
||||||
|
{
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public interface IReceive<TMessage> : IEcsProcessor
|
||||||
where TMessage : IEcsMessage
|
where TMessage : IEcsMessage
|
||||||
{
|
{
|
||||||
public void Do(EcsSession session, in TMessage message);
|
public void Do(EcsSession session, in TMessage m);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public struct _OnComponentRemoved : IEcsMessage
|
||||||
|
{
|
||||||
|
public int entityID;
|
||||||
|
}
|
||||||
|
public struct _OnComponentAdded : IEcsMessage
|
||||||
|
{
|
||||||
|
public int entityID;
|
||||||
|
}
|
||||||
|
public interface IEcsGReceive<TMessage> : IEcsProcessor
|
||||||
|
where TMessage : IEcsMessage
|
||||||
|
{
|
||||||
|
public void Do<T>(EcsSession session, in TMessage m, in T obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,6 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 0, Size = 8)]
|
[StructLayout(LayoutKind.Sequential, Pack = 0, Size = 8)]
|
||||||
public readonly struct ent : IEquatable<long>, IEquatable<ent>
|
public readonly struct ent : IEquatable<long>, IEquatable<ent>
|
||||||
{
|
{
|
||||||
@ -13,10 +12,10 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
// id - 32 bits
|
// id - 32 bits
|
||||||
// gen - 16 bits
|
// gen - 16 bits
|
||||||
// world - 8 bits
|
// world - 16 bits
|
||||||
// empty - 8 bits
|
|
||||||
public readonly long _full;
|
public readonly long _full;
|
||||||
|
|
||||||
|
#region Properties
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
public int id
|
public int id
|
||||||
{
|
{
|
||||||
@ -30,30 +29,23 @@ namespace DCFApixels.DragonECS
|
|||||||
get => (short)((_full << 32) >> 48);
|
get => (short)((_full << 32) >> 48);
|
||||||
|
|
||||||
}
|
}
|
||||||
// 255 = однозначно указывает что сущьность мертва или NULL
|
|
||||||
// но чтобы значене default было NULL сульностью, мир хранится в виде ID + 1
|
// но чтобы значене default было NULL сульностью, мир хранится в виде ID + 1
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
public byte world
|
public short world
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => (byte)(((_full << 48) >> 56) - 1);
|
get => (short)(((_full << 48) >> 48) - 1);
|
||||||
|
|
||||||
}
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
public byte type
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
get => (byte)((_full << 56) >> 56);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
public ent(int id, short gen, byte world)
|
public ent(int id, short gen, short world)
|
||||||
{
|
{
|
||||||
_full = ((long)id) << 32;
|
_full = ((long)id) << 32;
|
||||||
_full += ((long)gen) << 16;
|
_full += ((long)gen) << 16;
|
||||||
_full += ((long)(++world)) << 8; // сдвиг айдишников + 1
|
_full += ++world; // сдвиг айдишников + 1
|
||||||
//_full += ...;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -61,6 +53,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
_full = value;
|
_full = value;
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region GetHashCode
|
#region GetHashCode
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -103,6 +96,9 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static implicit operator long(in ent eent) => eent._full;
|
public static implicit operator long(in ent eent) => eent._full;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static implicit operator int(in ent eent) => eent.id;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static implicit operator ent(in long value) => new ent(value);
|
public static implicit operator ent(in long value) => new ent(value);
|
||||||
#endregion
|
#endregion
|
||||||
@ -114,5 +110,21 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
return self == ent.NULL;
|
return self == ent.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Entity UseIn(in ent self, EcsSession session)
|
||||||
|
{
|
||||||
|
session.GetWorld()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref struct Entity
|
||||||
|
{
|
||||||
|
internal EcsWorld world;
|
||||||
|
internal int id;
|
||||||
|
public Entity(EcsWorld world, int id)
|
||||||
|
{
|
||||||
|
this.world = world;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
11
src/Primitives/Ref.cs.meta
Normal file
11
src/Primitives/Ref.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e85a87d0753512d4bb7b365dd451701a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -1,56 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using DCFApixels.DragonECS.Reflection;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
|
||||||
public readonly struct mem<T> : IEquatable<mem<T>>, IEquatable<int>
|
|
||||||
where T : struct
|
|
||||||
{
|
|
||||||
public static readonly mem<T> NULL = default;
|
|
||||||
|
|
||||||
internal readonly int uniqueID;
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
public bool HasValue
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
get => uniqueID != 0;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private mem(int uniqueID) => this.uniqueID = uniqueID;
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Equals
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public override bool Equals(object obj) => obj is mem<T> key && uniqueID == key.uniqueID;
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public bool Equals(mem<T> other) => uniqueID == other.uniqueID;
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public bool Equals(int other) => uniqueID == other;
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region GetHashCode/ToString
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public override int GetHashCode() => uniqueID;
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public override string ToString() => HasValue ? MemberDeclarator.GetMemberInfo(this).ToString() : "NULL";
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region operators
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool operator ==(in mem<T> left, in mem<T> right) => left.Equals(right);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool operator !=(in mem<T> left, in mem<T> right) => !left.Equals(right);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static implicit operator mem<T>(string name) => new mem<T>(MemberDeclarator.GetOrDeclareMember<T>(name).UniqueID);
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
17
src/Primitives/proto.cs
Normal file
17
src/Primitives/proto.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public readonly struct proto
|
||||||
|
{
|
||||||
|
private readonly ent entity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
11
src/Primitives/proto.cs.meta
Normal file
11
src/Primitives/proto.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7b8a6b01f9e4e6041a681eadec261c55
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -1,6 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
|
||||||
public struct tag { }
|
|
||||||
}
|
|
||||||
39
src/React/EcsProcessorsGMessenger.cs
Normal file
39
src/React/EcsProcessorsGMessenger.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public class EcsProcessorsGMessenger<TMessage> : IEcsProcessorsMessenger<TMessage>
|
||||||
|
where TMessage : IEcsMessage
|
||||||
|
{
|
||||||
|
private readonly EcsSession _source;
|
||||||
|
private readonly IEcsGReceive<TMessage>[] _targets;
|
||||||
|
|
||||||
|
public EcsSession Source => _source;
|
||||||
|
public IReadOnlyList<IEcsGReceive<TMessage>> Targets => _targets;
|
||||||
|
|
||||||
|
internal EcsProcessorsGMessenger(EcsSession source)
|
||||||
|
{
|
||||||
|
_source = source;
|
||||||
|
List<IEcsGReceive<TMessage>> list = new List<IEcsGReceive<TMessage>>();
|
||||||
|
|
||||||
|
foreach (var item in _source.AllProcessors)
|
||||||
|
{
|
||||||
|
if (item is IEcsGReceive<TMessage> targetItem)
|
||||||
|
{
|
||||||
|
list.Add(targetItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_targets = list.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Send<T>(in TMessage message, in T obj)
|
||||||
|
{
|
||||||
|
foreach (var item in _targets)
|
||||||
|
{
|
||||||
|
item.Do(_source, in message, in obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Destroy() => _source.OnMessengerDetroyed(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/React/EcsProcessorsGMessenger.cs.meta
Normal file
11
src/React/EcsProcessorsGMessenger.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d340db685521a624792157f350923088
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -6,23 +6,24 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
public EcsSession Source { get; }
|
public EcsSession Source { get; }
|
||||||
}
|
}
|
||||||
public class EcsProcessorsMessenger<TMessage> : IEcsProcessorsMessenger
|
public interface IEcsProcessorsMessenger<TMessage> : IEcsProcessorsMessenger where TMessage : IEcsMessage { }
|
||||||
|
public class EcsProcessorsMessenger<TMessage> : IEcsProcessorsMessenger<TMessage>
|
||||||
where TMessage : IEcsMessage
|
where TMessage : IEcsMessage
|
||||||
{
|
{
|
||||||
private EcsSession _source;
|
private readonly EcsSession _source;
|
||||||
private IEcsDoMessege<TMessage>[] _targets;
|
private readonly IReceive<TMessage>[] _targets;
|
||||||
|
|
||||||
public EcsSession Source => _source;
|
public EcsSession Source => _source;
|
||||||
public IReadOnlyList<IEcsDoMessege<TMessage>> Systems => _targets;
|
public IReadOnlyList<IReceive<TMessage>> Targets => _targets;
|
||||||
|
|
||||||
internal EcsProcessorsMessenger(EcsSession source)
|
internal EcsProcessorsMessenger(EcsSession source)
|
||||||
{
|
{
|
||||||
_source = source;
|
_source = source;
|
||||||
List<IEcsDoMessege<TMessage>> list = new List<IEcsDoMessege<TMessage>>();
|
List<IReceive<TMessage>> list = new List<IReceive<TMessage>>();
|
||||||
|
|
||||||
foreach (var item in _source.AllProcessors)
|
foreach (var item in _source.AllProcessors)
|
||||||
{
|
{
|
||||||
if (item is IEcsDoMessege<TMessage> targetItem)
|
if (item is IReceive<TMessage> targetItem)
|
||||||
{
|
{
|
||||||
list.Add(targetItem);
|
list.Add(targetItem);
|
||||||
}
|
}
|
||||||
@ -34,8 +35,10 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
foreach (var item in _targets)
|
foreach (var item in _targets)
|
||||||
{
|
{
|
||||||
item.Do(_source, message);
|
item.Do(_source, in message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Destroy() => _source.OnMessengerDetroyed(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,20 +10,20 @@ namespace DCFApixels.DragonECS
|
|||||||
public class EcsProcessorsRunner<TDoTag> : IEcsProcessorsRunner
|
public class EcsProcessorsRunner<TDoTag> : IEcsProcessorsRunner
|
||||||
where TDoTag : IEcsDoTag
|
where TDoTag : IEcsDoTag
|
||||||
{
|
{
|
||||||
private EcsSession _source;
|
private readonly EcsSession _source;
|
||||||
private IEcsDo<TDoTag>[] _targets;
|
private readonly IDo<TDoTag>[] _targets;
|
||||||
|
|
||||||
public EcsSession Source => _source;
|
public EcsSession Source => _source;
|
||||||
public IReadOnlyList<IEcsDo<TDoTag>> Systems => _targets;
|
public IReadOnlyList<IDo<TDoTag>> Targets => _targets;
|
||||||
|
|
||||||
internal EcsProcessorsRunner(EcsSession source)
|
internal EcsProcessorsRunner(EcsSession source)
|
||||||
{
|
{
|
||||||
_source = source;
|
_source = source;
|
||||||
List<IEcsDo<TDoTag>> list = new List<IEcsDo<TDoTag>>();
|
List<IDo<TDoTag>> list = new List<IDo<TDoTag>>();
|
||||||
|
|
||||||
foreach (var item in _source.AllProcessors)
|
foreach (var item in _source.AllProcessors)
|
||||||
{
|
{
|
||||||
if (item is IEcsDo<TDoTag> targetItem)
|
if (item is IDo<TDoTag> targetItem)
|
||||||
{
|
{
|
||||||
list.Add(targetItem);
|
list.Add(targetItem);
|
||||||
}
|
}
|
||||||
@ -38,5 +38,7 @@ namespace DCFApixels.DragonECS
|
|||||||
item.Do(_source);
|
item.Do(_source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Destroy() => _source.OnRunnerDetroyed(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/Utils/ComponentType.cs
Normal file
17
src/Utils/ComponentType.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
internal abstract class ComponentType
|
||||||
|
{
|
||||||
|
protected static int _increment = 0;
|
||||||
|
}
|
||||||
|
internal sealed class ComponentType<T> : ComponentType
|
||||||
|
{
|
||||||
|
internal static int uniqueID = _increment++;
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/Utils/ComponentType.cs.meta
Normal file
11
src/Utils/ComponentType.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cef3dbf379d584346bc8a9313c22c563
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
64
src/Utils/CompressedBitMask.cs
Normal file
64
src/Utils/CompressedBitMask.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public class CompressedBitMask
|
||||||
|
{
|
||||||
|
private const int CHUNK = 32; //int bits
|
||||||
|
|
||||||
|
private int[] _fullChunkIndexes; // индексы чанков с полным заполнением
|
||||||
|
private int[] _sparseIndexes;
|
||||||
|
private int[] _denseMasks;
|
||||||
|
|
||||||
|
private int _highBit = 0;
|
||||||
|
|
||||||
|
public int HightBit => _highBit;
|
||||||
|
|
||||||
|
public void Set(int[] indexes, int count)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref struct EqualsRequest
|
||||||
|
{
|
||||||
|
private CompressedBitMask _source;
|
||||||
|
private CompressedBitMask _other;
|
||||||
|
public void GetEnumerator() =>
|
||||||
|
}
|
||||||
|
public ref struct Enumerator
|
||||||
|
{
|
||||||
|
private readonly int[] _indexes;
|
||||||
|
private readonly int[] _masks;
|
||||||
|
private int _index;
|
||||||
|
|
||||||
|
public Enumerator(int[] indexes, int[] masks)
|
||||||
|
|
||||||
|
{
|
||||||
|
_indexes = indexes;
|
||||||
|
_masks = masks;
|
||||||
|
_index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Current
|
||||||
|
{
|
||||||
|
get => 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose() { }
|
||||||
|
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
_index = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/Utils/CompressedBitMask.cs.meta
Normal file
11
src/Utils/CompressedBitMask.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f88c761abb374574fba2ac5aa2d5e41a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -1,177 +1,156 @@
|
|||||||
// _sparse[value] == index
|
using System;
|
||||||
// _dense[index] == value
|
|
||||||
//
|
|
||||||
// int[] _dense => |2|4|1|_|_|
|
|
||||||
// int[] _sparse => |_|2|0|_|1|
|
|
||||||
//
|
|
||||||
// indexator => [0]2, [1]4, [2]1
|
|
||||||
//
|
|
||||||
// can use foreach
|
|
||||||
// implements IEnumerable<int>
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using coretype = System.Int32;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
public class SparseSet : IEnumerable<int>, ICollection<int>, IReadOnlyCollection<int>
|
public class SparseSet : IEnumerable<coretype>, ICollection<coretype>, IReadOnlyCollection<coretype>
|
||||||
{
|
{
|
||||||
public const int DEFAULT_CAPACITY = 16;
|
public const int DEFAULT_CAPACITY = 16;
|
||||||
|
public const int MAX_CAPACITY = coretype.MaxValue;
|
||||||
|
|
||||||
private int[] _dense;
|
private coretype[] _dense;
|
||||||
private int[] _sparse;
|
private coretype[] _sparse;
|
||||||
|
|
||||||
private int _count;
|
private coretype _count;
|
||||||
|
|
||||||
|
private coretype _denseCapacity;
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
public int Count => _count;
|
public int Count => _count;
|
||||||
public int Capacity => _dense.Length;
|
public int CapacityDense
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get => _denseCapacity;
|
||||||
|
}
|
||||||
|
public int CapacitySparse
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get => _dense.Length;
|
||||||
|
}
|
||||||
|
|
||||||
public int this[int index]
|
public coretype this[int index]
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
ThrowHalper.CheckOutOfRange(this, index);
|
ThrowHalper.CheckOutOfRange(this, (coretype)index);
|
||||||
return _dense[index];
|
return _dense[index];
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
get => _dense[index];
|
get => _dense[index];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public IndexesCollection Indexes => new IndexesCollection(_sparse);
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
public SparseSet() : this(DEFAULT_CAPACITY) { }
|
public SparseSet() : this(DEFAULT_CAPACITY) { }
|
||||||
public SparseSet(int capacity)
|
public SparseSet(coretype capacity)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
ThrowHalper.CheckCapacity(capacity);
|
ThrowHalper.CheckCapacity(capacity);
|
||||||
#endif
|
#endif
|
||||||
_dense = new int[capacity];
|
_dense = new coretype[capacity];
|
||||||
_sparse = new int[capacity];
|
_sparse = new coretype[capacity];
|
||||||
for (int i = 0; i < _sparse.Length; i++)
|
for (coretype i = 0; i < _sparse.Length; i++)
|
||||||
{
|
{
|
||||||
_dense[i] = i;
|
_dense[i] = i;
|
||||||
_sparse[i] = i;
|
_sparse[i] = i;
|
||||||
}
|
}
|
||||||
_count = 0;
|
_count = 0;
|
||||||
|
_denseCapacity = 0;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Add/AddRange/GetFree
|
#region Add/AddRange/GetFree
|
||||||
public void Add<T>(int value, ref T[] normalizedArray)
|
public void Add<T>(coretype value, ref T[] normalizedArray)
|
||||||
{
|
{
|
||||||
Add(value);
|
Add(value);
|
||||||
Normalize(ref normalizedArray);
|
Normalize(ref normalizedArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Add(int value)
|
public void Add(coretype value)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
ThrowHalper.CheckValueIsPositive(value);
|
ThrowHalper.CheckValueIsPositive(value);
|
||||||
ThrowHalper.CheckValueNotContained(this, value);
|
ThrowHalper.CheckValueNotContained(this, value);
|
||||||
#endif
|
#endif
|
||||||
|
if (value > CapacitySparse)
|
||||||
int neadedSpace = _dense.Length;
|
|
||||||
while (value >= neadedSpace)
|
|
||||||
neadedSpace <<= 1;
|
|
||||||
|
|
||||||
if (neadedSpace != _dense.Length)
|
|
||||||
Resize(neadedSpace);
|
|
||||||
|
|
||||||
if (Contains(value))
|
|
||||||
{
|
{
|
||||||
return;
|
coretype neadedSpace = (coretype)_dense.Length;
|
||||||
|
while (value >= neadedSpace) neadedSpace <<= 1;
|
||||||
|
Resize(neadedSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
Swap(value, _count++);
|
Swap(value, _count++);
|
||||||
|
if (_count > _denseCapacity) _denseCapacity <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryAdd<T>(int value, ref T[] normalizedArray)
|
public bool TryAdd<T>(coretype value, ref T[] normalizedArray)
|
||||||
{
|
{
|
||||||
if (Contains(value))
|
if (Contains(value)) return false;
|
||||||
return false;
|
Add(value);
|
||||||
|
Normalize(ref normalizedArray);
|
||||||
Add(value, ref normalizedArray);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool TryAdd(int value)
|
public bool TryAdd(coretype value)
|
||||||
{
|
{
|
||||||
if (Contains(value))
|
if (Contains(value)) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
Add(value);
|
Add(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRange<T>(IEnumerable<int> range, ref T[] normalizedArray)
|
public void AddRange<T>(IEnumerable<coretype> range, ref T[] normalizedArray)
|
||||||
{
|
{
|
||||||
foreach (var item in range)
|
AddRange(range);
|
||||||
{
|
|
||||||
if (Contains(item))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Add(item);
|
|
||||||
}
|
|
||||||
Normalize(ref normalizedArray);
|
Normalize(ref normalizedArray);
|
||||||
}
|
}
|
||||||
|
public void AddRange(IEnumerable<coretype> range)
|
||||||
public void AddRange(IEnumerable<int> range)
|
|
||||||
{
|
{
|
||||||
foreach (var item in range)
|
foreach (var item in range)
|
||||||
{
|
{
|
||||||
if (Contains(item))
|
if (Contains(item)) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
Add(item);
|
Add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// <summary>
|
|
||||||
/// Adds a value between 0 and Capacity to the array and returns it.
|
/// <summary>Adds a value between 0 and Capacity to the array and returns it.</summary>
|
||||||
/// </summary>
|
|
||||||
/// <returns>Value between 0 and Capacity</returns>
|
/// <returns>Value between 0 and Capacity</returns>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public int GetFree<T>(ref T[] normalizedArray)
|
public coretype GetFree<T>(ref T[] normalizedArray)
|
||||||
{
|
{
|
||||||
int result = GetFree();
|
coretype result = GetFree();
|
||||||
Normalize(ref normalizedArray);
|
Normalize(ref normalizedArray);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>Adds a value between 0 and Capacity to the array and returns it.</summary>
|
||||||
/// Adds a value between 0 and Capacity to the array and returns it.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Value between 0 and Capacity</returns>
|
/// <returns>Value between 0 and Capacity</returns>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public int GetFree()
|
public coretype GetFree()
|
||||||
{
|
{
|
||||||
if (++_count >= _dense.Length)
|
if (++_count >= CapacitySparse) AddSpaces();
|
||||||
AddSpaces();
|
if (_count > _denseCapacity) _denseCapacity <<= 1;
|
||||||
|
|
||||||
return _dense[_count - 1];
|
return _dense[_count - 1];
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Contains
|
#region Contains
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Contains(int value)
|
public bool Contains(coretype value)
|
||||||
{
|
{
|
||||||
return value >= 0 && value < Capacity && _sparse[value] < _count;
|
return value >= 0 && value < CapacitySparse && _sparse[value] < _count;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Remove
|
#region Remove
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Remove(int value)
|
public void Remove(coretype value)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
ThrowHalper.CheckValueContained(this, value);
|
ThrowHalper.CheckValueContained(this, value);
|
||||||
@ -179,17 +158,15 @@ namespace DCFApixels.DragonECS
|
|||||||
Swap(_sparse[value], --_count);
|
Swap(_sparse[value], --_count);
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool TryRemove(int value)
|
public bool TryRemove(coretype value)
|
||||||
{
|
{
|
||||||
if (!Contains(value))
|
if (!Contains(value)) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
Remove(value);
|
Remove(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void RemoveAt(int index)
|
public void RemoveAt(coretype index)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
ThrowHalper.CheckOutOfRange(this, index);
|
ThrowHalper.CheckOutOfRange(this, index);
|
||||||
@ -202,23 +179,20 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Normalize<T>(ref T[] array)
|
public void Normalize<T>(ref T[] array)
|
||||||
{
|
{
|
||||||
if (array.Length != _dense.Length)
|
if (array.Length < CapacityDense) Array.Resize(ref array, CapacityDense);
|
||||||
Array.Resize(ref array, _dense.Length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public int IndexOf(int value)
|
public int IndexOf(coretype value)
|
||||||
{
|
{
|
||||||
if (value < 0 || !Contains(value))
|
if (value < 0 || !Contains(value)) return -1;
|
||||||
return -1;
|
|
||||||
|
|
||||||
return _sparse[value];
|
return _sparse[value];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Sort()
|
public void Sort()
|
||||||
{
|
{
|
||||||
int increment = 0;
|
coretype increment = 0;
|
||||||
for (int i = 0; i < Capacity; i++)
|
for (coretype i = 0; i < CapacitySparse; i++)
|
||||||
{
|
{
|
||||||
if (_sparse[i] < _count)
|
if (_sparse[i] < _count)
|
||||||
{
|
{
|
||||||
@ -230,9 +204,9 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
public void HardSort()
|
public void HardSort()
|
||||||
{
|
{
|
||||||
int inc = 0;
|
coretype inc = 0;
|
||||||
int inc2 = _count;
|
coretype inc2 = _count;
|
||||||
for (int i = 0; i < Capacity; i++)
|
for (coretype i = 0; i < CapacitySparse; i++)
|
||||||
{
|
{
|
||||||
if (_sparse[i] < _count)
|
if (_sparse[i] < _count)
|
||||||
{
|
{
|
||||||
@ -250,21 +224,19 @@ namespace DCFApixels.DragonECS
|
|||||||
public void CopyTo(SparseSet other)
|
public void CopyTo(SparseSet other)
|
||||||
{
|
{
|
||||||
other._count = _count;
|
other._count = _count;
|
||||||
if (Capacity != other.Capacity)
|
if (CapacitySparse != other.CapacitySparse)
|
||||||
{
|
{
|
||||||
other.Resize(Capacity);
|
other.Resize(CapacitySparse);
|
||||||
}
|
}
|
||||||
_dense.CopyTo(other._dense, 0);
|
_dense.CopyTo(other._dense, 0);
|
||||||
_sparse.CopyTo(other._sparse, 0);
|
_sparse.CopyTo(other._sparse, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyTo(int[] array, int arrayIndex)
|
public void CopyTo(coretype[] array, int arrayIndex)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (arrayIndex < 0)
|
if (arrayIndex < 0) throw new ArgumentException("arrayIndex is less than 0");
|
||||||
throw new ArgumentException("arrayIndex is less than 0");
|
if (arrayIndex + _count >= array.Length) throw new ArgumentException("The number of elements in the source List<T> is greater than the available space from arrayIndex to the end of the destination array.");
|
||||||
if (arrayIndex + _count >= array.Length)
|
|
||||||
throw new ArgumentException("The number of elements in the source List<T> is greater than the available space from arrayIndex to the end of the destination array.");
|
|
||||||
#endif
|
#endif
|
||||||
for (int i = 0; i < _count; i++, arrayIndex++)
|
for (int i = 0; i < _count; i++, arrayIndex++)
|
||||||
{
|
{
|
||||||
@ -275,21 +247,17 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region Clear/Reset
|
#region Clear/Reset
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Clear()
|
public void Clear() => _count = 0;
|
||||||
{
|
|
||||||
_count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
for (int i = 0; i < _dense.Length; i++)
|
for (coretype i = 0; i < _dense.Length; i++)
|
||||||
{
|
{
|
||||||
_dense[i] = i;
|
_dense[i] = i;
|
||||||
_sparse[i] = i;
|
_sparse[i] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void Reset(int newCapacity)
|
public void Reset(coretype newCapacity)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
ThrowHalper.CheckCapacity(newCapacity);
|
ThrowHalper.CheckCapacity(newCapacity);
|
||||||
@ -301,16 +269,16 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region AddSpace/Resize
|
#region AddSpace/Resize
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void AddSpaces() => Resize(_count << 1);
|
private void AddSpaces() => Resize((_count << 1));
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void Resize(int newSpace)
|
private void Resize(int newSpace)
|
||||||
{
|
{
|
||||||
int oldspace = _dense.Length;
|
coretype oldspace = (short)_dense.Length;
|
||||||
Array.Resize(ref _dense, newSpace);
|
Array.Resize(ref _dense, newSpace);
|
||||||
Array.Resize(ref _sparse, newSpace);
|
Array.Resize(ref _sparse, newSpace);
|
||||||
|
|
||||||
for (int i = oldspace; i < newSpace; i++)
|
for (coretype i = oldspace; i < newSpace; i++)
|
||||||
{
|
{
|
||||||
_dense[i] = i;
|
_dense[i] = i;
|
||||||
_sparse[i] = i;
|
_sparse[i] = i;
|
||||||
@ -320,10 +288,10 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region Swap
|
#region Swap
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void Swap(int fromIndex, int toIndex)
|
private void Swap(coretype fromIndex, coretype toIndex)
|
||||||
{
|
{
|
||||||
int value = _dense[toIndex];
|
coretype value = _dense[toIndex];
|
||||||
int oldValue = _dense[fromIndex];
|
coretype oldValue = _dense[fromIndex];
|
||||||
|
|
||||||
_dense[toIndex] = oldValue;
|
_dense[toIndex] = oldValue;
|
||||||
_dense[fromIndex] = value;
|
_dense[fromIndex] = value;
|
||||||
@ -338,19 +306,19 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
public ref struct RefEnumerator
|
public ref struct RefEnumerator
|
||||||
{
|
{
|
||||||
private readonly int[] _dense;
|
private readonly coretype[] _dense;
|
||||||
private readonly int _count;
|
private readonly coretype _count;
|
||||||
private int _index;
|
private coretype _index;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public RefEnumerator(int[] values, int count)
|
public RefEnumerator(coretype[] values, coretype count)
|
||||||
{
|
{
|
||||||
_dense = values;
|
_dense = values;
|
||||||
_count = count;
|
_count = count;
|
||||||
_index = -1;
|
_index = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Current
|
public coretype Current
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => _dense[_index];
|
get => _dense[_index];
|
||||||
@ -366,20 +334,20 @@ namespace DCFApixels.DragonECS
|
|||||||
public void Reset() => _index = -1;
|
public void Reset() => _index = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerator<int> IEnumerable<int>.GetEnumerator() => new Enumerator(_dense, _count);
|
IEnumerator<coretype> IEnumerable<coretype>.GetEnumerator() => new Enumerator(_dense, _count);
|
||||||
IEnumerator IEnumerable.GetEnumerator() => new Enumerator(_dense, _count);
|
IEnumerator IEnumerable.GetEnumerator() => new Enumerator(_dense, _count);
|
||||||
public struct Enumerator : IEnumerator<int> //to implement the IEnumerable interface and use the ref structure, 2 Enumerators were created.
|
public struct Enumerator : IEnumerator<coretype> //to implement the IEnumerable interface and use the ref structure, 2 Enumerators were created.
|
||||||
{
|
{
|
||||||
private readonly int[] _dense;
|
private readonly coretype[] _dense;
|
||||||
private readonly int _count;
|
private readonly coretype _count;
|
||||||
private int _index;
|
private coretype _index;
|
||||||
public Enumerator(int[] values, int count)
|
public Enumerator(coretype[] values, coretype count)
|
||||||
{
|
{
|
||||||
_dense = values;
|
_dense = values;
|
||||||
_count = count;
|
_count = count;
|
||||||
_index = -1;
|
_index = -1;
|
||||||
}
|
}
|
||||||
public int Current => _dense[_index];
|
public coretype Current => _dense[_index];
|
||||||
object IEnumerator.Current => _dense[_index];
|
object IEnumerator.Current => _dense[_index];
|
||||||
public void Dispose() { }
|
public void Dispose() { }
|
||||||
public bool MoveNext() => ++_index < _count;
|
public bool MoveNext() => ++_index < _count;
|
||||||
@ -387,55 +355,38 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Utils
|
|
||||||
public ref struct IndexesCollection
|
|
||||||
{
|
|
||||||
private readonly int[] _indexes;
|
|
||||||
|
|
||||||
public IndexesCollection(int[] indexes)
|
|
||||||
{
|
|
||||||
_indexes = indexes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int this[int value]
|
|
||||||
{
|
|
||||||
get => _indexes[value];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ICollection
|
#region ICollection
|
||||||
bool ICollection<int>.IsReadOnly => false;
|
bool ICollection<coretype>.IsReadOnly => false;
|
||||||
|
|
||||||
bool ICollection<int>.Remove(int value) => TryRemove(value);
|
bool ICollection<coretype>.Remove(coretype value) => TryRemove(value);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Debug
|
#region Debug
|
||||||
public string Log()
|
public string Log()
|
||||||
{
|
{
|
||||||
StringBuilder logbuild = new StringBuilder();
|
StringBuilder logbuild = new StringBuilder();
|
||||||
for (int i = 0; i < Capacity; i++)
|
for (int i = 0; i < CapacitySparse; i++)
|
||||||
{
|
{
|
||||||
logbuild.Append(_dense[i] + ", ");
|
logbuild.Append(_dense[i] + ", ");
|
||||||
}
|
}
|
||||||
logbuild.Append("\n\r");
|
logbuild.Append("\n\r");
|
||||||
for (int i = 0; i < Capacity; i++)
|
for (int i = 0; i < CapacitySparse; i++)
|
||||||
{
|
{
|
||||||
logbuild.Append(_sparse[i] + ", ");
|
logbuild.Append(_sparse[i] + ", ");
|
||||||
}
|
}
|
||||||
logbuild.Append("\n\r --------------------------");
|
logbuild.Append("\n\r --------------------------");
|
||||||
logbuild.Append("\n\r");
|
logbuild.Append("\n\r");
|
||||||
for (int i = 0; i < Capacity; i++)
|
for (int i = 0; i < CapacitySparse; i++)
|
||||||
{
|
{
|
||||||
logbuild.Append((i < _count ? _dense[i].ToString() : "_") + ", ");
|
logbuild.Append((i < _count ? _dense[i].ToString() : "_") + ", ");
|
||||||
}
|
}
|
||||||
logbuild.Append("\n\r");
|
logbuild.Append("\n\r");
|
||||||
for (int i = 0; i < Capacity; i++)
|
for (int i = 0; i < CapacitySparse; i++)
|
||||||
{
|
{
|
||||||
logbuild.Append((_sparse[i] < _count ? _sparse[i].ToString() : "_") + ", ");
|
logbuild.Append((_sparse[i] < _count ? _sparse[i].ToString() : "_") + ", ");
|
||||||
}
|
}
|
||||||
logbuild.Append("\n\r Count: " + _count);
|
logbuild.Append("\n\r Count: " + _count);
|
||||||
logbuild.Append("\n\r Capacity: " + Capacity);
|
logbuild.Append("\n\r Capacity: " + CapacitySparse);
|
||||||
logbuild.Append("\n\r IsValide: " + IsValide_Debug());
|
logbuild.Append("\n\r IsValide: " + IsValide_Debug());
|
||||||
|
|
||||||
logbuild.Append("\n\r");
|
logbuild.Append("\n\r");
|
||||||
@ -445,7 +396,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public bool IsValide_Debug()
|
public bool IsValide_Debug()
|
||||||
{
|
{
|
||||||
bool isPass = true;
|
bool isPass = true;
|
||||||
for (int index = 0; index < Capacity; index++)
|
for (int index = 0; index < CapacitySparse; index++)
|
||||||
{
|
{
|
||||||
int value = _dense[index];
|
int value = _dense[index];
|
||||||
isPass = isPass && _sparse[value] == index;
|
isPass = isPass && _sparse[value] == index;
|
||||||
@ -453,31 +404,30 @@ namespace DCFApixels.DragonECS
|
|||||||
return isPass;
|
return isPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
private static class ThrowHalper
|
private static class ThrowHalper
|
||||||
{
|
{
|
||||||
public static void CheckCapacity(int capacity)
|
public static void CheckCapacity(coretype capacity)
|
||||||
{
|
{
|
||||||
if (capacity < 0)
|
if (capacity < 0)
|
||||||
throw new ArgumentException("Capacity cannot be a negative number");
|
throw new ArgumentException("Capacity cannot be a negative number");
|
||||||
}
|
}
|
||||||
public static void CheckValueIsPositive(int value)
|
public static void CheckValueIsPositive(coretype value)
|
||||||
{
|
{
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
throw new ArgumentException("The SparseSet can only contain positive numbers");
|
throw new ArgumentException("The SparseSet can only contain positive numbers");
|
||||||
}
|
}
|
||||||
public static void CheckValueContained(SparseSet source, int value)
|
public static void CheckValueContained(SparseSet source, coretype value)
|
||||||
{
|
{
|
||||||
if (!source.Contains(value))
|
if (!source.Contains(value))
|
||||||
throw new ArgumentException($"Value {value} is not contained");
|
throw new ArgumentException($"Value {value} is not contained");
|
||||||
}
|
}
|
||||||
public static void CheckValueNotContained(SparseSet source, int value)
|
public static void CheckValueNotContained(SparseSet source, coretype value)
|
||||||
{
|
{
|
||||||
if (source.Contains(value))
|
if (source.Contains(value))
|
||||||
throw new ArgumentException($"Value {value} is already contained");
|
throw new ArgumentException($"Value {value} is already contained");
|
||||||
}
|
}
|
||||||
public static void CheckOutOfRange(SparseSet source, int index)
|
public static void CheckOutOfRange(SparseSet source, coretype index)
|
||||||
{
|
{
|
||||||
if (index < 0 || index >= source.Count)
|
if (index < 0 || index >= source.Count)
|
||||||
throw new ArgumentOutOfRangeException($"Index {index} was out of range. Must be non-negative and less than the size of the collection.");
|
throw new ArgumentOutOfRangeException($"Index {index} was out of range. Must be non-negative and less than the size of the collection.");
|
||||||
|
|||||||
18
test/Mems.cs
18
test/Mems.cs
@ -1,18 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
|
||||||
public static class Mems
|
|
||||||
{
|
|
||||||
public static readonly mem<float> health = "health";
|
|
||||||
public static readonly mem<float> regeneration = "regeneration";
|
|
||||||
public static readonly mem<Vector3> position = "position";
|
|
||||||
public static readonly mem<Quaternion> rotation = "rotation";
|
|
||||||
public static readonly mem<Vector3> scale = "scale";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
12
test/SharedData.cs
Normal file
12
test/SharedData.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public class SharedData
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,12 +9,14 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
|
|
||||||
private EcsSession _ecsSession;
|
private EcsSession _ecsSession;
|
||||||
|
public SharedData _data = new SharedData();
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
_ecsSession
|
_ecsSession
|
||||||
.AddWorld("")
|
.AddWorld("")
|
||||||
.Add(new TestSystem())
|
.Add(new TestSystem())
|
||||||
|
.Inject(_data)
|
||||||
.Init();
|
.Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,18 +6,26 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
public class TestSystem : IEcsDo<_Init>, IEcsDo<_Run>, IEcsDo<_Destroy>
|
public class TestSystem :
|
||||||
|
IReceive<_OnInject<SharedData>>,
|
||||||
|
IDo<_Init>, IDo<_Run>, IDo<_Destroy>
|
||||||
{
|
{
|
||||||
void IEcsDo<_Init>.Do(EcsSession engine)
|
private SharedData _sharedData;
|
||||||
|
void IReceive<_OnInject<SharedData>>.Do(EcsSession session, in _OnInject<SharedData> m) => _sharedData = m.data;
|
||||||
|
|
||||||
|
|
||||||
|
void IDo<_Init>.Do(EcsSession session)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void IEcsDo<_Run>.Do(EcsSession engine)
|
void IDo<_Run>.Do(EcsSession session)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IDo<_Destroy>.Do(EcsSession session)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void IEcsDo<_Destroy>.Do(EcsSession engine)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 35dbc0eb7d0449242a40ddcb8cbdbc06
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,136 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
|
||||||
public readonly struct EcsField<T> : IEcsMemberCachePool<EcsField<T>, T>
|
|
||||||
where T :struct
|
|
||||||
{
|
|
||||||
private readonly EcsPool<T> _pool;
|
|
||||||
private readonly int _poolID;
|
|
||||||
|
|
||||||
public EcsPool<T> Pool => _pool;
|
|
||||||
public int PoolID => _poolID;
|
|
||||||
|
|
||||||
private EcsField(int poolID)
|
|
||||||
{
|
|
||||||
_pool = null;
|
|
||||||
_poolID = poolID;
|
|
||||||
}
|
|
||||||
internal EcsField(EcsPool<T> pool)
|
|
||||||
{
|
|
||||||
_pool = pool;
|
|
||||||
_poolID = pool.ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
public ref T this[int entityID]
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
get => ref _pool[entityID];
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public bool Has(int entityID)
|
|
||||||
{
|
|
||||||
return _pool.Has(entityID);
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public ref T Add(int entityID)
|
|
||||||
{
|
|
||||||
return ref _pool.Add(entityID);
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Del(int entityID)
|
|
||||||
{
|
|
||||||
_pool.Del(entityID);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static implicit operator EcsField<T>(in int poolID) => new EcsField<T>(poolID);
|
|
||||||
|
|
||||||
void IEcsMemberCachePool<EcsField<T>, T>.Inject(out EcsField<T> self, EcsPool<T> pool)
|
|
||||||
{
|
|
||||||
self = new EcsField<T>(pool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public readonly struct EcsIncField<T> : IEcsMemberCachePool<EcsIncField<T>, T>
|
|
||||||
where T :struct
|
|
||||||
{
|
|
||||||
private readonly EcsPool<T> _pool;
|
|
||||||
private readonly int _poolID;
|
|
||||||
|
|
||||||
public EcsPool<T> Pool => _pool;
|
|
||||||
public int PoolID => _poolID;
|
|
||||||
|
|
||||||
private EcsIncField(int poolID)
|
|
||||||
{
|
|
||||||
_pool = null;
|
|
||||||
_poolID = poolID;
|
|
||||||
}
|
|
||||||
internal EcsIncField(EcsPool<T> pool)
|
|
||||||
{
|
|
||||||
_pool = pool;
|
|
||||||
_poolID = pool.ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
public ref T this[int entityID]
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
get => ref _pool[entityID];
|
|
||||||
}
|
|
||||||
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
public void Del(int entityID)
|
|
||||||
{
|
|
||||||
_pool.Del(entityID);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static implicit operator EcsIncField<T>(in int poolID) => new EcsIncField<T>(poolID);
|
|
||||||
|
|
||||||
void IEcsMemberCachePool<EcsIncField<T>, T>.Inject(out EcsIncField<T> self, EcsPool<T> pool)
|
|
||||||
{
|
|
||||||
self = new EcsIncField<T>(pool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct EcsExcField<T> : IEcsMemberCachePool<EcsExcField<T>, T>
|
|
||||||
where T :struct
|
|
||||||
{
|
|
||||||
private readonly EcsPool<T> _pool;
|
|
||||||
private readonly int _poolID;
|
|
||||||
|
|
||||||
public EcsPool<T> Pool => _pool;
|
|
||||||
public int PoolID => _poolID;
|
|
||||||
|
|
||||||
private EcsExcField(int poolID)
|
|
||||||
{
|
|
||||||
_pool = null;
|
|
||||||
_poolID = poolID;
|
|
||||||
}
|
|
||||||
internal EcsExcField(EcsPool<T> pool)
|
|
||||||
{
|
|
||||||
_pool = pool;
|
|
||||||
_poolID = pool.ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public ref T Add(int entityID)
|
|
||||||
{
|
|
||||||
return ref _pool.Add(entityID);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static implicit operator EcsExcField<T>(in int poolID) => new EcsExcField<T>(poolID);
|
|
||||||
|
|
||||||
void IEcsMemberCachePool<EcsExcField<T>, T>.Inject(out EcsExcField<T> self, EcsPool<T> pool)
|
|
||||||
{
|
|
||||||
self = new EcsExcField<T>(pool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 93de2f9d4ed4cd849a2b4fca39174c37
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
|
||||||
public readonly struct EcsTag : IEcsMemberCachePool<EcsTag, tag>
|
|
||||||
where T :struct
|
|
||||||
{
|
|
||||||
private readonly EcsPool<tag> _pool;
|
|
||||||
private readonly int _poolID;
|
|
||||||
|
|
||||||
public EcsPool<tag> Pool => _pool;
|
|
||||||
public int PoolID => _poolID;
|
|
||||||
|
|
||||||
private EcsTag(int poolID)
|
|
||||||
{
|
|
||||||
_pool = null;
|
|
||||||
_poolID = poolID;
|
|
||||||
}
|
|
||||||
internal EcsTag(EcsPool<tag> pool)
|
|
||||||
{
|
|
||||||
_pool = pool;
|
|
||||||
_poolID = pool.ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(int entityID)
|
|
||||||
{
|
|
||||||
_pool.Add(entityID);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static implicit operator EcsTag(in int poolID) => new EcsTag(poolID);
|
|
||||||
|
|
||||||
void IEcsMemberCachePool<EcsTag, tag>.Inject(out EcsTag self, EcsPool<tag> pool)
|
|
||||||
{
|
|
||||||
self = new EcsTag(pool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public readonly struct EcsIncTag : IEcsMemberCachePool<EcsIncTag, tag>
|
|
||||||
where T :struct
|
|
||||||
{
|
|
||||||
private readonly EcsPool<tag> _pool;
|
|
||||||
private readonly int _poolID;
|
|
||||||
|
|
||||||
public EcsPool<tag> Pool => _pool;
|
|
||||||
public int PoolID => _poolID;
|
|
||||||
|
|
||||||
private EcsIncTag(int poolID)
|
|
||||||
{
|
|
||||||
_pool = null;
|
|
||||||
_poolID = poolID;
|
|
||||||
}
|
|
||||||
internal EcsIncTag(EcsPool<tag> pool)
|
|
||||||
{
|
|
||||||
_pool = pool;
|
|
||||||
_poolID = pool.ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static implicit operator EcsIncTag(in int poolID) => new EcsIncTag(poolID);
|
|
||||||
|
|
||||||
void IEcsMemberCachePool<EcsIncTag, tag>.Inject(out EcsIncTag self, EcsPool<tag> pool)
|
|
||||||
{
|
|
||||||
self = new EcsIncTag(pool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public readonly struct EcsExcTag : IEcsMemberCachePool<EcsExcTag, tag>
|
|
||||||
where T :struct
|
|
||||||
{
|
|
||||||
private readonly EcsPool<tag> _pool;
|
|
||||||
private readonly int _poolID;
|
|
||||||
|
|
||||||
public EcsPool<tag> Pool => _pool;
|
|
||||||
public int PoolID => _poolID;
|
|
||||||
|
|
||||||
private EcsExcTag(int poolID)
|
|
||||||
{
|
|
||||||
_pool = null;
|
|
||||||
_poolID = poolID;
|
|
||||||
}
|
|
||||||
internal EcsExcTag(EcsPool<tag> pool)
|
|
||||||
{
|
|
||||||
_pool = pool;
|
|
||||||
_poolID = pool.ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static implicit operator EcsExcTag(in int poolID) => new EcsExcTag(poolID);
|
|
||||||
|
|
||||||
void IEcsMemberCachePool<EcsExcTag, tag>.Inject(out EcsExcTag self, EcsPool<tag> pool)
|
|
||||||
{
|
|
||||||
self = new EcsExcTag(pool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 524f71e4e46e94a44b302e2242150817
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
|
||||||
public interface IEcsTableMember
|
|
||||||
{
|
|
||||||
public int PoolID { get; }
|
|
||||||
}
|
|
||||||
public interface IEcsMemberCachePool<TSelf, T> : IEcsTableMember
|
|
||||||
where TSelf: struct, IEcsTableMember
|
|
||||||
where T :struct
|
|
||||||
{
|
|
||||||
public EcsPool<T> Pool { get; }
|
|
||||||
public void Inject(out TSelf self, EcsPool<T> pool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: e765044f6e73f5847aa432da56a1ec9d
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
Loading…
Reference in New Issue
Block a user