mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-11-13 00:55:55 +08:00
refactoring
This commit is contained in:
parent
31cc59f60f
commit
9db3f192ac
@ -1,7 +1,6 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: c0c409d38416ea840b358d614c3e62a4
|
guid: c616a590311a3c441ba37782d0d09ba1
|
||||||
folderAsset: yes
|
TextScriptImporter:
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
@ -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
|
||||||
@ -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;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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");
|
||||||
@ -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");
|
||||||
|
|||||||
@ -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)]
|
||||||
@ -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) { }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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