refactoring

This commit is contained in:
Mikhail 2023-03-16 01:49:14 +08:00
parent 31cc59f60f
commit 9db3f192ac
23 changed files with 21 additions and 407 deletions

View File

@ -1,7 +1,6 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: c0c409d38416ea840b358d614c3e62a4 guid: c616a590311a3c441ba37782d0d09ba1
folderAsset: yes TextScriptImporter:
DefaultImporter:
externalObjects: {} externalObjects: {}
userData: userData:
assetBundleName: assetBundleName:

View File

@ -17,7 +17,7 @@
public void Destroy(EcsSession session); public void Destroy(EcsSession session);
} }
public interface IEcsSimpleCycleSystem : public interface IEcsBaseSystem :
IEcsInitSystem, IEcsInitSystem,
IEcsRunSystem, IEcsRunSystem,
IEcsDestroySystem IEcsDestroySystem

View File

@ -1,11 +0,0 @@
namespace DCFApixels.DragonECS
{
public class DestroyProcessor : IEcsRunSystem
{
public void Run(EcsSession session)
{
}
}
public struct DestroyedTag { }
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: c48ecb209046a944e9602d18f3fd5237
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,10 +1,4 @@
using System; namespace DCFApixels.DragonECS
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DCFApixels.DragonECS
{ {
public interface IEcsInject<T> : IEcsSystem 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; private T _injectedData;
public InjectProcessor(T injectedData) public InjectSystem(T injectedData)
{ {
_injectedData = 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) public static EcsSession Inject<T>(this EcsSession self, T data)
{ {
self.Add(new InjectProcessor<T>(data)); self.Add(new InjectSystem<T>(data));
return self; return self;
} }

View File

@ -25,6 +25,8 @@ namespace DCFApixels.DragonECS
} }
public interface IEcsSystem { } public interface IEcsSystem { }
public interface IEcsRunner { }
public static class IEcsProcessorExtensions public static class IEcsProcessorExtensions
{ {
@ -90,7 +92,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InitFor<TInterface>() where TInterface : IEcsSystem internal static void InitFor<TInterface>() where TInterface : IEcsSystem
{ {
Type interfaceType = typeof(TInterface); Type interfaceType = typeof(TInterface);
Type nonGenericInterfaceType = interfaceType; Type nonGenericInterfaceType = interfaceType;
@ -113,15 +115,13 @@ namespace DCFApixels.DragonECS
} }
} }
public interface IEcsRunner { }
public abstract class EcsRunner<TInterface> : IEcsSystem, IEcsRunner public abstract class EcsRunner<TInterface> : IEcsSystem, IEcsRunner
where TInterface : IEcsSystem where TInterface : IEcsSystem
{ {
internal static void Init(Type subclass) internal static void Init(Type subclass)
{ {
#if DEBUG || DCFAECS_NO_SANITIZE_CHECKS #if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
if (_subclass != null) if (_subclass != null)
{ {
throw new ArgumentException($"The Runner<{typeof(TInterface).FullName}> can only have one subclass"); throw new ArgumentException($"The Runner<{typeof(TInterface).FullName}> can only have one subclass");

View File

@ -46,7 +46,7 @@ namespace DCFApixels.DragonECS
public abstract class EcsWorld public abstract class EcsWorld
{ {
internal static IEcsWorld[] Worlds = new IEcsWorld[8]; internal static IEcsWorld[] Worlds = new IEcsWorld[8];
private static IntDispenser _worldIdDispenser = new IntDispenser(); private static IntDispenser _worldIdDispenser = new IntDispenser(1);
public readonly short id; public readonly short id;
@ -182,7 +182,7 @@ namespace DCFApixels.DragonECS
#region IsMaskCompatible/IsMaskCompatibleWithout #region IsMaskCompatible/IsMaskCompatibleWithout
public bool IsMaskCompatible(EcsMask mask, int entity) public bool IsMaskCompatible(EcsMask mask, int entity)
{ {
#if DEBUG || !DCFAECS_NO_SANITIZE_CHECKS #if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
if (mask.WorldArchetypeType != typeof(TArchetype)) if (mask.WorldArchetypeType != typeof(TArchetype))
throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TArchetype)"); throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TArchetype)");
#endif #endif
@ -201,7 +201,7 @@ namespace DCFApixels.DragonECS
public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherComponentID) 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)) if (mask.WorldArchetypeType != typeof(TArchetype))
throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TArchetype)"); throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TArchetype)");
#endif #endif
@ -316,7 +316,7 @@ namespace DCFApixels.DragonECS
static ComponentType() static ComponentType()
{ {
uniqueID = ComponentType.increment++; uniqueID = ComponentType.increment++;
#if DEBUG || DCFAECS_NO_SANITIZE_CHECKS #if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
if (ComponentType.increment + 1 > ushort.MaxValue) if (ComponentType.increment + 1 > ushort.MaxValue)
{ {
throw new EcsFrameworkException($"No more room for new component for this {typeof(TArchetype).FullName} IWorldArchetype"); throw new EcsFrameworkException($"No more room for new component for this {typeof(TArchetype).FullName} IWorldArchetype");

View File

@ -29,12 +29,11 @@ namespace DCFApixels.DragonECS
get => (ushort)((_full << 32) >> 48); get => (ushort)((_full << 32) >> 48);
} }
// но чтобы значене default было NULL сульностью, мир хранится в виде ID + 1
[EditorBrowsable(EditorBrowsableState.Never)] [EditorBrowsable(EditorBrowsableState.Never)]
public short world public short world
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => (short)(((_full << 48) >> 48) - 1); get => (short)((_full << 48) >> 48);
} }
#endregion #endregion
@ -45,7 +44,7 @@ namespace DCFApixels.DragonECS
{ {
_full = ((long)id) << 32; _full = ((long)id) << 32;
_full += ((long)gen) << 16; _full += ((long)gen) << 16;
_full += ++world; // сдвиг айдишников + 1 _full += world;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Runtime.Serialization;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
@ -8,8 +9,6 @@ namespace DCFApixels.DragonECS
public EcsFrameworkException() { } public EcsFrameworkException() { }
public EcsFrameworkException(string message) : base(Exceptions.MESSAGE_SUFFIX + message) { } public EcsFrameworkException(string message) : base(Exceptions.MESSAGE_SUFFIX + message) { }
public EcsFrameworkException(string message, Exception inner) : base(Exceptions.MESSAGE_SUFFIX + message, inner) { } public EcsFrameworkException(string message, Exception inner) : base(Exceptions.MESSAGE_SUFFIX + message, inner) { }
protected EcsFrameworkException( protected EcsFrameworkException(SerializationInfo info, StreamingContext context) : base(info, context) { }
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
} }
} }

View File

@ -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) { }
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: b4766bca23373eb4cb95ecae89f45c3f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -7,4 +7,4 @@ DCFAECS_NO_SANITIZE_CHECKS - отвключение дополнительных
#if DEBUG || !DCFAECS_NO_SANITIZE_CHECKS #if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 7c2d964089dec3d439486d9a2c94dda2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,7 +0,0 @@
namespace DCFApixels.DragonECS
{
public readonly struct Ref<T> where T : class
{
public readonly T target;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: e85a87d0753512d4bb7b365dd451701a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 7b8a6b01f9e4e6041a681eadec261c55
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 0862221477782744a98863ae86648660
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: