mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-11-12 16:45:55 +08:00
refactoring
This commit is contained in:
parent
31cc59f60f
commit
9db3f192ac
@ -1,7 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0c409d38416ea840b358d614c3e62a4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
guid: c616a590311a3c441ba37782d0d09ba1
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@ -17,7 +17,7 @@
|
||||
public void Destroy(EcsSession session);
|
||||
}
|
||||
|
||||
public interface IEcsSimpleCycleSystem :
|
||||
public interface IEcsBaseSystem :
|
||||
IEcsInitSystem,
|
||||
IEcsRunSystem,
|
||||
IEcsDestroySystem
|
||||
@ -1,11 +0,0 @@
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public class DestroyProcessor : IEcsRunSystem
|
||||
{
|
||||
public void Run(EcsSession session)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public struct DestroyedTag { }
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c48ecb209046a944e9602d18f3fd5237
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface IEcsInject<T> : IEcsSystem
|
||||
{
|
||||
@ -21,11 +15,11 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
}
|
||||
|
||||
public class InjectProcessor<T> : IEcsPreInitSystem
|
||||
public class InjectSystem<T> : IEcsPreInitSystem
|
||||
{
|
||||
private T _injectedData;
|
||||
|
||||
public InjectProcessor(T injectedData)
|
||||
public InjectSystem(T injectedData)
|
||||
{
|
||||
_injectedData = injectedData;
|
||||
}
|
||||
@ -37,11 +31,11 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
}
|
||||
|
||||
public static class InjectProcessorExstensions
|
||||
public static class InjectSystemExstensions
|
||||
{
|
||||
public static EcsSession Inject<T>(this EcsSession self, T data)
|
||||
{
|
||||
self.Add(new InjectProcessor<T>(data));
|
||||
self.Add(new InjectSystem<T>(data));
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
|
||||
public interface IEcsSystem { }
|
||||
public interface IEcsRunner { }
|
||||
|
||||
|
||||
public static class IEcsProcessorExtensions
|
||||
{
|
||||
@ -90,7 +92,7 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void InitFor<TInterface>() where TInterface : IEcsSystem
|
||||
internal static void InitFor<TInterface>() where TInterface : IEcsSystem
|
||||
{
|
||||
Type interfaceType = typeof(TInterface);
|
||||
Type nonGenericInterfaceType = interfaceType;
|
||||
@ -113,15 +115,13 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
}
|
||||
|
||||
public interface IEcsRunner { }
|
||||
|
||||
public abstract class EcsRunner<TInterface> : IEcsSystem, IEcsRunner
|
||||
where TInterface : IEcsSystem
|
||||
{
|
||||
internal static void Init(Type subclass)
|
||||
{
|
||||
|
||||
#if DEBUG || DCFAECS_NO_SANITIZE_CHECKS
|
||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||
if (_subclass != null)
|
||||
{
|
||||
throw new ArgumentException($"The Runner<{typeof(TInterface).FullName}> can only have one subclass");
|
||||
@ -46,7 +46,7 @@ namespace DCFApixels.DragonECS
|
||||
public abstract class EcsWorld
|
||||
{
|
||||
internal static IEcsWorld[] Worlds = new IEcsWorld[8];
|
||||
private static IntDispenser _worldIdDispenser = new IntDispenser();
|
||||
private static IntDispenser _worldIdDispenser = new IntDispenser(1);
|
||||
|
||||
public readonly short id;
|
||||
|
||||
@ -182,7 +182,7 @@ namespace DCFApixels.DragonECS
|
||||
#region IsMaskCompatible/IsMaskCompatibleWithout
|
||||
public bool IsMaskCompatible(EcsMask mask, int entity)
|
||||
{
|
||||
#if DEBUG || !DCFAECS_NO_SANITIZE_CHECKS
|
||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||
if (mask.WorldArchetypeType != typeof(TArchetype))
|
||||
throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TArchetype)");
|
||||
#endif
|
||||
@ -201,7 +201,7 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherComponentID)
|
||||
{
|
||||
#if DEBUG || !DCFAECS_NO_SANITIZE_CHECKS
|
||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||
if (mask.WorldArchetypeType != typeof(TArchetype))
|
||||
throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TArchetype)");
|
||||
#endif
|
||||
@ -316,7 +316,7 @@ namespace DCFApixels.DragonECS
|
||||
static ComponentType()
|
||||
{
|
||||
uniqueID = ComponentType.increment++;
|
||||
#if DEBUG || DCFAECS_NO_SANITIZE_CHECKS
|
||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||
if (ComponentType.increment + 1 > ushort.MaxValue)
|
||||
{
|
||||
throw new EcsFrameworkException($"No more room for new component for this {typeof(TArchetype).FullName} IWorldArchetype");
|
||||
|
||||
@ -29,12 +29,11 @@ namespace DCFApixels.DragonECS
|
||||
get => (ushort)((_full << 32) >> 48);
|
||||
|
||||
}
|
||||
// но чтобы значене default было NULL сульностью, мир хранится в виде ID + 1
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public short world
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => (short)(((_full << 48) >> 48) - 1);
|
||||
get => (short)((_full << 48) >> 48);
|
||||
|
||||
}
|
||||
#endregion
|
||||
@ -45,7 +44,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
_full = ((long)id) << 32;
|
||||
_full += ((long)gen) << 16;
|
||||
_full += ++world; // сдвиг айдишников + 1
|
||||
_full += world;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
@ -8,8 +9,6 @@ namespace DCFApixels.DragonECS
|
||||
public EcsFrameworkException() { }
|
||||
public EcsFrameworkException(string message) : base(Exceptions.MESSAGE_SUFFIX + message) { }
|
||||
public EcsFrameworkException(string message, Exception inner) : base(Exceptions.MESSAGE_SUFFIX + message, inner) { }
|
||||
protected EcsFrameworkException(
|
||||
System.Runtime.Serialization.SerializationInfo info,
|
||||
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
|
||||
protected EcsFrameworkException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
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) { }
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4766bca23373eb4cb95ecae89f45c3f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -7,4 +7,4 @@ DCFAECS_NO_SANITIZE_CHECKS - отвключение дополнительных
|
||||
|
||||
|
||||
|
||||
#if DEBUG || !DCFAECS_NO_SANITIZE_CHECKS
|
||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c2d964089dec3d439486d9a2c94dda2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,7 +0,0 @@
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public readonly struct Ref<T> where T : class
|
||||
{
|
||||
public readonly T target;
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e85a87d0753512d4bb7b365dd451701a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,17 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b8a6b01f9e4e6041a681eadec261c55
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,264 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
|
||||
namespace DCFApixels
|
||||
{
|
||||
public class GrowingSparseCollection<TValue>
|
||||
{
|
||||
private const int EMPTY = -1;
|
||||
|
||||
private int[] _buckets = Array.Empty<int>();
|
||||
private Entry[] _entries = Array.Empty<Entry>();
|
||||
|
||||
private int _capacity;
|
||||
private int _count;
|
||||
|
||||
#region Properties
|
||||
public TValue this[int key]
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _entries[FindEntry(key)].value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Add
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Add(int key, TValue value)
|
||||
{
|
||||
#if DEBUG
|
||||
if (Contains(key))
|
||||
throw new ArgumentException("Contains(key) is true");
|
||||
#endif
|
||||
Insert(key, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Getter
|
||||
public bool TryGetValue(int key, out TValue value)
|
||||
{
|
||||
int index = IndexOfKey(key);
|
||||
if (index < 0)
|
||||
{
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
value = _entries[index].value;
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
public GrowingSparseCollection(int capacity)
|
||||
{
|
||||
Initialize(capacity);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Initialize
|
||||
private void Initialize(int capacity)
|
||||
{
|
||||
_capacity = HashHelpers.GetPrime(capacity);
|
||||
_buckets = new int[_capacity];
|
||||
|
||||
for (int i = 0; i < _capacity; i++)
|
||||
_buckets[i] = EMPTY;
|
||||
|
||||
_entries = new Entry[_capacity];
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Clear
|
||||
public void Clear()
|
||||
{
|
||||
if (_count > 0)
|
||||
{
|
||||
for (int i = 0; i < _buckets.Length; i++)
|
||||
{
|
||||
_buckets[i] = -1;
|
||||
}
|
||||
Array.Clear(_entries, 0, _count);
|
||||
_count = 0;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Contains
|
||||
public bool Contains(int key)
|
||||
{
|
||||
return IndexOfKey(key) >= 0;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IndexOfKey/Find/Insert
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int IndexOfKey(int key)
|
||||
{
|
||||
key &= ~int.MinValue;
|
||||
for (int i = _buckets[key % _capacity]; i >= 0; i = _entries[i].next)
|
||||
{
|
||||
if (_entries[i].key == key)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private int FindEntry(int key)
|
||||
{
|
||||
key &= ~int.MinValue;
|
||||
for (int i = _buckets[key % _capacity]; i >= 0; i = _entries[i].next)
|
||||
{
|
||||
if (_entries[i].key == key)
|
||||
return i;
|
||||
}
|
||||
throw new KeyNotFoundException();
|
||||
}
|
||||
|
||||
private void Insert(int key, TValue value)
|
||||
{
|
||||
key &= ~int.MinValue;
|
||||
int targetBucket = key % _capacity;
|
||||
|
||||
for (int i = _buckets[targetBucket]; i >= 0; i = _entries[i].next)
|
||||
{
|
||||
if (_entries[i].key == key)
|
||||
{
|
||||
_entries[i].value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (_count >= _entries.Length)
|
||||
{
|
||||
Resize();
|
||||
targetBucket = key % _capacity;
|
||||
}
|
||||
int index = _count;
|
||||
_count++;
|
||||
|
||||
_entries[index].next = _buckets[targetBucket];
|
||||
_entries[index].key = key;
|
||||
_entries[index].value = value;
|
||||
_buckets[targetBucket] = index;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Resize
|
||||
private void Resize()
|
||||
{
|
||||
Resize(HashHelpers.ExpandPrime(_count), false);
|
||||
}
|
||||
private void Resize(int newSize, bool forceNewHashCodes)
|
||||
{
|
||||
_capacity = newSize;
|
||||
Contract.Assert(newSize >= _entries.Length);
|
||||
int[] newBuckets = new int[newSize];
|
||||
for (int i = 0; i < newBuckets.Length; i++)
|
||||
{
|
||||
newBuckets[i] = EMPTY;
|
||||
}
|
||||
Entry[] newEntries = new Entry[newSize];
|
||||
Array.Copy(_entries, 0, newEntries, 0, _count);
|
||||
if (forceNewHashCodes)
|
||||
{
|
||||
for (int i = 0; i < _count; i++)
|
||||
{
|
||||
if (newEntries[i].key != -1)
|
||||
{
|
||||
newEntries[i].key = newEntries[i].key;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < _count; i++)
|
||||
{
|
||||
if (newEntries[i].key >= 0)
|
||||
{
|
||||
int bucket = newEntries[i].key % newSize;
|
||||
newEntries[i].next = newBuckets[bucket];
|
||||
newBuckets[bucket] = i;
|
||||
}
|
||||
}
|
||||
_buckets = newBuckets;
|
||||
_entries = newEntries;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Utils
|
||||
private struct Entry
|
||||
{
|
||||
public int next; // Index of next entry, -1 if last
|
||||
public int key; // key & hash
|
||||
public TValue value;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region HashHelpers
|
||||
internal static class HashHelpers
|
||||
{
|
||||
public const int MaxPrimeArrayLength = 0x7FEFFFFD;
|
||||
public static readonly int[] primes = {
|
||||
3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919,
|
||||
1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591,
|
||||
17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437,
|
||||
187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263,
|
||||
1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369};
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
public static bool IsPrime(int candidate)
|
||||
{
|
||||
if ((candidate & 1) != 0)
|
||||
{
|
||||
int limit = (int)Math.Sqrt(candidate);
|
||||
for (int divisor = 3; divisor <= limit; divisor += 2)
|
||||
{
|
||||
if ((candidate % divisor) == 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return (candidate == 2);
|
||||
}
|
||||
|
||||
public static int ExpandPrime(int oldSize)
|
||||
{
|
||||
int newSize = 2 * oldSize;
|
||||
|
||||
if ((uint)newSize > MaxPrimeArrayLength && MaxPrimeArrayLength > oldSize)
|
||||
{
|
||||
Contract.Assert(MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength");
|
||||
return MaxPrimeArrayLength;
|
||||
}
|
||||
|
||||
return GetPrime(newSize);
|
||||
}
|
||||
internal const int HashtableHashPrime = 101;
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
public static int GetPrime(int min)
|
||||
{
|
||||
if (min < 0)
|
||||
{
|
||||
throw new ArgumentException("min < 0"); //TODO
|
||||
}
|
||||
Contract.EndContractBlock();
|
||||
|
||||
for (int i = 0; i < primes.Length; i++)
|
||||
{
|
||||
int prime = primes[i];
|
||||
if (prime >= min)
|
||||
return prime;
|
||||
}
|
||||
|
||||
for (int i = (min | 1); i < int.MaxValue; i += 2)
|
||||
{
|
||||
if (IsPrime(i) && ((i - 1) % HashtableHashPrime != 0))
|
||||
return i;
|
||||
}
|
||||
return min;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0862221477782744a98863ae86648660
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Reference in New Issue
Block a user