mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-19 10:34:37 +08:00
Merge branch 'dev' into test-pool
This commit is contained in:
commit
08021f25be
@ -10,7 +10,7 @@
|
|||||||
<RootNamespace>DCFApixels.DragonECS</RootNamespace>
|
<RootNamespace>DCFApixels.DragonECS</RootNamespace>
|
||||||
|
|
||||||
<Title>DragonECS</Title>
|
<Title>DragonECS</Title>
|
||||||
<Version>0.9.1</Version>
|
<Version>0.9.9</Version>
|
||||||
<Authors>DCFApixels</Authors>
|
<Authors>DCFApixels</Authors>
|
||||||
<Description>ECS Framework for Game Engines with C# and .Net Platform</Description>
|
<Description>ECS Framework for Game Engines with C# and .Net Platform</Description>
|
||||||
<Copyright>DCFApixels</Copyright>
|
<Copyright>DCFApixels</Copyright>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
"displayName": "DragonECS",
|
"displayName": "DragonECS",
|
||||||
"description": "C# Entity Component System Framework",
|
"description": "C# Entity Component System Framework",
|
||||||
"unity": "2020.3",
|
"unity": "2020.3",
|
||||||
"version": "0.9.4",
|
"version": "0.9.9",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/DCFApixels/DragonECS.git"
|
"url": "https://github.com/DCFApixels/DragonECS.git"
|
||||||
|
@ -10,7 +10,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Init() is called. Before Init")]
|
[MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Init() is called. Before Init")]
|
||||||
[MetaID("DE26527C92015AFDD4ECF4D81A4C946B")]
|
[MetaID("DragonECS_DE26527C92015AFDD4ECF4D81A4C946B")]
|
||||||
public interface IEcsPreInit : IEcsProcess
|
public interface IEcsPreInit : IEcsProcess
|
||||||
{
|
{
|
||||||
void PreInit();
|
void PreInit();
|
||||||
@ -19,7 +19,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Init() is called. After PreInit")]
|
[MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Init() is called. After PreInit")]
|
||||||
[MetaID("CC45527C9201DF82DCAAAEF33072F9EF")]
|
[MetaID("DragonECS_CC45527C9201DF82DCAAAEF33072F9EF")]
|
||||||
public interface IEcsInit : IEcsProcess
|
public interface IEcsInit : IEcsProcess
|
||||||
{
|
{
|
||||||
void Init();
|
void Init();
|
||||||
@ -28,7 +28,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Run() is called.")]
|
[MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Run() is called.")]
|
||||||
[MetaID("9654527C9201BE75546322B9BB03C131")]
|
[MetaID("DragonECS_9654527C9201BE75546322B9BB03C131")]
|
||||||
public interface IEcsRun : IEcsProcess
|
public interface IEcsRun : IEcsProcess
|
||||||
{
|
{
|
||||||
void Run();
|
void Run();
|
||||||
@ -44,7 +44,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Destroy() is called.")]
|
[MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Destroy() is called.")]
|
||||||
[MetaID("4661527C9201EE669C6EB61B19899AE5")]
|
[MetaID("DragonECS_4661527C9201EE669C6EB61B19899AE5")]
|
||||||
public interface IEcsDestroy : IEcsProcess
|
public interface IEcsDestroy : IEcsProcess
|
||||||
{
|
{
|
||||||
void Destroy();
|
void Destroy();
|
||||||
@ -62,7 +62,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "...")]
|
[MetaDescription(EcsConsts.AUTHOR, "...")]
|
||||||
[MetaTags(MetaTags.HIDDEN)]
|
[MetaTags(MetaTags.HIDDEN)]
|
||||||
[MetaID("3273527C9201285BAA0A463F700A50FB")]
|
[MetaID("DragonECS_3273527C9201285BAA0A463F700A50FB")]
|
||||||
internal sealed class EcsPreInitRunner : EcsRunner<IEcsPreInit>, IEcsPreInit
|
internal sealed class EcsPreInitRunner : EcsRunner<IEcsPreInit>, IEcsPreInit
|
||||||
{
|
{
|
||||||
private RunHelper _helper;
|
private RunHelper _helper;
|
||||||
@ -83,7 +83,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "...")]
|
[MetaDescription(EcsConsts.AUTHOR, "...")]
|
||||||
[MetaTags(MetaTags.HIDDEN)]
|
[MetaTags(MetaTags.HIDDEN)]
|
||||||
[MetaID("ED85527C9201A391AB8EC0B734917859")]
|
[MetaID("DragonECS_ED85527C9201A391AB8EC0B734917859")]
|
||||||
internal sealed class EcsInitRunner : EcsRunner<IEcsInit>, IEcsInit
|
internal sealed class EcsInitRunner : EcsRunner<IEcsInit>, IEcsInit
|
||||||
{
|
{
|
||||||
private RunHelper _helper;
|
private RunHelper _helper;
|
||||||
@ -104,7 +104,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "...")]
|
[MetaDescription(EcsConsts.AUTHOR, "...")]
|
||||||
[MetaTags(MetaTags.HIDDEN)]
|
[MetaTags(MetaTags.HIDDEN)]
|
||||||
[MetaID("2098527C9201F260C840BFD50BC7E0BA")]
|
[MetaID("DragonECS_2098527C9201F260C840BFD50BC7E0BA")]
|
||||||
internal sealed class EcsRunRunner : EcsRunner<IEcsRun>, IEcsRun
|
internal sealed class EcsRunRunner : EcsRunner<IEcsRun>, IEcsRun
|
||||||
{
|
{
|
||||||
private readonly struct Pair
|
private readonly struct Pair
|
||||||
@ -150,9 +150,10 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
#if DRAGONECS_DISABLE_CATH_EXCEPTIONS
|
#if DRAGONECS_DISABLE_CATH_EXCEPTIONS
|
||||||
throw;
|
throw e;
|
||||||
#endif
|
#else
|
||||||
EcsDebug.PrintError(e);
|
EcsDebug.PrintError(e);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -184,7 +185,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "...")]
|
[MetaDescription(EcsConsts.AUTHOR, "...")]
|
||||||
[MetaTags(MetaTags.HIDDEN)]
|
[MetaTags(MetaTags.HIDDEN)]
|
||||||
[MetaID("06A6527C92010430ACEB3DA520F272CC")]
|
[MetaID("DragonECS_06A6527C92010430ACEB3DA520F272CC")]
|
||||||
internal sealed class EcsDestroyRunner : EcsRunner<IEcsDestroy>, IEcsDestroy
|
internal sealed class EcsDestroyRunner : EcsRunner<IEcsDestroy>, IEcsDestroy
|
||||||
{
|
{
|
||||||
private RunHelper _helper;
|
private RunHelper _helper;
|
||||||
|
@ -10,12 +10,13 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.WORLDS_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.WORLDS_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "Inherits EcsWorld without extending its functionality and is used for specific injections. Can be used to store regular game entities, can also be used as a single world in the game for all entities.")]
|
[MetaDescription(EcsConsts.AUTHOR, "Inherits EcsWorld without extending its functionality and is used for specific injections. Can be used to store regular game entities, can also be used as a single world in the game for all entities.")]
|
||||||
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
||||||
[MetaID("4EE3527C92015BAB0299CB7B4E2663D1")]
|
[MetaID("DragonECS_4EE3527C92015BAB0299CB7B4E2663D1")]
|
||||||
public sealed class EcsDefaultWorld : EcsWorld, IInjectionUnit
|
public sealed class EcsDefaultWorld : EcsWorld, IInjectionUnit
|
||||||
{
|
{
|
||||||
public EcsDefaultWorld() : base() { }
|
private const string DEFAULT_NAME = "Default";
|
||||||
public EcsDefaultWorld(EcsWorldConfig config = null, string name = null, short worldID = -1) : base(config, name == null ? "Default" : name, worldID) { }
|
public EcsDefaultWorld() : base(default(EcsWorldConfig), DEFAULT_NAME) { }
|
||||||
public EcsDefaultWorld(IConfigContainer configs, string name = null, short worldID = -1) : base(configs, name == null ? "Default" : name, worldID) { }
|
public EcsDefaultWorld(EcsWorldConfig config = null, string name = null, short worldID = -1) : base(config, name == null ? DEFAULT_NAME : name, worldID) { }
|
||||||
|
public EcsDefaultWorld(IConfigContainer configs, string name = null, short worldID = -1) : base(configs, name == null ? DEFAULT_NAME : name, worldID) { }
|
||||||
void IInjectionUnit.InitInjectionNode(InjectionGraph nodes) { nodes.AddNode(this); }
|
void IInjectionUnit.InitInjectionNode(InjectionGraph nodes) { nodes.AddNode(this); }
|
||||||
}
|
}
|
||||||
/// <summary> EcsWrold for store event entities. </summary>
|
/// <summary> EcsWrold for store event entities. </summary>
|
||||||
@ -23,12 +24,13 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.WORLDS_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.WORLDS_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "Inherits EcsWorld without extending its functionality and is used for specific injections. Can be used to store event entities.")]
|
[MetaDescription(EcsConsts.AUTHOR, "Inherits EcsWorld without extending its functionality and is used for specific injections. Can be used to store event entities.")]
|
||||||
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
||||||
[MetaID("D7CE527C920160BCD765EFA72DBF8B89")]
|
[MetaID("DragonECS_D7CE527C920160BCD765EFA72DBF8B89")]
|
||||||
public sealed class EcsEventWorld : EcsWorld, IInjectionUnit
|
public sealed class EcsEventWorld : EcsWorld, IInjectionUnit
|
||||||
{
|
{
|
||||||
public EcsEventWorld() : base() { }
|
private const string DEFAULT_NAME = "Events";
|
||||||
public EcsEventWorld(EcsWorldConfig config = null, string name = null, short worldID = -1) : base(config, name == null ? "Events" : name, worldID) { }
|
public EcsEventWorld() : base(default(EcsWorldConfig), DEFAULT_NAME) { }
|
||||||
public EcsEventWorld(IConfigContainer configs, string name = null, short worldID = -1) : base(configs, name == null ? "Events" : name, worldID) { }
|
public EcsEventWorld(EcsWorldConfig config = null, string name = null, short worldID = -1) : base(config, name == null ? DEFAULT_NAME : name, worldID) { }
|
||||||
|
public EcsEventWorld(IConfigContainer configs, string name = null, short worldID = -1) : base(configs, name == null ? DEFAULT_NAME : name, worldID) { }
|
||||||
void IInjectionUnit.InitInjectionNode(InjectionGraph nodes) { nodes.AddNode(this); }
|
void IInjectionUnit.InitInjectionNode(InjectionGraph nodes) { nodes.AddNode(this); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,7 +400,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
if (++_count >= _dense.Length)
|
if (++_count >= _dense.Length)
|
||||||
{
|
{
|
||||||
Array.Resize(ref _dense, ArrayUtility.NormalizeSizeToPowerOfTwo(_count << 1));
|
Array.Resize(ref _dense, ArrayUtility.NextPow2(_count << 1));
|
||||||
}
|
}
|
||||||
_dense[_count] = entityID;
|
_dense[_count] = entityID;
|
||||||
|
|
||||||
@ -531,7 +531,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
if (minSize >= _dense.Length)
|
if (minSize >= _dense.Length)
|
||||||
{
|
{
|
||||||
Array.Resize(ref _dense, ArrayUtility.NormalizeSizeToPowerOfTwo_ClampOverflow(minSize));
|
Array.Resize(ref _dense, ArrayUtility.NextPow2_ClampOverflow(minSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,7 +618,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
if (dynamicBuffer.Length < _count)
|
if (dynamicBuffer.Length < _count)
|
||||||
{
|
{
|
||||||
Array.Resize(ref dynamicBuffer, ArrayUtility.NormalizeSizeToPowerOfTwo(_count));
|
Array.Resize(ref dynamicBuffer, ArrayUtility.NextPow2(_count));
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var e in this)
|
foreach (var e in this)
|
||||||
|
@ -97,7 +97,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
if (dynamicBuffer.Length < _values.Length)
|
if (dynamicBuffer.Length < _values.Length)
|
||||||
{
|
{
|
||||||
Array.Resize(ref dynamicBuffer, ArrayUtility.NormalizeSizeToPowerOfTwo(_values.Length));
|
Array.Resize(ref dynamicBuffer, ArrayUtility.NextPow2(_values.Length));
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var e in this)
|
foreach (var e in this)
|
||||||
@ -246,7 +246,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
if (dynamicBuffer.Length < _source.Count)
|
if (dynamicBuffer.Length < _source.Count)
|
||||||
{
|
{
|
||||||
Array.Resize(ref dynamicBuffer, ArrayUtility.NormalizeSizeToPowerOfTwo(_source.Count));
|
Array.Resize(ref dynamicBuffer, ArrayUtility.NextPow2(_source.Count));
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var e in this)
|
foreach (var e in this)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#endif
|
#endif
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS.Core
|
||||||
{
|
{
|
||||||
#region IEcsWorldComponent
|
#region IEcsWorldComponent
|
||||||
public interface IEcsWorldComponent<T>
|
public interface IEcsWorldComponent<T>
|
||||||
@ -44,11 +44,11 @@ namespace DCFApixels.DragonECS
|
|||||||
void Enable(ref T component);
|
void Enable(ref T component);
|
||||||
void Disable(ref T component);
|
void Disable(ref T component);
|
||||||
}
|
}
|
||||||
public static class EcsComponentResetHandler<T>
|
public static class EcsComponentLifecycleHandler<T>
|
||||||
{
|
{
|
||||||
public static readonly IEcsComponentLifecycle<T> instance;
|
public static readonly IEcsComponentLifecycle<T> instance;
|
||||||
public static readonly bool isHasHandler;
|
public static readonly bool isHasHandler;
|
||||||
static EcsComponentResetHandler()
|
static EcsComponentLifecycleHandler()
|
||||||
{
|
{
|
||||||
T def = default;
|
T def = default;
|
||||||
if (def is IEcsComponentLifecycle<T> intrf)
|
if (def is IEcsComponentLifecycle<T> intrf)
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
#if DISABLE_DEBUG
|
#if DISABLE_DEBUG
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
using DCFApixels.DragonECS.Core;
|
||||||
using DCFApixels.DragonECS.Internal;
|
using DCFApixels.DragonECS.Internal;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using static DCFApixels.DragonECS.EcsConsts;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
using static EcsConsts;
|
#region EcsProfilerMarker
|
||||||
public readonly struct EcsProfilerMarker
|
public readonly struct EcsProfilerMarker
|
||||||
{
|
{
|
||||||
#if DEBUG || DRAGONECS_ENABLE_DEBUG_SERVICE
|
#if DEBUG || DRAGONECS_ENABLE_DEBUG_SERVICE
|
||||||
@ -75,13 +77,15 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static explicit operator EcsProfilerMarker(string markerName) { return new EcsProfilerMarker(markerName); }
|
public static explicit operator EcsProfilerMarker(string markerName) { return new EcsProfilerMarker(markerName); }
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(PACK_GROUP, DEBUG_GROUP)]
|
[MetaGroup(PACK_GROUP, DEBUG_GROUP)]
|
||||||
[MetaDescription(AUTHOR, "Debugging utility. To modify or change the behavior, create a new class inherited from DebugService and set this service using DebugService.Set<T>().")]
|
[MetaDescription(AUTHOR, "Debugging utility. To modify or change the behavior, create a new class inherited from DebugService and set this service using DebugService.Set<T>().")]
|
||||||
[MetaID("10A4587C92013B55820D8604D718A1C3")]
|
[MetaID("DragonECS_10A4587C92013B55820D8604D718A1C3")]
|
||||||
public static class EcsDebug
|
public static class EcsDebug
|
||||||
{
|
{
|
||||||
|
#region Set
|
||||||
public static void Set<T>() where T : DebugService, new()
|
public static void Set<T>() where T : DebugService, new()
|
||||||
{
|
{
|
||||||
DebugService.Set<T>();
|
DebugService.Set<T>();
|
||||||
@ -90,7 +94,12 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
DebugService.Set(service);
|
DebugService.Set(service);
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Print
|
||||||
|
#if UNITY_2021_3_OR_NEWER
|
||||||
|
[UnityEngine.HideInCallstack]
|
||||||
|
#endif
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void PrintWarning(object v)
|
public static void PrintWarning(object v)
|
||||||
{
|
{
|
||||||
@ -99,6 +108,9 @@ namespace DCFApixels.DragonECS
|
|||||||
DebugService.CurrentThreadInstance.PrintWarning(v);
|
DebugService.CurrentThreadInstance.PrintWarning(v);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#if UNITY_2021_3_OR_NEWER
|
||||||
|
[UnityEngine.HideInCallstack]
|
||||||
|
#endif
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void PrintError(object v)
|
public static void PrintError(object v)
|
||||||
{
|
{
|
||||||
@ -107,6 +119,9 @@ namespace DCFApixels.DragonECS
|
|||||||
DebugService.CurrentThreadInstance.PrintError(v);
|
DebugService.CurrentThreadInstance.PrintError(v);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#if UNITY_2021_3_OR_NEWER
|
||||||
|
[UnityEngine.HideInCallstack]
|
||||||
|
#endif
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void PrintErrorAndBreak(object v)
|
public static void PrintErrorAndBreak(object v)
|
||||||
{
|
{
|
||||||
@ -115,6 +130,9 @@ namespace DCFApixels.DragonECS
|
|||||||
DebugService.CurrentThreadInstance.PrintErrorAndBreak(v);
|
DebugService.CurrentThreadInstance.PrintErrorAndBreak(v);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#if UNITY_2021_3_OR_NEWER
|
||||||
|
[UnityEngine.HideInCallstack]
|
||||||
|
#endif
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void PrintPass(object v)
|
public static void PrintPass(object v)
|
||||||
{
|
{
|
||||||
@ -123,6 +141,9 @@ namespace DCFApixels.DragonECS
|
|||||||
DebugService.CurrentThreadInstance.PrintPass(v);
|
DebugService.CurrentThreadInstance.PrintPass(v);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#if UNITY_2021_3_OR_NEWER
|
||||||
|
[UnityEngine.HideInCallstack]
|
||||||
|
#endif
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void Print()
|
public static void Print()
|
||||||
{
|
{
|
||||||
@ -131,6 +152,9 @@ namespace DCFApixels.DragonECS
|
|||||||
DebugService.CurrentThreadInstance.Print();
|
DebugService.CurrentThreadInstance.Print();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#if UNITY_2021_3_OR_NEWER
|
||||||
|
[UnityEngine.HideInCallstack]
|
||||||
|
#endif
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void Print(object v)
|
public static void Print(object v)
|
||||||
{
|
{
|
||||||
@ -139,6 +163,9 @@ namespace DCFApixels.DragonECS
|
|||||||
DebugService.CurrentThreadInstance.Print(v);
|
DebugService.CurrentThreadInstance.Print(v);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#if UNITY_2021_3_OR_NEWER
|
||||||
|
[UnityEngine.HideInCallstack]
|
||||||
|
#endif
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void Print(string tag, object v)
|
public static void Print(string tag, object v)
|
||||||
{
|
{
|
||||||
@ -147,6 +174,9 @@ namespace DCFApixels.DragonECS
|
|||||||
DebugService.CurrentThreadInstance.Print(tag, v);
|
DebugService.CurrentThreadInstance.Print(tag, v);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Other
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void Break()
|
public static void Break()
|
||||||
{
|
{
|
||||||
@ -154,9 +184,12 @@ namespace DCFApixels.DragonECS
|
|||||||
DebugService.CurrentThreadInstance.Break();
|
DebugService.CurrentThreadInstance.Break();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Events
|
||||||
public static OnPrintHandler OnPrint = delegate { };
|
public static OnPrintHandler OnPrint = delegate { };
|
||||||
public delegate void OnPrintHandler(string tag, object v);
|
public delegate void OnPrintHandler(string tag, object v);
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------------------//
|
//------------------------------------------------------------------------------------------------------------//
|
||||||
@ -164,19 +197,23 @@ namespace DCFApixels.DragonECS
|
|||||||
public abstract class DebugService
|
public abstract class DebugService
|
||||||
{
|
{
|
||||||
private static DebugService _instance;
|
private static DebugService _instance;
|
||||||
private static object _lock = new object();
|
private readonly static object _lock = new object();
|
||||||
|
|
||||||
private static HashSet<DebugService> _threadServiceClonesSet = new HashSet<DebugService>();
|
private readonly static HashSet<DebugService> _threadServiceClonesSet = new HashSet<DebugService>();
|
||||||
|
|
||||||
[ThreadStatic]
|
[ThreadStatic]
|
||||||
private static DebugService _currentThreadInstanceClone;
|
private static DebugService _currentThreadInstanceClone;
|
||||||
[ThreadStatic]
|
[ThreadStatic]
|
||||||
private static DebugService _currentThreadInstance; // для сравнения
|
private static DebugService _currentThreadInstance; // для сравнения
|
||||||
|
|
||||||
private static IdDispenser _idDispenser = new IdDispenser(16, 0);
|
private readonly static IdDispenser _idDispenser = new IdDispenser(16, 0);
|
||||||
private static Dictionary<string, int> _nameIdTable = new Dictionary<string, int>();
|
private readonly static Dictionary<string, int> _nameIdTable = new Dictionary<string, int>();
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
public static bool IsNullOrDefault
|
||||||
|
{
|
||||||
|
get { return _instance == null || _instance is NullDebugService || _instance is DefaultDebugService; }
|
||||||
|
}
|
||||||
public static DebugService Instance
|
public static DebugService Instance
|
||||||
{
|
{
|
||||||
get { return _instance; }
|
get { return _instance; }
|
||||||
@ -207,10 +244,14 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Static Constructor
|
||||||
static DebugService()
|
static DebugService()
|
||||||
{
|
{
|
||||||
|
#if !UNITY_5_3_OR_NEWER
|
||||||
|
Set(new NullDebugService());
|
||||||
|
#else
|
||||||
Set(new DefaultDebugService());
|
Set(new DefaultDebugService());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -241,15 +282,17 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
service.OnNewProfilerMark(record.Value, record.Key);
|
service.OnNewProfilerMark(record.Value, record.Key);
|
||||||
}
|
}
|
||||||
service.OnServiceSetup(oldService);
|
oldService?.OnDisableBaseService(service);
|
||||||
|
service.OnEnableBaseService(oldService);
|
||||||
OnServiceChanged(service);
|
OnServiceChanged(service);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region OnServiceSetup/CreateThreadInstance
|
#region OnEnable/OnDisable/CreateThreadInstance
|
||||||
protected virtual void OnServiceSetup(DebugService oldService) { }
|
protected virtual void OnEnableBaseService(DebugService prevService) { }
|
||||||
|
protected virtual void OnDisableBaseService(DebugService nextService) { }
|
||||||
protected abstract DebugService CreateThreadInstance();
|
protected abstract DebugService CreateThreadInstance();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -328,10 +371,17 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public static OnServiceChangedHandler OnServiceChanged = delegate { };
|
#region Events
|
||||||
|
public static event OnServiceChangedHandler OnServiceChanged = delegate { };
|
||||||
|
|
||||||
public delegate void OnServiceChangedHandler(DebugService service);
|
public delegate void OnServiceChangedHandler(DebugService service);
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS.Core
|
||||||
|
{
|
||||||
|
#region DebugServiceExtensions
|
||||||
public static class DebugServiceExtensions
|
public static class DebugServiceExtensions
|
||||||
{
|
{
|
||||||
public static void PrintWarning(this DebugService self, object v)
|
public static void PrintWarning(this DebugService self, object v)
|
||||||
@ -361,7 +411,9 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
//TODO PrintJson возможно будет добавлено когда-то
|
//TODO PrintJson возможно будет добавлено когда-то
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region DefaultServices
|
||||||
//------------------------------------------------------------------------------------------------------------//
|
//------------------------------------------------------------------------------------------------------------//
|
||||||
|
|
||||||
public sealed class NullDebugService : DebugService
|
public sealed class NullDebugService : DebugService
|
||||||
@ -379,7 +431,6 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
public sealed class DefaultDebugService : DebugService
|
public sealed class DefaultDebugService : DebugService
|
||||||
{
|
{
|
||||||
#if !UNITY_5_3_OR_NEWER
|
|
||||||
private const string PROFILER_MARKER = "ProfilerMark";
|
private const string PROFILER_MARKER = "ProfilerMark";
|
||||||
private const string PROFILER_MARKER_CACHE = "[" + PROFILER_MARKER + "] ";
|
private const string PROFILER_MARKER_CACHE = "[" + PROFILER_MARKER + "] ";
|
||||||
|
|
||||||
@ -548,14 +599,6 @@ namespace DCFApixels.DragonECS
|
|||||||
return this.AutoToString();
|
return this.AutoToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
protected sealed override DebugService CreateThreadInstance() { return this; }
|
|
||||||
public sealed override void Break() { }
|
|
||||||
public sealed override void Print(string tag, object v) { }
|
|
||||||
public sealed override void ProfilerMarkBegin(int id) { }
|
|
||||||
public sealed override void ProfilerMarkEnd(int id) { }
|
|
||||||
protected sealed override void OnDelProfilerMark(int id) { }
|
|
||||||
protected sealed override void OnNewProfilerMark(int id, string name) { }
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
#if DISABLE_DEBUG
|
#if DISABLE_DEBUG
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
using DCFApixels.DragonECS.Internal;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
#if DEBUG || !REFLECTION_DISABLED
|
#if DEBUG || !REFLECTION_DISABLED
|
||||||
@ -312,6 +313,9 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
public static TypeMeta GetMeta(this object self)
|
public static TypeMeta GetMeta(this object self)
|
||||||
{
|
{
|
||||||
|
#if DEBUG && DRAGONECS_DEEP_DEBUG
|
||||||
|
if (self is Type type) { Throw.DeepDebugException(); }
|
||||||
|
#endif
|
||||||
return EcsDebugUtility.GetTypeMeta(self);
|
return EcsDebugUtility.GetTypeMeta(self);
|
||||||
}
|
}
|
||||||
public static TypeMeta ToMeta(this Type self)
|
public static TypeMeta ToMeta(this Type self)
|
||||||
|
@ -28,6 +28,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
get { return string.IsNullOrEmpty(Author) == false; }
|
get { return string.IsNullOrEmpty(Author) == false; }
|
||||||
}
|
}
|
||||||
|
public MetaDescription(string text) : this(null, text) { }
|
||||||
public MetaDescription(string author, string text)
|
public MetaDescription(string author, string text)
|
||||||
{
|
{
|
||||||
if (author == null) { author = string.Empty; }
|
if (author == null) { author = string.Empty; }
|
||||||
|
@ -12,54 +12,67 @@ namespace DCFApixels.DragonECS
|
|||||||
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
|
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
|
||||||
public sealed class MetaGroupAttribute : EcsMetaAttribute
|
public sealed class MetaGroupAttribute : EcsMetaAttribute
|
||||||
{
|
{
|
||||||
public const char SEPARATOR = '/';
|
public const char SEPARATOR = MetaGroup.SEPARATOR;
|
||||||
public readonly MetaGroup Data;
|
public readonly string Name = string.Empty;
|
||||||
|
|
||||||
[Obsolete(EcsMetaAttributeHalper.EMPTY_NO_SENSE_MESSAGE)]
|
[Obsolete(EcsMetaAttributeHalper.EMPTY_NO_SENSE_MESSAGE)]
|
||||||
public MetaGroupAttribute() { Data = MetaGroup.Empty; }
|
public MetaGroupAttribute() { }
|
||||||
public MetaGroupAttribute(string name) { Data = new MetaGroup(name); }
|
public MetaGroupAttribute(string name) { Name = name; }
|
||||||
public MetaGroupAttribute(params string[] path) : this(string.Join(SEPARATOR, path)) { }
|
public MetaGroupAttribute(params string[] path) { Name = string.Join(SEPARATOR, path); }
|
||||||
}
|
}
|
||||||
[DebuggerDisplay("{Name}")]
|
[DebuggerDisplay("{Name}")]
|
||||||
public class MetaGroup
|
public class MetaGroup
|
||||||
{
|
{
|
||||||
public const char SEPARATOR = MetaGroupAttribute.SEPARATOR;
|
public const char SEPARATOR = '/';
|
||||||
|
private const string SEPARATOR_STR = "/";
|
||||||
public const string UNGROUPED = "<UNGROUPED>";
|
public const string UNGROUPED = "<UNGROUPED>";
|
||||||
private const string PATTERN = @"Module(?=/)";
|
private const string PATTERN = @"Module(?=/)";
|
||||||
public static readonly MetaGroup Empty = new MetaGroup(UNGROUPED);
|
public static readonly MetaGroup Empty = new MetaGroup(UNGROUPED);
|
||||||
|
|
||||||
public readonly string Name;
|
public readonly string Name;
|
||||||
private string[] _path = null;
|
private string[] _splited = null;
|
||||||
public IReadOnlyCollection<string> Splited
|
public IReadOnlyCollection<string> Splited
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_path == null)
|
if (_splited == null)
|
||||||
{
|
{
|
||||||
_path = EcsMetaAttributeHalper.Split(SEPARATOR, Name);
|
_splited = EcsMetaAttributeHalper.Split(SEPARATOR, Name);
|
||||||
}
|
}
|
||||||
return _path;
|
return _splited;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public bool IsEmpty
|
public bool IsEmpty
|
||||||
{
|
{
|
||||||
get { return this == Empty; }
|
get { return this == Empty; }
|
||||||
}
|
}
|
||||||
public MetaGroup(string name)
|
private MetaGroup(string name)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(name))
|
if (string.IsNullOrEmpty(name))
|
||||||
{
|
{
|
||||||
Name = UNGROUPED;
|
Name = UNGROUPED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
name = name.Replace('\\', SEPARATOR);
|
name = Regex.Replace(name, @"(\s*[\/\\]+\s*)+", SEPARATOR_STR).Trim();
|
||||||
if (name[name.Length - 1] != SEPARATOR)
|
if (name[name.Length - 1] != SEPARATOR)
|
||||||
{
|
{
|
||||||
name += SEPARATOR;
|
name += SEPARATOR;
|
||||||
}
|
}
|
||||||
|
if (name[0] == SEPARATOR)
|
||||||
|
{
|
||||||
|
name = name.Substring(1);
|
||||||
|
}
|
||||||
Name = Regex.Replace(name, PATTERN, "");
|
Name = Regex.Replace(name, PATTERN, "");
|
||||||
Name = string.Intern(Name);
|
Name = string.Intern(Name);
|
||||||
}
|
}
|
||||||
|
public static MetaGroup FromName(string name)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
|
{
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
return new MetaGroup(name);
|
||||||
|
}
|
||||||
public static MetaGroup FromNameSpace(Type type)
|
public static MetaGroup FromNameSpace(Type type)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(type.Namespace))
|
if (string.IsNullOrWhiteSpace(type.Namespace))
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
using DCFApixels.DragonECS.Core;
|
using DCFApixels.DragonECS.Core;
|
||||||
using DCFApixels.DragonECS.Internal;
|
using DCFApixels.DragonECS.Internal;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
@ -17,62 +21,384 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(id))
|
if (string.IsNullOrEmpty(id))
|
||||||
{
|
{
|
||||||
Throw.ArgumentNull(nameof(id));
|
EcsDebug.PrintError("The identifier cannot be empty or null");
|
||||||
|
id = string.Empty;
|
||||||
}
|
}
|
||||||
if (MetaID.IsGenericID(id) == false)
|
if (MetaID.IsValidID(id) == false)
|
||||||
{
|
{
|
||||||
Throw.ArgumentException($"Identifier {id} contains invalid characters: ,<>");
|
EcsDebug.PrintError($"Identifier {id} contains invalid characters. Allowed charset: {MetaID.ALLOWED_CHARSET}");
|
||||||
|
id = string.Empty;
|
||||||
}
|
}
|
||||||
id = string.Intern(id);
|
|
||||||
ID = id;
|
ID = id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MetaID
|
public static unsafe class MetaID
|
||||||
{
|
{
|
||||||
[ThreadStatic]
|
public const string ALLOWED_CHARSET = "_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
private static Random _randon;
|
|
||||||
[ThreadStatic]
|
|
||||||
private static byte[] _buffer;
|
|
||||||
[ThreadStatic]
|
|
||||||
private static bool _isInit;
|
|
||||||
|
|
||||||
|
//public static bool IsFixedNameType(Type type)
|
||||||
|
//{
|
||||||
|
// if (type.IsPrimitive)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// if(type == typeof(string))
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
public static bool IsGenericID(string id)
|
public static bool IsGenericID(string id)
|
||||||
{
|
{
|
||||||
return Regex.IsMatch(id, @"^[^,<>\s]*$");
|
return id[id.Length - 1] == '>' || Regex.IsMatch(id, @"^[^,<>\s]*$");
|
||||||
|
}
|
||||||
|
public static bool IsValidID(string id)
|
||||||
|
{
|
||||||
|
return Regex.IsMatch(id, @"^[a-zA-Z0-9_]+$");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe string GenerateNewUniqueID()
|
|
||||||
|
[ThreadStatic]
|
||||||
|
private static uint _randonState;
|
||||||
|
public static string GenerateNewUniqueID()
|
||||||
{
|
{
|
||||||
if (_isInit == false)
|
const int BYTES = 16;
|
||||||
|
const int CHARS = BYTES * 2;
|
||||||
|
const string CHARSET = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
if (_randonState == 0)
|
||||||
{
|
{
|
||||||
IntPtr prt = Marshal.AllocHGlobal(1);
|
IntPtr prt = Marshal.AllocHGlobal(1);
|
||||||
long alloc = (long)prt;
|
long alloc = (long)prt;
|
||||||
Marshal.Release(prt);
|
Marshal.FreeHGlobal(prt);
|
||||||
_randon = new Random((int)alloc);
|
_randonState = (uint)alloc ^ (uint)DateTime.Now.Millisecond;
|
||||||
_buffer = new byte[8];
|
|
||||||
_isInit = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
byte* hibits = stackalloc byte[8];
|
byte* bytes = stackalloc byte[BYTES];
|
||||||
long* hibitsL = (long*)hibits;
|
Span<byte> x = new Span<byte>(bytes, BYTES);
|
||||||
hibitsL[0] = DateTime.Now.Ticks;
|
long* bytesLong = (long*)bytes;
|
||||||
hibitsL[1] = _randon.Next();
|
uint* bytesUInt = (uint*)bytes;
|
||||||
|
bytesLong[0] = DateTime.Now.Ticks;
|
||||||
|
_randonState = BitsUtility.NextXorShiftState(_randonState);
|
||||||
|
bytesUInt[2] = _randonState;
|
||||||
|
_randonState = BitsUtility.NextXorShiftState(_randonState);
|
||||||
|
bytesUInt[3] = _randonState;
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
|
char* str = stackalloc char[CHARS];
|
||||||
|
for (int i = 0, j = 0; i < BYTES; i++)
|
||||||
{
|
{
|
||||||
_buffer[i] = hibits[i];
|
byte b = bytes[i];
|
||||||
|
str[j++] = CHARSET[b & 0x0000_000F];
|
||||||
|
str[j++] = CHARSET[(b >> 4) & 0x0000_000F];
|
||||||
}
|
}
|
||||||
|
|
||||||
return BitConverter.ToString(_buffer).Replace("-", "");
|
return new string(str, 0, CHARS);
|
||||||
}
|
}
|
||||||
public static string IDToAttribute(string id)
|
public static string IDToAttribute(string id)
|
||||||
{
|
{
|
||||||
return $"[MetaID(\"id\")]";
|
return $"[MetaID(\"{id}\")]";
|
||||||
}
|
}
|
||||||
|
public static string ConvertIDToTypeName(string id)
|
||||||
|
{
|
||||||
|
id = id.Replace("_1", "__");
|
||||||
|
id = id.Replace("_2", "__");
|
||||||
|
id = id.Replace("_3", "__");
|
||||||
|
|
||||||
|
id = id.Replace("<", "_1");
|
||||||
|
id = id.Replace(">", "_2");
|
||||||
|
id = id.Replace(",", "_3");
|
||||||
|
return "_" + id;
|
||||||
|
}
|
||||||
|
public static string ParseIDFromTypeName(string name)
|
||||||
|
{
|
||||||
|
char* buffer = TempBuffer<char>.Get(name.Length);
|
||||||
|
int count = 0;
|
||||||
|
//skip name[0] char
|
||||||
|
for (int i = 1, iMax = name.Length; i < iMax; i++)
|
||||||
|
{
|
||||||
|
char current = name[i];
|
||||||
|
if (current == '_')
|
||||||
|
{
|
||||||
|
if (++i >= iMax) { break; }
|
||||||
|
current = name[i];
|
||||||
|
switch (current)
|
||||||
|
{
|
||||||
|
case '1': current = '<'; break;
|
||||||
|
case '2': current = '>'; break;
|
||||||
|
case '3': current = ','; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer[count++] = current;
|
||||||
|
}
|
||||||
|
return new string(buffer, 0, count);
|
||||||
|
}
|
||||||
|
|
||||||
public static string GenerateNewUniqueIDWithAttribute()
|
public static string GenerateNewUniqueIDWithAttribute()
|
||||||
{
|
{
|
||||||
return IDToAttribute(GenerateNewUniqueID());
|
return IDToAttribute(GenerateNewUniqueID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static bool TryFindMetaIDCollisions(IEnumerable<TypeMeta> metas, out CollisionList collisions)
|
||||||
|
{
|
||||||
|
collisions = new CollisionList(metas);
|
||||||
|
return collisions.IsHasAnyCollision;
|
||||||
|
}
|
||||||
|
public static CollisionList FindMetaIDCollisions(IEnumerable<TypeMeta> metas)
|
||||||
|
{
|
||||||
|
return new CollisionList(metas);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region CollisionList
|
||||||
|
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
||||||
|
[DebuggerDisplay("HasAnyCollision: {IsHasAnyCollision} ListsCount: {Count}")]
|
||||||
|
public class CollisionList : IEnumerable<CollisionList.Collision>
|
||||||
|
{
|
||||||
|
private LinkedList[] _linkedLists;
|
||||||
|
private Entry[] _entries;
|
||||||
|
private int _collisionsCount;
|
||||||
|
private int _listsCount;
|
||||||
|
private HashSet<string> _collidingIDs;
|
||||||
|
|
||||||
|
public int CollisionsCount
|
||||||
|
{
|
||||||
|
get { return _collisionsCount; }
|
||||||
|
}
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get { return _listsCount; }
|
||||||
|
}
|
||||||
|
public bool IsHasAnyCollision
|
||||||
|
{
|
||||||
|
get { return _listsCount > 0; }
|
||||||
|
}
|
||||||
|
public Collision this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var list = _linkedLists[index];
|
||||||
|
return new Collision(this, list.headNode, list.count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsCollidingID(string id)
|
||||||
|
{
|
||||||
|
if(_collidingIDs== null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return _collidingIDs.Contains(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CollisionList(IEnumerable<TypeMeta> metas)
|
||||||
|
{
|
||||||
|
var metasCount = metas.Count();
|
||||||
|
Dictionary<string, int> listIndexes = new Dictionary<string, int>(metasCount);
|
||||||
|
_linkedLists = new LinkedList[metasCount];
|
||||||
|
_entries = new Entry[metasCount];
|
||||||
|
|
||||||
|
bool hasCollision = false;
|
||||||
|
|
||||||
|
_listsCount = 0;
|
||||||
|
foreach (var meta in metas)
|
||||||
|
{
|
||||||
|
if (meta.IsHasMetaID() == false) { continue; }
|
||||||
|
if (listIndexes.TryGetValue(meta.MetaID, out int headIndex))
|
||||||
|
{
|
||||||
|
hasCollision = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
headIndex = _listsCount++;
|
||||||
|
listIndexes.Add(meta.MetaID, headIndex);
|
||||||
|
}
|
||||||
|
int nodeIndex = _collisionsCount++;
|
||||||
|
|
||||||
|
ref var list = ref _linkedLists[headIndex];
|
||||||
|
ref Entry entry = ref _entries[nodeIndex];
|
||||||
|
if (list.count == 0)
|
||||||
|
{
|
||||||
|
entry.next = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry.next = list.headNode;
|
||||||
|
}
|
||||||
|
entry.meta = meta;
|
||||||
|
list.headNode = nodeIndex;
|
||||||
|
listIndexes[meta.MetaID] = headIndex;
|
||||||
|
list.count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasCollision)
|
||||||
|
{
|
||||||
|
_collidingIDs = new HashSet<string>();
|
||||||
|
for (int i = 0; i < _listsCount; i++)
|
||||||
|
{
|
||||||
|
ref var list = ref _linkedLists[i];
|
||||||
|
if (list.count <= 1)
|
||||||
|
{
|
||||||
|
_linkedLists[i--] = _linkedLists[--_listsCount];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < _listsCount; i++)
|
||||||
|
{
|
||||||
|
_collidingIDs.Add(this[i].MetaID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_listsCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[DebuggerDisplay("Count: {count}")]
|
||||||
|
private struct LinkedList
|
||||||
|
{
|
||||||
|
public int count;
|
||||||
|
public int headNode;
|
||||||
|
}
|
||||||
|
[DebuggerDisplay("ID: {meta.MetaID} next: {next}")]
|
||||||
|
public struct Entry
|
||||||
|
{
|
||||||
|
public TypeMeta meta;
|
||||||
|
public int next;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Enumerator
|
||||||
|
public Enumerator GetEnumerator() { return new Enumerator(this, _listsCount); }
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
|
||||||
|
IEnumerator<Collision> IEnumerable<Collision>.GetEnumerator() { return GetEnumerator(); }
|
||||||
|
public struct Enumerator : IEnumerator<Collision>
|
||||||
|
{
|
||||||
|
private readonly CollisionList _collisions;
|
||||||
|
private readonly int _count;
|
||||||
|
private int _index;
|
||||||
|
public Collision Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var list = _collisions._linkedLists[_index];
|
||||||
|
return new Collision(_collisions, list.headNode, list.count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object IEnumerator.Current { get { return Current; } }
|
||||||
|
public Enumerator(CollisionList collisions, int count)
|
||||||
|
{
|
||||||
|
_collisions = collisions;
|
||||||
|
_count = count;
|
||||||
|
_index = -1;
|
||||||
|
}
|
||||||
|
public bool MoveNext() { return ++_index < _count; }
|
||||||
|
public void Dispose() { }
|
||||||
|
public void Reset() { _index = -1; }
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
[DebuggerDisplay("Count: {Count}")]
|
||||||
|
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
||||||
|
public readonly struct Collision : IEnumerable<TypeMeta>
|
||||||
|
{
|
||||||
|
private readonly CollisionList _collisions;
|
||||||
|
private readonly string _metaID;
|
||||||
|
private readonly int _head;
|
||||||
|
private readonly int _count;
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get { return _count; }
|
||||||
|
}
|
||||||
|
public string MetaID
|
||||||
|
{
|
||||||
|
get { return _metaID; }
|
||||||
|
}
|
||||||
|
internal Collision(CollisionList collisions, int head, int count)
|
||||||
|
{
|
||||||
|
_collisions = collisions;
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
_head = 0;
|
||||||
|
_metaID = string.Empty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_head = head;
|
||||||
|
_metaID = collisions._entries[_head].meta.MetaID;
|
||||||
|
}
|
||||||
|
_head = head;
|
||||||
|
_count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Enumerator
|
||||||
|
public Enumerator GetEnumerator() { return new Enumerator(_collisions._entries, _head); }
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
|
||||||
|
IEnumerator<TypeMeta> IEnumerable<TypeMeta>.GetEnumerator() { return GetEnumerator(); }
|
||||||
|
public struct Enumerator : IEnumerator<TypeMeta>
|
||||||
|
{
|
||||||
|
private readonly Entry[] _linkedEntries;
|
||||||
|
private readonly int _head;
|
||||||
|
private int _nextIndex;
|
||||||
|
private int _index;
|
||||||
|
public TypeMeta Current { get { return _linkedEntries[_index].meta; } }
|
||||||
|
object IEnumerator.Current { get { return Current; } }
|
||||||
|
public Enumerator(Entry[] linkedEntries, int head)
|
||||||
|
{
|
||||||
|
_linkedEntries = linkedEntries;
|
||||||
|
_head = head;
|
||||||
|
_nextIndex = _head;
|
||||||
|
_index = -1;
|
||||||
|
}
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
if (_nextIndex < 0) { return false; }
|
||||||
|
_index = _nextIndex;
|
||||||
|
_nextIndex = _linkedEntries[_index].next;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public void Dispose() { }
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
_nextIndex = _head;
|
||||||
|
_index = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region DebuggerProxy
|
||||||
|
private class DebuggerProxy
|
||||||
|
{
|
||||||
|
public Type[] Types;
|
||||||
|
public DebuggerProxy(Collision collision)
|
||||||
|
{
|
||||||
|
Types = collision.Select(o => o.Type).ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
#region DebuggerProxy
|
||||||
|
private class DebuggerProxy
|
||||||
|
{
|
||||||
|
public string[][] Lists;
|
||||||
|
public DebuggerProxy(CollisionList collisions)
|
||||||
|
{
|
||||||
|
Lists = new string[collisions.Count][];
|
||||||
|
int i = 0;
|
||||||
|
foreach (var list in collisions)
|
||||||
|
{
|
||||||
|
int j = 0;
|
||||||
|
Lists[i] = new string[list.Count];
|
||||||
|
foreach (var typeMeta in list)
|
||||||
|
{
|
||||||
|
Lists[i][j] = typeMeta.MetaID;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,8 +3,10 @@
|
|||||||
#endif
|
#endif
|
||||||
using DCFApixels.DragonECS.Core;
|
using DCFApixels.DragonECS.Core;
|
||||||
using DCFApixels.DragonECS.Internal;
|
using DCFApixels.DragonECS.Internal;
|
||||||
|
using DCFApixels.DragonECS.PoolsCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
#if DEBUG || !REFLECTION_DISABLED
|
#if DEBUG || !REFLECTION_DISABLED
|
||||||
@ -36,14 +38,14 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "Intended for extending meta information of types, for customization of type display in the editor. You can get it by using the object.GetMeta() or Type.ToMeta() extension method. Meta information is collected from meta attributes.")]
|
[MetaDescription(EcsConsts.AUTHOR, "Intended for extending meta information of types, for customization of type display in the editor. You can get it by using the object.GetMeta() or Type.ToMeta() extension method. Meta information is collected from meta attributes.")]
|
||||||
[MetaID("248D587C9201EAEA881F27871B4D18A6")]
|
[MetaID("DragonECS_248D587C9201EAEA881F27871B4D18A6")]
|
||||||
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
||||||
public sealed class TypeMeta : ITypeMeta
|
public sealed class TypeMeta : ITypeMeta
|
||||||
{
|
{
|
||||||
private const string NULL_NAME = "NULL";
|
private const string NULL_NAME = "NULL";
|
||||||
public static readonly TypeMeta NullTypeMeta;
|
public static readonly TypeMeta NullTypeMeta;
|
||||||
|
|
||||||
private static object _lock = new object();
|
private static readonly object _lock = new object();
|
||||||
private static readonly Dictionary<Type, TypeMeta> _metaCache = new Dictionary<Type, TypeMeta>();
|
private static readonly Dictionary<Type, TypeMeta> _metaCache = new Dictionary<Type, TypeMeta>();
|
||||||
private static int _increment = 1;
|
private static int _increment = 1;
|
||||||
|
|
||||||
@ -65,6 +67,10 @@ namespace DCFApixels.DragonECS
|
|||||||
private string _metaID;
|
private string _metaID;
|
||||||
private EcsTypeCode _typeCode;
|
private EcsTypeCode _typeCode;
|
||||||
|
|
||||||
|
private bool _isProcess;
|
||||||
|
private bool _isComponent;
|
||||||
|
private bool _isPool;
|
||||||
|
|
||||||
private InitFlag _initFlags = InitFlag.None;
|
private InitFlag _initFlags = InitFlag.None;
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
@ -78,9 +84,9 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
_name = NULL_NAME,
|
_name = NULL_NAME,
|
||||||
_typeName = NULL_NAME,
|
_typeName = NULL_NAME,
|
||||||
_color = new MetaColor(MetaColor.Black),
|
_color = MetaColor.Black,
|
||||||
_description = new MetaDescription("", NULL_NAME),
|
_description = new MetaDescription("", NULL_NAME),
|
||||||
_group = new MetaGroup(""),
|
_group = MetaGroup.Empty,
|
||||||
_tags = Array.Empty<string>(),
|
_tags = Array.Empty<string>(),
|
||||||
_metaID = string.Empty,
|
_metaID = string.Empty,
|
||||||
_typeCode = EcsTypeCodeManager.Get(typeof(void)),
|
_typeCode = EcsTypeCodeManager.Get(typeof(void)),
|
||||||
@ -270,6 +276,7 @@ namespace DCFApixels.DragonECS
|
|||||||
return _metaID;
|
return _metaID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public bool IsHasMetaID() { return string.IsNullOrEmpty(MetaID) == false; }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region TypeCode
|
#region TypeCode
|
||||||
@ -287,6 +294,45 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region ReflectionInfo
|
||||||
|
public bool IsComponent
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_initFlags.HasFlag(InitFlag.ReflectionInfo) == false)
|
||||||
|
{
|
||||||
|
MetaGenerator.GetReflectionInfo(this);
|
||||||
|
_initFlags |= InitFlag.ReflectionInfo;
|
||||||
|
}
|
||||||
|
return _isComponent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool IsProcess
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_initFlags.HasFlag(InitFlag.ReflectionInfo) == false)
|
||||||
|
{
|
||||||
|
MetaGenerator.GetReflectionInfo(this);
|
||||||
|
_initFlags |= InitFlag.ReflectionInfo;
|
||||||
|
}
|
||||||
|
return _isProcess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool IsPool
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_initFlags.HasFlag(InitFlag.ReflectionInfo) == false)
|
||||||
|
{
|
||||||
|
MetaGenerator.GetReflectionInfo(this);
|
||||||
|
_initFlags |= InitFlag.ReflectionInfo;
|
||||||
|
}
|
||||||
|
return _isPool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region InitializeAll
|
#region InitializeAll
|
||||||
public TypeMeta InitializeAll()
|
public TypeMeta InitializeAll()
|
||||||
{
|
{
|
||||||
@ -316,9 +362,10 @@ namespace DCFApixels.DragonECS
|
|||||||
Tags = 1 << 4,
|
Tags = 1 << 4,
|
||||||
MetaID = 1 << 5,
|
MetaID = 1 << 5,
|
||||||
TypeCode = 1 << 6,
|
TypeCode = 1 << 6,
|
||||||
//MemberType = 1 << 7,
|
ReflectionInfo = 1 << 7,
|
||||||
|
//MemberType = 1 << 8,
|
||||||
|
|
||||||
All = Name | Group | Color | Description | Tags | TypeCode | MetaID //| MemberType
|
All = Name | Group | Color | Description | Tags | TypeCode | MetaID | ReflectionInfo //| MemberType
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -336,7 +383,17 @@ namespace DCFApixels.DragonECS
|
|||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
public static bool IsHasMeta(Type type)
|
public static bool TryGetCustomMeta(Type type, out TypeMeta meta)
|
||||||
|
{
|
||||||
|
if (IsHasCustomMeta(type))
|
||||||
|
{
|
||||||
|
meta = type.ToMeta();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
meta = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static bool IsHasCustomMeta(Type type)
|
||||||
{
|
{
|
||||||
#if DEBUG || !REFLECTION_DISABLED
|
#if DEBUG || !REFLECTION_DISABLED
|
||||||
return CheckEcsMemener(type) || Attribute.GetCustomAttributes(type, typeof(EcsMetaAttribute), false).Length > 0;
|
return CheckEcsMemener(type) || Attribute.GetCustomAttributes(type, typeof(EcsMetaAttribute), false).Length > 0;
|
||||||
@ -348,7 +405,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public static bool IsHasMetaID(Type type)
|
public static bool IsHasMetaID(Type type)
|
||||||
{
|
{
|
||||||
#if DEBUG || !REFLECTION_DISABLED
|
#if DEBUG || !REFLECTION_DISABLED
|
||||||
return type.HasAttribute<MetaIDAttribute>();
|
return TryGetCustomMeta(type, out TypeMeta meta) && meta.IsHasMetaID();
|
||||||
#else
|
#else
|
||||||
EcsDebug.PrintWarning($"Reflection is not available, the {nameof(TypeMeta)}.{nameof(IsHasMetaID)} method does not work.");
|
EcsDebug.PrintWarning($"Reflection is not available, the {nameof(TypeMeta)}.{nameof(IsHasMetaID)} method does not work.");
|
||||||
return false;
|
return false;
|
||||||
@ -404,6 +461,15 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Obsolete
|
||||||
|
[Obsolete("Use TryGetCustomMeta(type)")]
|
||||||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
|
public static bool IsHasMeta(Type type)
|
||||||
|
{
|
||||||
|
return IsHasCustomMeta(type);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region MetaGenerator
|
#region MetaGenerator
|
||||||
private static class MetaGenerator
|
private static class MetaGenerator
|
||||||
{
|
{
|
||||||
@ -442,7 +508,6 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GetColor
|
#region GetColor
|
||||||
|
|
||||||
private static MetaColor AutoColor(TypeMeta meta)
|
private static MetaColor AutoColor(TypeMeta meta)
|
||||||
{
|
{
|
||||||
int hash;
|
int hash;
|
||||||
@ -463,7 +528,7 @@ namespace DCFApixels.DragonECS
|
|||||||
return (isCustom ? atr.color : AutoColor(meta), isCustom);
|
return (isCustom ? atr.color : AutoColor(meta), isCustom);
|
||||||
#else
|
#else
|
||||||
EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetColor)} method does not work.");
|
EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetColor)} method does not work.");
|
||||||
return (AutoColor(type), false);
|
return (MetaColor.White, false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -472,7 +537,14 @@ namespace DCFApixels.DragonECS
|
|||||||
public static MetaGroup GetGroup(Type type)
|
public static MetaGroup GetGroup(Type type)
|
||||||
{
|
{
|
||||||
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
||||||
return type.TryGetAttribute(out MetaGroupAttribute atr) ? atr.Data : MetaGroup.FromNameSpace(type);
|
if (type.TryGetAttribute(out MetaGroupAttribute atr))
|
||||||
|
{
|
||||||
|
return MetaGroup.FromName(atr.Name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return MetaGroup.FromNameSpace(type);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetGroup)} method does not work.");
|
EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetGroup)} method does not work.");
|
||||||
return MetaGroup.Empty;
|
return MetaGroup.Empty;
|
||||||
@ -507,9 +579,6 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GetMetaID
|
#region GetMetaID
|
||||||
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
|
||||||
private static Dictionary<string, Type> _idTypePairs = new Dictionary<string, Type>();
|
|
||||||
#endif
|
|
||||||
public static string GetMetaID(Type type)
|
public static string GetMetaID(Type type)
|
||||||
{
|
{
|
||||||
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
||||||
@ -524,22 +593,17 @@ namespace DCFApixels.DragonECS
|
|||||||
string id = atr.ID;
|
string id = atr.ID;
|
||||||
if (type.IsGenericType && type.IsGenericTypeDefinition == false)
|
if (type.IsGenericType && type.IsGenericTypeDefinition == false)
|
||||||
{
|
{
|
||||||
var metaIds = type.GetGenericArguments().Select(o => GetMetaID(o));
|
var metaIDs = type.GetGenericArguments().Select(o => GetMetaID(o));
|
||||||
if (metaIds.Any(o => string.IsNullOrEmpty(o)))
|
if (metaIDs.Any(o => string.IsNullOrEmpty(o)))
|
||||||
{
|
{
|
||||||
id = string.Empty;
|
id = string.Empty;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
id = $"{id}<{string.Join(", ", metaIds)}>";
|
id = $"{id}<{string.Join(", ", metaIDs)}>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(id) == false &&
|
id = string.Intern(id);
|
||||||
_idTypePairs.TryGetValue(id, out Type otherType) && type != otherType)
|
|
||||||
{
|
|
||||||
Throw.Exception($"Types {type.ToMeta().TypeName} and {otherType.ToMeta().TypeName} have duplicate {atr.ID} MetaID.");
|
|
||||||
}
|
|
||||||
_idTypePairs[id] = type;
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -548,6 +612,15 @@ namespace DCFApixels.DragonECS
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region GetReflectionInfo
|
||||||
|
public static void GetReflectionInfo(TypeMeta meta)
|
||||||
|
{
|
||||||
|
meta._isComponent = typeof(IEcsComponentMember).IsAssignableFrom(meta.Type);
|
||||||
|
meta._isProcess = typeof(IEcsProcess).IsAssignableFrom(meta.Type);
|
||||||
|
meta._isPool = typeof(IEcsPoolImplementation).IsAssignableFrom(meta.Type);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
//Инициализация аспектов проходит в синхронизированном состоянии, поэтому использование _staticMaskCache потоко безопасно.
|
//Инициализация аспектов проходит в синхронизированном состоянии, поэтому использование _staticMaskCache потоко безопасно.
|
||||||
private static Dictionary<Type, EcsStaticMask> _staticMaskCache = new Dictionary<Type, EcsStaticMask>();
|
private readonly static Dictionary<Type, EcsStaticMask> _staticMaskCache = new Dictionary<Type, EcsStaticMask>();
|
||||||
|
|
||||||
internal EcsWorld _source;
|
internal EcsWorld _source;
|
||||||
internal EcsMask _mask;
|
internal EcsMask _mask;
|
||||||
@ -272,13 +272,13 @@ namespace DCFApixels.DragonECS
|
|||||||
public TPool IncludePool<TPool>() where TPool : IEcsPoolImplementation, new()
|
public TPool IncludePool<TPool>() where TPool : IEcsPoolImplementation, new()
|
||||||
{
|
{
|
||||||
var pool = CachePool<TPool>();
|
var pool = CachePool<TPool>();
|
||||||
IncludeImplicit(pool.ComponentType);
|
SetMaskInclude(pool.ComponentType);
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
public TPool ExcludePool<TPool>() where TPool : IEcsPoolImplementation, new()
|
public TPool ExcludePool<TPool>() where TPool : IEcsPoolImplementation, new()
|
||||||
{
|
{
|
||||||
var pool = CachePool<TPool>();
|
var pool = CachePool<TPool>();
|
||||||
ExcludeImplicit(pool.ComponentType);
|
SetMaskExclude(pool.ComponentType);
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
public TPool OptionalPool<TPool>() where TPool : IEcsPoolImplementation, new()
|
public TPool OptionalPool<TPool>() where TPool : IEcsPoolImplementation, new()
|
||||||
@ -291,14 +291,14 @@ namespace DCFApixels.DragonECS
|
|||||||
var pool = _world.GetPoolInstance<TPool>();
|
var pool = _world.GetPoolInstance<TPool>();
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
private void IncludeImplicit(Type type)
|
public void SetMaskInclude(Type type)
|
||||||
{
|
{
|
||||||
if (_maskBuilder.IsNull == false)
|
if (_maskBuilder.IsNull == false)
|
||||||
{
|
{
|
||||||
_maskBuilder.Inc(type);
|
_maskBuilder.Inc(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void ExcludeImplicit(Type type)
|
public void SetMaskExclude(Type type)
|
||||||
{
|
{
|
||||||
if (_maskBuilder.IsNull == false)
|
if (_maskBuilder.IsNull == false)
|
||||||
{
|
{
|
||||||
@ -334,8 +334,8 @@ namespace DCFApixels.DragonECS
|
|||||||
IncludePool<TPool>();
|
IncludePool<TPool>();
|
||||||
ExcludePool<TPool>();
|
ExcludePool<TPool>();
|
||||||
OptionalPool<TPool>();
|
OptionalPool<TPool>();
|
||||||
IncludeImplicit(null);
|
SetMaskInclude(null);
|
||||||
ExcludeImplicit(null);
|
SetMaskExclude(null);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -488,7 +488,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[Il2CppSetOption(Option.NullChecks, false)]
|
[Il2CppSetOption(Option.NullChecks, false)]
|
||||||
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
#endif
|
#endif
|
||||||
public class EcsMaskIterator
|
public class EcsMaskIterator : IDisposable
|
||||||
{
|
{
|
||||||
// TODO есть идея перенести эти ChunckBuffer-ы в стек,
|
// TODO есть идея перенести эти ChunckBuffer-ы в стек,
|
||||||
// для этого нужно проработать дизайн так чтобы память в стеке выделялась за пределами итератора и GetEnumerator,
|
// для этого нужно проработать дизайн так чтобы память в стеке выделялась за пределами итератора и GetEnumerator,
|
||||||
@ -555,6 +555,15 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe ~EcsMaskIterator()
|
unsafe ~EcsMaskIterator()
|
||||||
|
{
|
||||||
|
Cleanup(false);
|
||||||
|
}
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Cleanup(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
private void Cleanup(bool disposing)
|
||||||
{
|
{
|
||||||
_sortIncBuffer.ReadonlyDispose();
|
_sortIncBuffer.ReadonlyDispose();
|
||||||
//_sortExcBuffer.ReadonlyDispose();// использует общую памяять с _sortIncBuffer;
|
//_sortExcBuffer.ReadonlyDispose();// использует общую памяять с _sortIncBuffer;
|
||||||
@ -563,7 +572,7 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region SortConstraints
|
#region SortConstraints/TryFindEntityStorage
|
||||||
private unsafe int SortConstraints_Internal()
|
private unsafe int SortConstraints_Internal()
|
||||||
{
|
{
|
||||||
UnsafeArray<int> sortIncBuffer = _sortIncBuffer;
|
UnsafeArray<int> sortIncBuffer = _sortIncBuffer;
|
||||||
@ -611,7 +620,7 @@ namespace DCFApixels.DragonECS
|
|||||||
// Поэтому исключающее ограничение игнорируется для maxEntites.
|
// Поэтому исключающее ограничение игнорируется для maxEntites.
|
||||||
return maxEntites;
|
return maxEntites;
|
||||||
}
|
}
|
||||||
private unsafe bool TryGetEntityStorage(out IEntityStorage storage)
|
private unsafe bool TryFindEntityStorage(out IEntityStorage storage)
|
||||||
{
|
{
|
||||||
if (_isHasAnyEntityStorage)
|
if (_isHasAnyEntityStorage)
|
||||||
{
|
{
|
||||||
@ -737,7 +746,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
return new Enumerator(_span.Slice(0, 0), _iterator);
|
return new Enumerator(_span.Slice(0, 0), _iterator);
|
||||||
}
|
}
|
||||||
if (_iterator.TryGetEntityStorage(out IEntityStorage storage))
|
if (_iterator.TryFindEntityStorage(out IEntityStorage storage))
|
||||||
{
|
{
|
||||||
return new Enumerator(storage.ToSpan(), _iterator);
|
return new Enumerator(storage.ToSpan(), _iterator);
|
||||||
}
|
}
|
||||||
@ -811,6 +820,7 @@ namespace DCFApixels.DragonECS
|
|||||||
#region Iterate/Enumerable OnlyInc
|
#region Iterate/Enumerable OnlyInc
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public OnlyIncEnumerable IterateOnlyInc(EcsSpan span) { return new OnlyIncEnumerable(this, span); }
|
public OnlyIncEnumerable IterateOnlyInc(EcsSpan span) { return new OnlyIncEnumerable(this, span); }
|
||||||
|
|
||||||
#if ENABLE_IL2CPP
|
#if ENABLE_IL2CPP
|
||||||
[Il2CppSetOption(Option.NullChecks, false)]
|
[Il2CppSetOption(Option.NullChecks, false)]
|
||||||
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
@ -952,29 +962,30 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
internal const int STACK_BUFFER_THRESHOLD = 100;
|
internal const int STACK_BUFFER_THRESHOLD = 100;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static void ConvertToChuncks(EcsMaskChunck* ptr, UnsafeArray<int> input, UnsafeArray<EcsMaskChunck> output)
|
internal static void ConvertToChuncks(EcsMaskChunck* bufferPtr, UnsafeArray<int> input, UnsafeArray<EcsMaskChunck> output)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < input.Length; i++)
|
for (int i = 0; i < input.Length; i++)
|
||||||
{
|
{
|
||||||
ptr[i] = EcsMaskChunck.FromID(input.ptr[i]);
|
bufferPtr[i] = EcsMaskChunck.FromID(input.ptr[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int inputI = 0, outputI = 0; outputI < output.Length; inputI++, ptr++)
|
for (int inputI = 0, outputI = 0; outputI < output.Length; inputI++, bufferPtr++)
|
||||||
{
|
{
|
||||||
int maskX = ptr->mask;
|
int stackingMask = bufferPtr->mask;
|
||||||
if (maskX == 0) { continue; }
|
if (stackingMask == 0) { continue; }
|
||||||
int chunkIndexX = ptr->chunkIndex;
|
int stackingChunkIndex = bufferPtr->chunkIndex;
|
||||||
|
|
||||||
EcsMaskChunck* subptr = ptr;
|
EcsMaskChunck* bufferSpanPtr = bufferPtr + 1;
|
||||||
for (int j = 1; j < input.Length - inputI; j++, subptr++)
|
for (int j = 1; j < input.Length - inputI; j++, bufferSpanPtr++)
|
||||||
{
|
{
|
||||||
if (subptr->chunkIndex == chunkIndexX)
|
if (bufferSpanPtr->chunkIndex == stackingChunkIndex)
|
||||||
{
|
{
|
||||||
maskX |= subptr->mask;
|
stackingMask |= bufferSpanPtr->mask;
|
||||||
*subptr = default;
|
*bufferSpanPtr = default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output.ptr[outputI] = new EcsMaskChunck(chunkIndexX, maskX);
|
|
||||||
|
output.ptr[outputI] = new EcsMaskChunck(stackingChunkIndex, stackingMask);
|
||||||
outputI++;
|
outputI++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(PACK_GROUP, OTHER_GROUP)]
|
[MetaGroup(PACK_GROUP, OTHER_GROUP)]
|
||||||
[MetaDescription(AUTHOR, "...")]
|
[MetaDescription(AUTHOR, "...")]
|
||||||
[MetaID("FC38597C9201C15D1A14D133237BD67F")]
|
[MetaID("DragonECS_FC38597C9201C15D1A14D133237BD67F")]
|
||||||
public interface IEcsDefaultAddParams
|
public interface IEcsDefaultAddParams
|
||||||
{
|
{
|
||||||
AddParams AddParams { get; }
|
AddParams AddParams { get; }
|
||||||
@ -726,7 +726,7 @@ namespace DCFApixels.DragonECS
|
|||||||
#region SerializableTemplate
|
#region SerializableTemplate
|
||||||
public EcsPipelineTemplate GenerateSerializableTemplate()
|
public EcsPipelineTemplate GenerateSerializableTemplate()
|
||||||
{
|
{
|
||||||
var it = new LinkedListIterator<SystemNode>(_systemNodes, _systemNodesCount, _startIndex);
|
var it = new LinkedListCountIterator<SystemNode>(_systemNodes, _systemNodesCount, _startIndex);
|
||||||
EcsPipelineTemplate result = new EcsPipelineTemplate();
|
EcsPipelineTemplate result = new EcsPipelineTemplate();
|
||||||
result.layers = new string[Layers.Count];
|
result.layers = new string[Layers.Count];
|
||||||
result.records = new EcsPipelineTemplate.Record[it.Count];
|
result.records = new EcsPipelineTemplate.Record[it.Count];
|
||||||
|
@ -14,6 +14,7 @@ using static DCFApixels.DragonECS.EcsConsts;
|
|||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
public interface IEcsMember { }
|
public interface IEcsMember { }
|
||||||
|
public interface IEcsComponentMember : IEcsMember { }
|
||||||
public interface INamedMember
|
public interface INamedMember
|
||||||
{
|
{
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
@ -22,7 +23,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(PACK_GROUP, OTHER_GROUP)]
|
[MetaGroup(PACK_GROUP, OTHER_GROUP)]
|
||||||
[MetaDescription(AUTHOR, "...")]
|
[MetaDescription(AUTHOR, "...")]
|
||||||
[MetaID("F064557C92010419AB677453893D00AE")]
|
[MetaID("DragonECS_F064557C92010419AB677453893D00AE")]
|
||||||
public interface IEcsPipelineMember : IEcsProcess
|
public interface IEcsPipelineMember : IEcsProcess
|
||||||
{
|
{
|
||||||
EcsPipeline Pipeline { get; set; }
|
EcsPipeline Pipeline { get; set; }
|
||||||
@ -31,7 +32,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(PACK_GROUP, OTHER_GROUP)]
|
[MetaGroup(PACK_GROUP, OTHER_GROUP)]
|
||||||
[MetaDescription(AUTHOR, "Container and engine for systems. Responsible for configuring the execution order of systems, providing a mechanism for messaging between systems, and a dependency injection mechanism.")]
|
[MetaDescription(AUTHOR, "Container and engine for systems. Responsible for configuring the execution order of systems, providing a mechanism for messaging between systems, and a dependency injection mechanism.")]
|
||||||
[MetaID("9F5A557C9201C5C3D9BCAC2FF1CC07D4")]
|
[MetaID("DragonECS_9F5A557C9201C5C3D9BCAC2FF1CC07D4")]
|
||||||
public sealed partial class EcsPipeline
|
public sealed partial class EcsPipeline
|
||||||
{
|
{
|
||||||
private readonly IConfigContainer _configs;
|
private readonly IConfigContainer _configs;
|
||||||
@ -113,20 +114,18 @@ namespace DCFApixels.DragonECS
|
|||||||
private static IEcsProcess[] _buffer;
|
private static IEcsProcess[] _buffer;
|
||||||
private T[] CreateProcess<T>() where T : IEcsProcess
|
private T[] CreateProcess<T>() where T : IEcsProcess
|
||||||
{
|
{
|
||||||
if (_buffer == null || _buffer.Length < _allSystems.Length)
|
ArrayUtility.UpsizeWithoutCopy(ref _buffer, _allSystems.Length);
|
||||||
{
|
int bufferLength = 0;
|
||||||
Array.Resize(ref _buffer, _allSystems.Length);
|
|
||||||
}
|
|
||||||
int l = 0;
|
|
||||||
for (int i = 0, iMax = _allSystems.Length; i < iMax; i++)
|
for (int i = 0, iMax = _allSystems.Length; i < iMax; i++)
|
||||||
{
|
{
|
||||||
if (_allSystems[i] is T)
|
if (_allSystems[i] is T)
|
||||||
{
|
{
|
||||||
_buffer[l++] = _allSystems[i];
|
_buffer[bufferLength++] = _allSystems[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
T[] result = new T[l];
|
T[] result = new T[bufferLength];
|
||||||
Array.Copy(_buffer, result, l);
|
Array.Copy(_buffer, result, bufferLength);
|
||||||
|
Array.Clear(_buffer, 0, bufferLength);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -288,7 +287,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.Black)]
|
[MetaColor(MetaColor.Black)]
|
||||||
[MetaGroup(PACK_GROUP, OTHER_GROUP)]
|
[MetaGroup(PACK_GROUP, OTHER_GROUP)]
|
||||||
[MetaDescription(AUTHOR, "An auxiliary type of system for dividing a pipeline into layers. This system is automatically added to the EcsPipeline.")]
|
[MetaDescription(AUTHOR, "An auxiliary type of system for dividing a pipeline into layers. This system is automatically added to the EcsPipeline.")]
|
||||||
[MetaID("42596C7C9201D0B85D1335E6E4704B57")]
|
[MetaID("DragonECS_42596C7C9201D0B85D1335E6E4704B57")]
|
||||||
public class SystemsLayerMarkerSystem : IEcsProcess
|
public class SystemsLayerMarkerSystem : IEcsProcess
|
||||||
{
|
{
|
||||||
public readonly string name;
|
public readonly string name;
|
||||||
|
@ -14,7 +14,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.OTHER_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.OTHER_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "...")]
|
[MetaDescription(EcsConsts.AUTHOR, "...")]
|
||||||
[MetaTags(MetaTags.HIDDEN)]
|
[MetaTags(MetaTags.HIDDEN)]
|
||||||
[MetaID("EF8A557C9201E6F04D4A76DC670BDE19")]
|
[MetaID("DragonECS_EF8A557C9201E6F04D4A76DC670BDE19")]
|
||||||
public interface IEcsProcess : IEcsMember { }
|
public interface IEcsProcess : IEcsMember { }
|
||||||
|
|
||||||
namespace RunnersCore
|
namespace RunnersCore
|
||||||
@ -69,7 +69,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.OTHER_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.OTHER_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "...")]
|
[MetaDescription(EcsConsts.AUTHOR, "...")]
|
||||||
[MetaTags(MetaTags.HIDDEN)]
|
[MetaTags(MetaTags.HIDDEN)]
|
||||||
[MetaID("E49B557C92010E46DF1602972BC988BC")]
|
[MetaID("DragonECS_E49B557C92010E46DF1602972BC988BC")]
|
||||||
public interface IEcsRunner : IEcsProcess
|
public interface IEcsRunner : IEcsProcess
|
||||||
{
|
{
|
||||||
EcsPipeline Pipeline { get; }
|
EcsPipeline Pipeline { get; }
|
||||||
@ -84,7 +84,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.OTHER_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.OTHER_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "...")]
|
[MetaDescription(EcsConsts.AUTHOR, "...")]
|
||||||
[MetaTags(MetaTags.HIDDEN)]
|
[MetaTags(MetaTags.HIDDEN)]
|
||||||
[MetaID("7DB3557C9201F85E0E1C17D7B19D9CEE")]
|
[MetaID("DragonECS_7DB3557C9201F85E0E1C17D7B19D9CEE")]
|
||||||
public abstract class EcsRunner<TProcess> : EcsRunner, IEcsRunner, IEcsProcess
|
public abstract class EcsRunner<TProcess> : EcsRunner, IEcsRunner, IEcsProcess
|
||||||
where TProcess : IEcsProcess
|
where TProcess : IEcsProcess
|
||||||
{
|
{
|
||||||
@ -211,9 +211,10 @@ namespace DCFApixels.DragonECS
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
#if DRAGONECS_DISABLE_CATH_EXCEPTIONS
|
#if DRAGONECS_DISABLE_CATH_EXCEPTIONS
|
||||||
throw;
|
throw e;
|
||||||
#endif
|
#else
|
||||||
EcsDebug.PrintError(e);
|
EcsDebug.PrintError(e);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
_markers[i].End();
|
_markers[i].End();
|
||||||
}
|
}
|
||||||
@ -251,9 +252,10 @@ namespace DCFApixels.DragonECS
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
#if DRAGONECS_DISABLE_CATH_EXCEPTIONS
|
#if DRAGONECS_DISABLE_CATH_EXCEPTIONS
|
||||||
throw;
|
throw e;
|
||||||
#endif
|
#else
|
||||||
EcsDebug.PrintError(e);
|
EcsDebug.PrintError(e);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
_markers[i].End();
|
_markers[i].End();
|
||||||
}
|
}
|
||||||
@ -378,9 +380,10 @@ namespace DCFApixels.DragonECS
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
#if DRAGONECS_DISABLE_CATH_EXCEPTIONS
|
#if DRAGONECS_DISABLE_CATH_EXCEPTIONS
|
||||||
throw;
|
throw e;
|
||||||
#endif
|
#else
|
||||||
EcsDebug.PrintError(e);
|
EcsDebug.PrintError(e);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -433,9 +436,10 @@ namespace DCFApixels.DragonECS
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
#if DRAGONECS_DISABLE_CATH_EXCEPTIONS
|
#if DRAGONECS_DISABLE_CATH_EXCEPTIONS
|
||||||
throw;
|
throw e;
|
||||||
#endif
|
#else
|
||||||
EcsDebug.PrintError(e);
|
EcsDebug.PrintError(e);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
154
src/EcsWorld.cs
154
src/EcsWorld.cs
@ -48,7 +48,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.WORLDS_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.WORLDS_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "Container for entities and components.")]
|
[MetaDescription(EcsConsts.AUTHOR, "Container for entities and components.")]
|
||||||
[MetaID("AEF3557C92019C976FC48F90E95A9DA6")]
|
[MetaID("DragonECS_AEF3557C92019C976FC48F90E95A9DA6")]
|
||||||
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
||||||
public partial class EcsWorld : IEntityStorage, IEcsMember, INamedMember
|
public partial class EcsWorld : IEntityStorage, IEcsMember, INamedMember
|
||||||
{
|
{
|
||||||
@ -65,6 +65,8 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
private int[] _delEntBuffer = Array.Empty<int>();
|
private int[] _delEntBuffer = Array.Empty<int>();
|
||||||
private int _delEntBufferCount = 0;
|
private int _delEntBufferCount = 0;
|
||||||
|
private int[] _emptyEntities = Array.Empty<int>();
|
||||||
|
private int _emptyEntitiesCount = 0;
|
||||||
private bool _isEnableAutoReleaseDelEntBuffer = true;
|
private bool _isEnableAutoReleaseDelEntBuffer = true;
|
||||||
|
|
||||||
internal int _entityComponentMaskLength;
|
internal int _entityComponentMaskLength;
|
||||||
@ -194,12 +196,12 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
_poolsMediator = new PoolsMediator(this);
|
_poolsMediator = new PoolsMediator(this);
|
||||||
|
|
||||||
int poolsCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.PoolsCapacity);
|
int poolsCapacity = ArrayUtility.NextPow2(config.PoolsCapacity);
|
||||||
_pools = new IEcsPoolImplementation[poolsCapacity];
|
_pools = new IEcsPoolImplementation[poolsCapacity];
|
||||||
_poolSlots = new PoolSlot[poolsCapacity];
|
_poolSlots = new PoolSlot[poolsCapacity];
|
||||||
ArrayUtility.Fill(_pools, _nullPool);
|
ArrayUtility.Fill(_pools, _nullPool);
|
||||||
|
|
||||||
int entitiesCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.EntitiesCapacity);
|
int entitiesCapacity = ArrayUtility.NextPow2(config.EntitiesCapacity);
|
||||||
_entityDispenser = new IdDispenser(entitiesCapacity, 0, OnEntityDispenserResized);
|
_entityDispenser = new IdDispenser(entitiesCapacity, 0, OnEntityDispenserResized);
|
||||||
|
|
||||||
_executorCoures = new Dictionary<(Type, object), IQueryExecutorImplementation>(config.PoolComponentsCapacity);
|
_executorCoures = new Dictionary<(Type, object), IQueryExecutorImplementation>(config.PoolComponentsCapacity);
|
||||||
@ -253,6 +255,38 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
return Get<AspectCache<TAspect>>().Instance;
|
return Get<AspectCache<TAspect>>().Instance;
|
||||||
}
|
}
|
||||||
|
public void GetAspects<TAspect0>(out TAspect0 a0)
|
||||||
|
where TAspect0 : new()
|
||||||
|
{
|
||||||
|
a0 = GetAspect<TAspect0>();
|
||||||
|
}
|
||||||
|
public void GetAspects<TAspect0, TAspect1>(out TAspect0 a0, out TAspect1 a1)
|
||||||
|
where TAspect0 : new()
|
||||||
|
where TAspect1 : new()
|
||||||
|
{
|
||||||
|
a0 = GetAspect<TAspect0>();
|
||||||
|
a1 = GetAspect<TAspect1>();
|
||||||
|
}
|
||||||
|
public void GetAspects<TAspect0, TAspect1, TAspect2>(out TAspect0 a0, out TAspect1 a1, out TAspect2 a2)
|
||||||
|
where TAspect0 : new()
|
||||||
|
where TAspect1 : new()
|
||||||
|
where TAspect2 : new()
|
||||||
|
{
|
||||||
|
a0 = GetAspect<TAspect0>();
|
||||||
|
a1 = GetAspect<TAspect1>();
|
||||||
|
a2 = GetAspect<TAspect2>();
|
||||||
|
}
|
||||||
|
public void GetAspects<TAspect0, TAspect1, TAspect2, TAspect3>(out TAspect0 a0, out TAspect1 a1, out TAspect2 a2, out TAspect3 a3)
|
||||||
|
where TAspect0 : new()
|
||||||
|
where TAspect1 : new()
|
||||||
|
where TAspect2 : new()
|
||||||
|
where TAspect3 : new()
|
||||||
|
{
|
||||||
|
a0 = GetAspect<TAspect0>();
|
||||||
|
a1 = GetAspect<TAspect1>();
|
||||||
|
a2 = GetAspect<TAspect2>();
|
||||||
|
a3 = GetAspect<TAspect3>();
|
||||||
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public TAspect GetAspect<TAspect>(out EcsMask mask) where TAspect : new()
|
public TAspect GetAspect<TAspect>(out EcsMask mask) where TAspect : new()
|
||||||
{
|
{
|
||||||
@ -327,6 +361,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public int NewEntity(int entityID)
|
public int NewEntity(int entityID)
|
||||||
{
|
{
|
||||||
|
_entityDispenser.Upsize(entityID + 1);
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (IsUsed(entityID)) { Throw.World_EntityIsAlreadyСontained(entityID); }
|
if (IsUsed(entityID)) { Throw.World_EntityIsAlreadyСontained(entityID); }
|
||||||
#elif DRAGONECS_STABILITY_MODE
|
#elif DRAGONECS_STABILITY_MODE
|
||||||
@ -348,6 +383,7 @@ namespace DCFApixels.DragonECS
|
|||||||
slot.gen |= GEN_SLEEP_MASK;
|
slot.gen |= GEN_SLEEP_MASK;
|
||||||
}
|
}
|
||||||
_entityListeners.InvokeOnNewEntity(entityID);
|
_entityListeners.InvokeOnNewEntity(entityID);
|
||||||
|
MoveToEmptyEntities(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -380,7 +416,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public void DelEntity(int entityID)
|
public void DelEntity(int entityID)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (IsUsed(entityID) == false) { Throw.World_EntityIsAlreadyСontained(entityID); }
|
if (IsUsed(entityID) == false) { Throw.World_EntityIsNotContained(entityID); }
|
||||||
#elif DRAGONECS_STABILITY_MODE
|
#elif DRAGONECS_STABILITY_MODE
|
||||||
if (IsUsed(entityID) == false) { return; }
|
if (IsUsed(entityID) == false) { return; }
|
||||||
#endif
|
#endif
|
||||||
@ -390,6 +426,24 @@ namespace DCFApixels.DragonECS
|
|||||||
_entitiesCount--;
|
_entitiesCount--;
|
||||||
_entityListeners.InvokeOnDelEntity(entityID);
|
_entityListeners.InvokeOnDelEntity(entityID);
|
||||||
}
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private void MoveToEmptyEntities(int entityID)
|
||||||
|
{
|
||||||
|
_emptyEntities[_emptyEntitiesCount++] = entityID;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private bool RemoveFromEmptyEntities(int entityID)
|
||||||
|
{
|
||||||
|
for (int i = _emptyEntitiesCount - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if(_emptyEntities[i] == entityID)
|
||||||
|
{
|
||||||
|
_emptyEntities[i] = _emptyEntities[--_emptyEntitiesCount];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Other
|
#region Other
|
||||||
@ -477,20 +531,60 @@ namespace DCFApixels.DragonECS
|
|||||||
#elif DRAGONECS_STABILITY_MODE
|
#elif DRAGONECS_STABILITY_MODE
|
||||||
if (mask.WorldID != ID) { return false; }
|
if (mask.WorldID != ID) { return false; }
|
||||||
#endif
|
#endif
|
||||||
for (int i = 0, iMax = mask._incs.Length; i < iMax; i++)
|
|
||||||
|
|
||||||
|
#if DEBUG && DRAGONECS_DEEP_DEBUG
|
||||||
|
bool IsMatchesMaskDeepDebug(EcsMask mask_, int entityID_)
|
||||||
{
|
{
|
||||||
if (!_pools[mask._incs[i]].Has(entityID))
|
for (int i = 0, iMax = mask_._incs.Length; i < iMax; i++)
|
||||||
{
|
{
|
||||||
|
if (!_pools[mask_._incs[i]].Has(entityID_))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0, iMax = mask_._excs.Length; i < iMax; i++)
|
||||||
|
{
|
||||||
|
if (_pools[mask_._excs[i]].Has(entityID_))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool deepDebug = IsMatchesMaskDeepDebug(mask, entityID);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
var incChuncks = mask._incChunckMasks;
|
||||||
|
var excChuncks = mask._excChunckMasks;
|
||||||
|
var componentMaskStartIndex = entityID << _entityComponentMaskLengthBitShift;
|
||||||
|
|
||||||
|
for (int i = 0; i < incChuncks.Length; i++)
|
||||||
|
{
|
||||||
|
var bit = incChuncks[i];
|
||||||
|
if ((_entityComponentMasks[componentMaskStartIndex + bit.chunkIndex] & bit.mask) != bit.mask)
|
||||||
|
{
|
||||||
|
#if DEBUG && DRAGONECS_DEEP_DEBUG
|
||||||
|
if (false != deepDebug) { Throw.DeepDebugException(); }
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0, iMax = mask._excs.Length; i < iMax; i++)
|
for (int i = 0; i < excChuncks.Length; i++)
|
||||||
{
|
{
|
||||||
if (_pools[mask._excs[i]].Has(entityID))
|
var bit = excChuncks[i];
|
||||||
|
if ((_entityComponentMasks[componentMaskStartIndex + bit.chunkIndex] & bit.mask) != 0)
|
||||||
{
|
{
|
||||||
|
#if DEBUG && DRAGONECS_DEEP_DEBUG
|
||||||
|
if (false != deepDebug) { Throw.DeepDebugException(); }
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG && DRAGONECS_DEEP_DEBUG
|
||||||
|
if (true != deepDebug) { Throw.DeepDebugException(); }
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -745,13 +839,24 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
public void ReleaseDelEntityBufferAll()
|
public void ReleaseDelEntityBufferAll()
|
||||||
{
|
{
|
||||||
ReleaseDelEntityBuffer(_delEntBufferCount);
|
ReleaseDelEntityBuffer(-1);
|
||||||
}
|
}
|
||||||
public unsafe void ReleaseDelEntityBuffer(int count)
|
public unsafe void ReleaseDelEntityBuffer(int count)
|
||||||
{
|
{
|
||||||
if (_delEntBufferCount <= 0) { return; }
|
if (_emptyEntitiesCount <= 0 && _delEntBufferCount <= 0) { return; }
|
||||||
unchecked { _version++; }
|
unchecked { _version++; }
|
||||||
|
|
||||||
|
for (int i = 0; i < _emptyEntitiesCount; i++)
|
||||||
|
{
|
||||||
|
TryDelEntity(_emptyEntities[i]);
|
||||||
|
}
|
||||||
|
_emptyEntitiesCount = 0;
|
||||||
|
|
||||||
|
if(count < 0)
|
||||||
|
{
|
||||||
|
count = _delEntBufferCount;
|
||||||
|
}
|
||||||
|
|
||||||
count = Math.Max(0, Math.Min(count, _delEntBufferCount));
|
count = Math.Max(0, Math.Min(count, _delEntBufferCount));
|
||||||
_delEntBufferCount -= count;
|
_delEntBufferCount -= count;
|
||||||
int slisedCount = count;
|
int slisedCount = count;
|
||||||
@ -831,6 +936,7 @@ namespace DCFApixels.DragonECS
|
|||||||
SetEntityComponentMaskLength(CalcEntityComponentMaskLength()); //_pools.Length / COMPONENT_MASK_CHUNK_SIZE + 1;
|
SetEntityComponentMaskLength(CalcEntityComponentMaskLength()); //_pools.Length / COMPONENT_MASK_CHUNK_SIZE + 1;
|
||||||
Array.Resize(ref _entities, newSize);
|
Array.Resize(ref _entities, newSize);
|
||||||
Array.Resize(ref _delEntBuffer, newSize);
|
Array.Resize(ref _delEntBuffer, newSize);
|
||||||
|
Array.Resize(ref _emptyEntities, newSize);
|
||||||
Array.Resize(ref _entityComponentMasks, newSize * _entityComponentMaskLength);
|
Array.Resize(ref _entityComponentMasks, newSize * _entityComponentMaskLength);
|
||||||
|
|
||||||
ArrayUtility.Fill(_entities, EntitySlot.Empty, _entitiesCapacity);
|
ArrayUtility.Fill(_entities, EntitySlot.Empty, _entitiesCapacity);
|
||||||
@ -951,10 +1057,8 @@ namespace DCFApixels.DragonECS
|
|||||||
public ReadOnlySpan<object> GetComponentsFor(int entityID)
|
public ReadOnlySpan<object> GetComponentsFor(int entityID)
|
||||||
{
|
{
|
||||||
int count = GetComponentTypeIDsFor_Internal(entityID, ref _componentIDsBuffer);
|
int count = GetComponentTypeIDsFor_Internal(entityID, ref _componentIDsBuffer);
|
||||||
if (_componentsBuffer == null || _componentsBuffer.Length < count)
|
ArrayUtility.UpsizeWithoutCopy(ref _componentIDsBuffer, count);
|
||||||
{
|
|
||||||
_componentsBuffer = new object[count];
|
|
||||||
}
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
_componentsBuffer[i] = _pools[_componentIDsBuffer[i]].GetRaw(entityID);
|
_componentsBuffer[i] = _pools[_componentIDsBuffer[i]].GetRaw(entityID);
|
||||||
@ -982,14 +1086,7 @@ namespace DCFApixels.DragonECS
|
|||||||
private unsafe int GetComponentTypeIDsFor_Internal(int entityID, ref int[] componentIDs)
|
private unsafe int GetComponentTypeIDsFor_Internal(int entityID, ref int[] componentIDs)
|
||||||
{
|
{
|
||||||
var itemsCount = GetComponentsCount(entityID);
|
var itemsCount = GetComponentsCount(entityID);
|
||||||
if (componentIDs == null)
|
ArrayUtility.UpsizeWithoutCopy(ref componentIDs, itemsCount);
|
||||||
{
|
|
||||||
componentIDs = new int[itemsCount];
|
|
||||||
}
|
|
||||||
if (componentIDs.Length < itemsCount)
|
|
||||||
{
|
|
||||||
Array.Resize(ref componentIDs, itemsCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itemsCount <= 0) { return 0; }
|
if (itemsCount <= 0) { return 0; }
|
||||||
|
|
||||||
@ -1004,8 +1101,8 @@ namespace DCFApixels.DragonECS
|
|||||||
int arrayIndex = 0;
|
int arrayIndex = 0;
|
||||||
for (int chunkIndex = entityID << _entityComponentMaskLengthBitShift,
|
for (int chunkIndex = entityID << _entityComponentMaskLengthBitShift,
|
||||||
chunkIndexMax = chunkIndex + _entityComponentMaskLength;
|
chunkIndexMax = chunkIndex + _entityComponentMaskLength;
|
||||||
chunkIndex < chunkIndexMax;
|
chunkIndex < chunkIndexMax;
|
||||||
chunkIndex++)
|
chunkIndex++)
|
||||||
{
|
{
|
||||||
int chunk = _entityComponentMasks[chunkIndex];
|
int chunk = _entityComponentMasks[chunkIndex];
|
||||||
if (chunk == 0)
|
if (chunk == 0)
|
||||||
@ -1150,15 +1247,19 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
private EcsWorld _world;
|
private EcsWorld _world;
|
||||||
private List<MaskQueryExecutor> _queries;
|
private List<MaskQueryExecutor> _queries;
|
||||||
|
public string Name { get { return _world.Name; } }
|
||||||
public EntitySlotInfo[] Entities
|
public EntitySlotInfo[] Entities
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
EntitySlotInfo[] result = new EntitySlotInfo[_world.Count];
|
EntitySlotInfo[] result = new EntitySlotInfo[_world.Count];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var e in _world.ToSpan())
|
using (_world.DisableAutoReleaseDelEntBuffer())
|
||||||
{
|
{
|
||||||
result[i++] = _world.GetEntitySlotInfoDebug(e);
|
foreach (var e in _world.ToSpan())
|
||||||
|
{
|
||||||
|
result[i++] = _world.GetEntitySlotInfoDebug(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1166,6 +1267,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public long Version { get { return _world.Version; } }
|
public long Version { get { return _world.Version; } }
|
||||||
public IEcsPool[] Pools { get { return _world._pools; } }
|
public IEcsPool[] Pools { get { return _world._pools; } }
|
||||||
public short ID { get { return _world.ID; } }
|
public short ID { get { return _world.ID; } }
|
||||||
|
public bool IsDestroyed { get { return _world._isDestroyed; } }
|
||||||
public List<MaskQueryExecutor> MaskQueries { get { return _queries; } }
|
public List<MaskQueryExecutor> MaskQueries { get { return _queries; } }
|
||||||
public DebuggerProxy(EcsWorld world)
|
public DebuggerProxy(EcsWorld world)
|
||||||
{
|
{
|
||||||
|
@ -40,6 +40,17 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
return FindPoolInstance_Internal(GetComponentTypeID(componentType));
|
return FindPoolInstance_Internal(GetComponentTypeID(componentType));
|
||||||
}
|
}
|
||||||
|
public bool TryFindPoolInstance(int componentTypeID, out IEcsPool pool)
|
||||||
|
{
|
||||||
|
pool = FindPoolInstance(componentTypeID);
|
||||||
|
return pool.IsNullOrDummy() == false;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool TryFindPoolInstance(Type componentType, out IEcsPool pool)
|
||||||
|
{
|
||||||
|
pool = FindPoolInstance(componentType);
|
||||||
|
return pool.IsNullOrDummy() == false;
|
||||||
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private IEcsPool FindPoolInstance_Internal(int componentTypeID)
|
private IEcsPool FindPoolInstance_Internal(int componentTypeID)
|
||||||
{
|
{
|
||||||
@ -267,7 +278,11 @@ namespace DCFApixels.DragonECS
|
|||||||
ref PoolSlot slot = ref _poolSlots[componentTypeID];
|
ref PoolSlot slot = ref _poolSlots[componentTypeID];
|
||||||
slot.count++;
|
slot.count++;
|
||||||
slot.version++;
|
slot.version++;
|
||||||
_entities[entityID].componentsCount++;
|
var count = _entities[entityID].componentsCount++;
|
||||||
|
if (count == 0 && IsUsed(entityID))
|
||||||
|
{
|
||||||
|
RemoveFromEmptyEntities(entityID);
|
||||||
|
}
|
||||||
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex] |= maskBit.mask;
|
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex] |= maskBit.mask;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -282,7 +297,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
if (count == 0 && IsUsed(entityID))
|
if (count == 0 && IsUsed(entityID))
|
||||||
{
|
{
|
||||||
DelEntity(entityID);
|
MoveToEmptyEntities(entityID);
|
||||||
}
|
}
|
||||||
CheckUnregisterValid(count, entityID);
|
CheckUnregisterValid(count, entityID);
|
||||||
}
|
}
|
||||||
@ -298,7 +313,11 @@ namespace DCFApixels.DragonECS
|
|||||||
ref PoolSlot slot = ref _poolSlots[componentTypeID];
|
ref PoolSlot slot = ref _poolSlots[componentTypeID];
|
||||||
slot.count++;
|
slot.count++;
|
||||||
slot.version++;
|
slot.version++;
|
||||||
_entities[entityID].componentsCount++;
|
var count = _entities[entityID].componentsCount++;
|
||||||
|
if(count == 0 && IsUsed(entityID))
|
||||||
|
{
|
||||||
|
RemoveFromEmptyEntities(entityID);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -319,7 +338,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
if (count == 0 && IsUsed(entityID))
|
if (count == 0 && IsUsed(entityID))
|
||||||
{
|
{
|
||||||
DelEntity(entityID);
|
MoveToEmptyEntities(entityID);
|
||||||
}
|
}
|
||||||
CheckUnregisterValid(count, entityID);
|
CheckUnregisterValid(count, entityID);
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#if DISABLE_DEBUG
|
#if DISABLE_DEBUG
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
using DCFApixels.DragonECS.Core;
|
||||||
using DCFApixels.DragonECS.Internal;
|
using DCFApixels.DragonECS.Internal;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -25,11 +26,11 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
private static EcsWorld[] _worlds = Array.Empty<EcsWorld>();
|
private static EcsWorld[] _worlds = Array.Empty<EcsWorld>();
|
||||||
private static readonly IdDispenser _worldIdDispenser = new IdDispenser(4, 0, n => Array.Resize(ref _worlds, n));
|
private static readonly IdDispenser _worldIdDispenser = new IdDispenser(4, 0, n => Array.Resize(ref _worlds, n));
|
||||||
|
|
||||||
private static StructList<WorldComponentPoolAbstract> _allWorldComponentPools = new StructList<WorldComponentPoolAbstract>(64);
|
private static StructList<WorldComponentPoolAbstract> _allWorldComponentPools = new StructList<WorldComponentPoolAbstract>(64);
|
||||||
|
private static readonly object _worldLock = new object();
|
||||||
|
|
||||||
private StructList<WorldComponentPoolAbstract> _worldComponentPools;
|
private StructList<WorldComponentPoolAbstract> _worldComponentPools;
|
||||||
private int _builtinWorldComponentsCount = 0;
|
private int _builtinWorldComponentsCount = 0;
|
||||||
private static readonly object _worldLock = new object();
|
|
||||||
|
|
||||||
static EcsWorld()
|
static EcsWorld()
|
||||||
{
|
{
|
||||||
@ -80,6 +81,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
public static void ResetStaticState()
|
public static void ResetStaticState()
|
||||||
{
|
{
|
||||||
|
var nullworld = _worlds[0];
|
||||||
for (int i = 1; i < _worlds.Length; i++)
|
for (int i = 1; i < _worlds.Length; i++)
|
||||||
{
|
{
|
||||||
var world = _worlds[i];
|
var world = _worlds[i];
|
||||||
@ -91,6 +93,8 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
world = null;
|
world = null;
|
||||||
}
|
}
|
||||||
|
_worlds = new EcsWorld[_worldIdDispenser.Capacity];
|
||||||
|
_worlds[0] = nullworld;
|
||||||
_worldIdDispenser.ReleaseAll();
|
_worldIdDispenser.ReleaseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,8 +140,8 @@ namespace DCFApixels.DragonECS
|
|||||||
private static short _count;
|
private static short _count;
|
||||||
private static short[] _recycledItems = new short[4];
|
private static short[] _recycledItems = new short[4];
|
||||||
private static short _recycledItemsCount;
|
private static short _recycledItemsCount;
|
||||||
private static IEcsWorldComponent<T> _interface = EcsWorldComponentHandler<T>.instance;
|
private static readonly IEcsWorldComponent<T> _interface = EcsWorldComponentHandler<T>.instance;
|
||||||
private static Abstract _controller = new Abstract();
|
private static readonly Abstract _controller = new Abstract();
|
||||||
static WorldComponentPool()
|
static WorldComponentPool()
|
||||||
{
|
{
|
||||||
_allWorldComponentPools.Add(_controller);
|
_allWorldComponentPools.Add(_controller);
|
||||||
|
@ -89,6 +89,28 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
public EcsSpan Execute()
|
public EcsSpan Execute()
|
||||||
{
|
{
|
||||||
Execute_Iternal();
|
Execute_Iternal();
|
||||||
|
#if DEBUG && DRAGONECS_DEEP_DEBUG
|
||||||
|
var newSpan = new EcsSpan(World.ID, _filteredAllEntities, _filteredAllEntitiesCount);
|
||||||
|
using (EcsGroup group = EcsGroup.New(World))
|
||||||
|
{
|
||||||
|
foreach (var e in World.Entities)
|
||||||
|
{
|
||||||
|
if (World.IsMatchesMask(Mask, e))
|
||||||
|
{
|
||||||
|
group.Add(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (group.SetEquals(newSpan) == false)
|
||||||
|
{
|
||||||
|
int[] array = new int[_filteredAllEntities.Length];
|
||||||
|
var count = _iterator.IterateTo(World.Entities, ref array);
|
||||||
|
|
||||||
|
EcsDebug.PrintError(newSpan.ToString() + "\r\n" + group.ToSpan().ToString());
|
||||||
|
Throw.DeepDebugException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return new EcsSpan(World.ID, _filteredAllEntities, _filteredAllEntitiesCount);
|
return new EcsSpan(World.ID, _filteredAllEntities, _filteredAllEntitiesCount);
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -99,6 +121,16 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
return Execute();
|
return Execute();
|
||||||
}
|
}
|
||||||
ExecuteFor_Iternal(span);
|
ExecuteFor_Iternal(span);
|
||||||
|
#if DEBUG && DRAGONECS_DEEP_DEBUG
|
||||||
|
var newSpan = new EcsSpan(World.ID, _filteredEntities, _filteredEntitiesCount);
|
||||||
|
foreach (var e in newSpan)
|
||||||
|
{
|
||||||
|
if (World.IsMatchesMask(Mask, e) == false)
|
||||||
|
{
|
||||||
|
Throw.DeepDebugException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return new EcsSpan(World.ID, _filteredEntities, _filteredEntitiesCount);
|
return new EcsSpan(World.ID, _filteredEntities, _filteredEntitiesCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +68,24 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
{
|
{
|
||||||
_version++;
|
_version++;
|
||||||
_iterator.IterateTo(World.Entities, _filteredAllGroup);
|
_iterator.IterateTo(World.Entities, _filteredAllGroup);
|
||||||
|
#if DEBUG && DRAGONECS_DEEP_DEBUG
|
||||||
|
if(_filteredGroup == null)
|
||||||
|
{
|
||||||
|
_filteredGroup = EcsGroup.New(World);
|
||||||
|
}
|
||||||
|
_filteredGroup.Clear();
|
||||||
|
foreach (var e in World.Entities)
|
||||||
|
{
|
||||||
|
if(World.IsMatchesMask(Mask, e))
|
||||||
|
{
|
||||||
|
_filteredGroup.Add(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(_filteredAllGroup.SetEquals(_filteredGroup) == false)
|
||||||
|
{
|
||||||
|
throw new System.InvalidOperationException();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
@ -125,6 +125,7 @@ namespace DCFApixels.DragonECS.Core
|
|||||||
_maskInc = mask._incs;
|
_maskInc = mask._incs;
|
||||||
_maskExc = mask._excs;
|
_maskExc = mask._excs;
|
||||||
_count = 1 + mask._incs.Length + mask._excs.Length;
|
_count = 1 + mask._incs.Length + mask._excs.Length;
|
||||||
|
|
||||||
_versions = UnmanagedArrayUtility.NewAndInit<long>(_count);
|
_versions = UnmanagedArrayUtility.NewAndInit<long>(_count);
|
||||||
}
|
}
|
||||||
public bool Check()
|
public bool Check()
|
||||||
@ -158,17 +159,17 @@ namespace DCFApixels.DragonECS.Core
|
|||||||
{
|
{
|
||||||
*_versions = _world.Version;
|
*_versions = _world.Version;
|
||||||
|
|
||||||
long* ptr = _versions;
|
long* versionsPtr = _versions;
|
||||||
var slots = _world._poolSlots;
|
var slots = _world._poolSlots;
|
||||||
foreach (var slotIndex in _maskInc)
|
foreach (var slotIndex in _maskInc)
|
||||||
{
|
{
|
||||||
ptr++;
|
versionsPtr++;
|
||||||
*ptr = slots[slotIndex].version;
|
*versionsPtr = slots[slotIndex].version;
|
||||||
}
|
}
|
||||||
foreach (var slotIndex in _maskExc)
|
foreach (var slotIndex in _maskExc)
|
||||||
{
|
{
|
||||||
ptr++;
|
versionsPtr++;
|
||||||
*ptr = slots[slotIndex].version;
|
*versionsPtr = slots[slotIndex].version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public bool CheckAndNext()
|
public bool CheckAndNext()
|
||||||
@ -179,25 +180,27 @@ namespace DCFApixels.DragonECS.Core
|
|||||||
}
|
}
|
||||||
*_versions = _world.Version;
|
*_versions = _world.Version;
|
||||||
|
|
||||||
long* ptr = _versions;
|
long* versionsPtr = _versions;
|
||||||
var slots = _world._poolSlots;
|
var slots = _world._poolSlots;
|
||||||
bool result = _count != 1;
|
// Так как проверки EXC работают не правильно при отсутсвии INC,
|
||||||
|
// то проверки без INC должны всегда возвращать false.
|
||||||
|
bool result = _maskInc.Length > 0;
|
||||||
foreach (var slotIndex in _maskInc)
|
foreach (var slotIndex in _maskInc)
|
||||||
{
|
{
|
||||||
ptr++;
|
versionsPtr++;
|
||||||
if (*ptr != slots[slotIndex].version)
|
if (*versionsPtr != slots[slotIndex].version)
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
*ptr = slots[slotIndex].version;
|
*versionsPtr = slots[slotIndex].version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var slotIndex in _maskExc)
|
foreach (var slotIndex in _maskExc)
|
||||||
{
|
{
|
||||||
ptr++;
|
versionsPtr++;
|
||||||
if (*ptr != slots[slotIndex].version)
|
if (*versionsPtr != slots[slotIndex].version)
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
*ptr = slots[slotIndex].version;
|
*versionsPtr = slots[slotIndex].version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -9,7 +9,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.DI_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.DI_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "The interface of the dependency injection process.")]
|
[MetaDescription(EcsConsts.AUTHOR, "The interface of the dependency injection process.")]
|
||||||
[MetaID("4C86537C92019AA24383CBF53CBD456C")]
|
[MetaID("DragonECS_4C86537C92019AA24383CBF53CBD456C")]
|
||||||
public interface IEcsInject<T> : IEcsInjectProcess
|
public interface IEcsInject<T> : IEcsInjectProcess
|
||||||
{
|
{
|
||||||
void Inject(T obj);
|
void Inject(T obj);
|
||||||
@ -22,7 +22,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.DI_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.DI_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "The process interface that signals the completion of injection during pipeline initialization via the EcsPipeline.Init() method.")]
|
[MetaDescription(EcsConsts.AUTHOR, "The process interface that signals the completion of injection during pipeline initialization via the EcsPipeline.Init() method.")]
|
||||||
[MetaID("05C3537C920155AFC044C900E4F17D90")]
|
[MetaID("DragonECS_05C3537C920155AFC044C900E4F17D90")]
|
||||||
public interface IOnInitInjectionComplete : IEcsProcess
|
public interface IOnInitInjectionComplete : IEcsProcess
|
||||||
{
|
{
|
||||||
void OnBeforeInitInjection();
|
void OnBeforeInitInjection();
|
||||||
|
@ -14,13 +14,13 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
{
|
{
|
||||||
int Next { get; }
|
int Next { get; }
|
||||||
}
|
}
|
||||||
internal readonly struct LinkedListIterator<T> : IEnumerable<T>
|
internal readonly struct LinkedListCountIterator<T> : IEnumerable<T>
|
||||||
where T : ILinkedNext
|
where T : ILinkedNext
|
||||||
{
|
{
|
||||||
public readonly T[] Array;
|
public readonly T[] Array;
|
||||||
public readonly int Count;
|
public readonly int Count;
|
||||||
public readonly int StartIndex;
|
public readonly int StartIndex;
|
||||||
public LinkedListIterator(T[] array, int count, int startIndex)
|
public LinkedListCountIterator(T[] array, int count, int startIndex)
|
||||||
{
|
{
|
||||||
Array = array;
|
Array = array;
|
||||||
Count = count;
|
Count = count;
|
||||||
@ -66,6 +66,58 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
void IEnumerator.Reset() { throw new NotSupportedException(); }
|
void IEnumerator.Reset() { throw new NotSupportedException(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
internal readonly struct LinkedListIterator<T> : IEnumerable<T>
|
||||||
|
where T : ILinkedNext
|
||||||
|
{
|
||||||
|
public readonly T[] Array;
|
||||||
|
public readonly int EndIndex;
|
||||||
|
public readonly int StartIndex;
|
||||||
|
public LinkedListIterator(T[] array, int endIndex, int startIndex)
|
||||||
|
{
|
||||||
|
Array = array;
|
||||||
|
EndIndex = endIndex;
|
||||||
|
StartIndex = startIndex;
|
||||||
|
}
|
||||||
|
public Enumerator GetEnumerator()
|
||||||
|
{
|
||||||
|
return new Enumerator(Array, EndIndex, StartIndex);
|
||||||
|
}
|
||||||
|
IEnumerator<T> IEnumerable<T>.GetEnumerator() { return GetEnumerator(); }
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
|
||||||
|
public struct Enumerator : IEnumerator<T>
|
||||||
|
{
|
||||||
|
private readonly T[] _array;
|
||||||
|
private readonly int _endIndex;
|
||||||
|
private readonly int _startIndex;
|
||||||
|
private int _nextIndex;
|
||||||
|
private int _index;
|
||||||
|
public ref T Current { get { return ref _array[_index]; } }
|
||||||
|
T IEnumerator<T>.Current { get { return Current; } }
|
||||||
|
object IEnumerator.Current { get { return Current; } }
|
||||||
|
public Enumerator(T[] array, int endIndex, int head)
|
||||||
|
{
|
||||||
|
_array = array;
|
||||||
|
_startIndex = head;
|
||||||
|
_nextIndex = _startIndex;
|
||||||
|
_endIndex = endIndex;
|
||||||
|
_index = _endIndex;
|
||||||
|
}
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
if (_nextIndex < 0) { return false; }
|
||||||
|
_index = _nextIndex;
|
||||||
|
_nextIndex = _array[_index].Next;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public void Dispose() { }
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
_nextIndex = _startIndex;
|
||||||
|
_index = _endIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
internal static class ArrayUtility
|
internal static class ArrayUtility
|
||||||
{
|
{
|
||||||
@ -92,58 +144,33 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
Array.Copy(array, array.Length - rightHeadLength, result, array.Length - rightHeadLength, rightHeadLength); // copy right head
|
Array.Copy(array, array.Length - rightHeadLength, result, array.Length - rightHeadLength, rightHeadLength); // copy right head
|
||||||
array = result;
|
array = result;
|
||||||
}
|
}
|
||||||
private static int GetHighBitNumber(uint bits)
|
|
||||||
{
|
public static int NextPow2(int v)
|
||||||
if (bits == 0)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int bit = 0;
|
|
||||||
if ((bits & 0xFFFF0000) != 0)
|
|
||||||
{
|
|
||||||
bits >>= 16;
|
|
||||||
bit |= 16;
|
|
||||||
}
|
|
||||||
if ((bits & 0xFF00) != 0)
|
|
||||||
{
|
|
||||||
bits >>= 8;
|
|
||||||
bit |= 8;
|
|
||||||
}
|
|
||||||
if ((bits & 0xF0) != 0)
|
|
||||||
{
|
|
||||||
bits >>= 4;
|
|
||||||
bit |= 4;
|
|
||||||
}
|
|
||||||
if ((bits & 0xC) != 0)
|
|
||||||
{
|
|
||||||
bits >>= 2;
|
|
||||||
bit |= 2;
|
|
||||||
}
|
|
||||||
if ((bits & 0x2) != 0)
|
|
||||||
{
|
|
||||||
bit |= 1;
|
|
||||||
}
|
|
||||||
return bit;
|
|
||||||
}
|
|
||||||
public static int NormalizeSizeToPowerOfTwo(int minSize)
|
|
||||||
{
|
{
|
||||||
unchecked
|
unchecked
|
||||||
{
|
{
|
||||||
return 1 << (GetHighBitNumber((uint)minSize - 1u) + 1);
|
v--;
|
||||||
|
v |= v >> 1;
|
||||||
|
v |= v >> 2;
|
||||||
|
v |= v >> 4;
|
||||||
|
v |= v >> 8;
|
||||||
|
v |= v >> 16;
|
||||||
|
return ++v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static int NormalizeSizeToPowerOfTwo_ClampOverflow(int minSize)
|
public static int NextPow2_ClampOverflow(int v)
|
||||||
{
|
{
|
||||||
unchecked
|
unchecked
|
||||||
{
|
{
|
||||||
int hibit = (GetHighBitNumber((uint)minSize - 1u) + 1);
|
const int NO_SIGN_HIBIT = 0x40000000;
|
||||||
if (hibit >= 32)
|
if ((v & NO_SIGN_HIBIT) != 0)
|
||||||
{
|
{
|
||||||
return int.MaxValue;
|
return int.MaxValue;
|
||||||
}
|
}
|
||||||
return 1 << hibit;
|
return NextPow2(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Fill<T>(T[] array, T value, int startIndex = 0, int length = -1)
|
public static void Fill<T>(T[] array, T value, int startIndex = 0, int length = -1)
|
||||||
{
|
{
|
||||||
if (length < 0)
|
if (length < 0)
|
||||||
@ -159,6 +186,39 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
array[i] = value;
|
array[i] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void UpsizeWithoutCopy<T>(ref T[] array, int minSize)
|
||||||
|
{
|
||||||
|
if (array == null || minSize > array.Length)
|
||||||
|
{
|
||||||
|
array = new T[minSize];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void Upsize<T>(ref T[] array, int minSize)
|
||||||
|
{
|
||||||
|
if (array == null)
|
||||||
|
{
|
||||||
|
array = new T[minSize];
|
||||||
|
}
|
||||||
|
else if (minSize > array.Length)
|
||||||
|
{
|
||||||
|
Array.Resize(ref array, minSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void UpsizeToNextPow2<T>(ref T[] array, int minSize)
|
||||||
|
{
|
||||||
|
if (array == null)
|
||||||
|
{
|
||||||
|
minSize = NextPow2(minSize);
|
||||||
|
array = new T[minSize];
|
||||||
|
}
|
||||||
|
else if (minSize > array.Length)
|
||||||
|
{
|
||||||
|
minSize = NextPow2(minSize);
|
||||||
|
Array.Resize(ref array, minSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
internal readonly struct EnumerableInt : IEnumerable<int>
|
internal readonly struct EnumerableInt : IEnumerable<int>
|
||||||
{
|
{
|
||||||
|
@ -12,46 +12,6 @@ using Unity.IL2CPP.CompilerServices;
|
|||||||
|
|
||||||
namespace DCFApixels.DragonECS.Internal
|
namespace DCFApixels.DragonECS.Internal
|
||||||
{
|
{
|
||||||
#if ENABLE_IL2CPP
|
|
||||||
[Il2CppSetOption(Option.NullChecks, false)]
|
|
||||||
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
|
||||||
#endif
|
|
||||||
[DebuggerDisplay("{" + nameof(GetDebuggerDisplay) + "(),nq}")]
|
|
||||||
internal readonly struct EcsTypeCodeKey : IEquatable<EcsTypeCodeKey>
|
|
||||||
{
|
|
||||||
public readonly Type Type;
|
|
||||||
public readonly string NameKey;
|
|
||||||
public EcsTypeCodeKey(Type type, string nameKey)
|
|
||||||
{
|
|
||||||
Type = type;
|
|
||||||
NameKey = nameKey;
|
|
||||||
}
|
|
||||||
public bool Equals(EcsTypeCodeKey other)
|
|
||||||
{
|
|
||||||
return Type == other.Type && NameKey == other.NameKey;
|
|
||||||
}
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
return obj is EcsTypeCodeKey other && Equals(other);
|
|
||||||
}
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return HashCode.Combine(Type, NameKey);
|
|
||||||
}
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(NameKey))
|
|
||||||
{
|
|
||||||
return Type.ToString();
|
|
||||||
}
|
|
||||||
return $"{Type} {NameKey}";
|
|
||||||
}
|
|
||||||
public static implicit operator EcsTypeCodeKey(Type type) { return new EcsTypeCodeKey(type, string.Empty); }
|
|
||||||
private string GetDebuggerDisplay()
|
|
||||||
{
|
|
||||||
return ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//TODO разработать возможность ручного устанавливания ID типам.
|
//TODO разработать возможность ручного устанавливания ID типам.
|
||||||
//это может быть полезно как детерминированность для сети
|
//это может быть полезно как детерминированность для сети
|
||||||
#if ENABLE_IL2CPP
|
#if ENABLE_IL2CPP
|
||||||
@ -62,7 +22,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
{
|
{
|
||||||
private static readonly Dictionary<EcsTypeCodeKey, EcsTypeCode> _codes = new Dictionary<EcsTypeCodeKey, EcsTypeCode>();
|
private static readonly Dictionary<EcsTypeCodeKey, EcsTypeCode> _codes = new Dictionary<EcsTypeCodeKey, EcsTypeCode>();
|
||||||
private static int _increment = 1;
|
private static int _increment = 1;
|
||||||
private static object _lock = new object();
|
private static readonly object _lock = new object();
|
||||||
public static int Count
|
public static int Count
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -83,7 +43,6 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static EcsTypeCode Get<T>() { return EcsTypeCodeCache<T>.code; }
|
public static EcsTypeCode Get<T>() { return EcsTypeCodeCache<T>.code; }
|
||||||
public static bool Has(Type type) { return _codes.ContainsKey(type); }
|
public static bool Has(Type type) { return _codes.ContainsKey(type); }
|
||||||
public static bool Has<T>() { return _codes.ContainsKey(typeof(T)); }
|
|
||||||
public static EcsTypeCodeKey FindTypeOfCode(EcsTypeCode typeCode)
|
public static EcsTypeCodeKey FindTypeOfCode(EcsTypeCode typeCode)
|
||||||
{
|
{
|
||||||
foreach (var item in _codes)
|
foreach (var item in _codes)
|
||||||
@ -123,4 +82,40 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
return this.AutoToString(false);
|
return this.AutoToString(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if ENABLE_IL2CPP
|
||||||
|
[Il2CppSetOption(Option.NullChecks, false)]
|
||||||
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
|
#endif
|
||||||
|
[DebuggerDisplay("{" + nameof(ToString) + "()}")]
|
||||||
|
internal readonly struct EcsTypeCodeKey : IEquatable<EcsTypeCodeKey>
|
||||||
|
{
|
||||||
|
public readonly Type Type;
|
||||||
|
public readonly string NameKey;
|
||||||
|
public EcsTypeCodeKey(Type type, string nameKey)
|
||||||
|
{
|
||||||
|
Type = type;
|
||||||
|
NameKey = nameKey;
|
||||||
|
}
|
||||||
|
public bool Equals(EcsTypeCodeKey other)
|
||||||
|
{
|
||||||
|
return Type == other.Type && NameKey == other.NameKey;
|
||||||
|
}
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
return obj is EcsTypeCodeKey other && Equals(other);
|
||||||
|
}
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return HashCode.Combine(Type, NameKey);
|
||||||
|
}
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(NameKey))
|
||||||
|
{
|
||||||
|
return Type.ToString();
|
||||||
|
}
|
||||||
|
return $"{Type} {NameKey}";
|
||||||
|
}
|
||||||
|
public static implicit operator EcsTypeCodeKey(Type type) { return new EcsTypeCodeKey(type, string.Empty); }
|
||||||
|
}
|
||||||
}
|
}
|
@ -35,7 +35,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get { return _usedCount; }
|
get { return _usedCount; }
|
||||||
}
|
}
|
||||||
public int Size
|
public int Capacity
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get { return _size; }
|
get { return _size; }
|
||||||
@ -247,7 +247,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
private void Upsize_Internal(int minSize)
|
private void Upsize_Internal(int minSize)
|
||||||
{
|
{
|
||||||
Resize(ArrayUtility.NormalizeSizeToPowerOfTwo_ClampOverflow(minSize));
|
Resize(ArrayUtility.NextPow2_ClampOverflow(minSize));
|
||||||
}
|
}
|
||||||
private void Resize(int newSize)
|
private void Resize(int newSize)
|
||||||
{
|
{
|
||||||
@ -339,7 +339,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Pair[] result = new Pair[_target.Size];
|
Pair[] result = new Pair[_target.Capacity];
|
||||||
for (int i = 0; i < result.Length; i++)
|
for (int i = 0; i < result.Length; i++)
|
||||||
{
|
{
|
||||||
result[i] = new Pair(
|
result[i] = new Pair(
|
||||||
@ -354,7 +354,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
ID[] result = new ID[_target.Size];
|
ID[] result = new ID[_target.Capacity];
|
||||||
for (int i = 0; i < result.Length; i++)
|
for (int i = 0; i < result.Length; i++)
|
||||||
{
|
{
|
||||||
int id = _target._dense[i];
|
int id = _target._dense[i];
|
||||||
@ -365,7 +365,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
}
|
}
|
||||||
public bool IsValid => _target.IsValid();
|
public bool IsValid => _target.IsValid();
|
||||||
public int Count => _target.Count;
|
public int Count => _target.Count;
|
||||||
public int Size => _target.Size;
|
public int Capacity => _target.Capacity;
|
||||||
public int NullID => _target._nullID;
|
public int NullID => _target._nullID;
|
||||||
internal readonly struct ID
|
internal readonly struct ID
|
||||||
{
|
{
|
||||||
|
@ -26,7 +26,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= _items.Length) { return; }
|
if (value <= _items.Length) { return; }
|
||||||
value = ArrayUtility.NormalizeSizeToPowerOfTwo(value);
|
value = ArrayUtility.NextPow2(value);
|
||||||
Array.Resize(ref _items, value);
|
Array.Resize(ref _items, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public StructList(int capacity)
|
public StructList(int capacity)
|
||||||
{
|
{
|
||||||
_items = new T[ArrayUtility.NormalizeSizeToPowerOfTwo(capacity)];
|
_items = new T[ArrayUtility.NextPow2(capacity)];
|
||||||
_count = 0;
|
_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_IL2CPP
|
#if ENABLE_IL2CPP
|
||||||
[Il2CppSetOption(Option.NullChecks, false)]
|
[Il2CppSetOption(Option.NullChecks, false)]
|
||||||
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
|
@ -21,8 +21,8 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "Standard component.")]
|
[MetaDescription(EcsConsts.AUTHOR, "Standard component.")]
|
||||||
[MetaID("84D2537C9201D6F6B92FEC1C8883A07A")]
|
[MetaID("DragonECS_84D2537C9201D6F6B92FEC1C8883A07A")]
|
||||||
public interface IEcsComponent : IEcsMember { }
|
public interface IEcsComponent : IEcsComponentMember { }
|
||||||
|
|
||||||
/// <summary>Pool for IEcsComponent components</summary>
|
/// <summary>Pool for IEcsComponent components</summary>
|
||||||
#if ENABLE_IL2CPP
|
#if ENABLE_IL2CPP
|
||||||
@ -31,7 +31,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "Pool for IEcsComponent components.")]
|
[MetaDescription(EcsConsts.AUTHOR, "Pool for IEcsComponent components.")]
|
||||||
[MetaID("C501547C9201A4B03FC25632E4FAAFD7")]
|
[MetaID("DragonECS_C501547C9201A4B03FC25632E4FAAFD7")]
|
||||||
[DebuggerDisplay("Count: {Count} Type: {ComponentType}")]
|
[DebuggerDisplay("Count: {Count} Type: {ComponentType}")]
|
||||||
public sealed class EcsPool<T> : IEcsPoolImplementation<T>, IEcsStructPool<T>, IEntityStorage, IEnumerable<T> //IEnumerable<T> - IntelliSense hack
|
public sealed class EcsPool<T> : IEcsPoolImplementation<T>, IEcsStructPool<T>, IEntityStorage, IEnumerable<T> //IEnumerable<T> - IntelliSense hack
|
||||||
where T : struct, IEcsComponent
|
where T : struct, IEcsComponent
|
||||||
@ -51,8 +51,8 @@ namespace DCFApixels.DragonECS
|
|||||||
private bool _isDenseEntitiesDelayedValid = false;
|
private bool _isDenseEntitiesDelayedValid = false;
|
||||||
private int _recycledCount = 0;
|
private int _recycledCount = 0;
|
||||||
|
|
||||||
private readonly IEcsComponentLifecycle<T> _componentLifecycleHandler = EcsComponentResetHandler<T>.instance;
|
private readonly IEcsComponentLifecycle<T> _componentLifecycleHandler = EcsComponentLifecycleHandler<T>.instance;
|
||||||
private readonly bool _isHasComponentLifecycleHandler = EcsComponentResetHandler<T>.isHasHandler;
|
private readonly bool _isHasComponentLifecycleHandler = EcsComponentLifecycleHandler<T>.isHasHandler;
|
||||||
private readonly IEcsComponentCopy<T> _componentCopyHandler = EcsComponentCopyHandler<T>.instance;
|
private readonly IEcsComponentCopy<T> _componentCopyHandler = EcsComponentCopyHandler<T>.instance;
|
||||||
private readonly bool _isHasComponentCopyHandler = EcsComponentCopyHandler<T>.isHasHandler;
|
private readonly bool _isHasComponentCopyHandler = EcsComponentCopyHandler<T>.isHasHandler;
|
||||||
|
|
||||||
@ -101,11 +101,12 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
ref int itemIndex = ref _mapping[entityID];
|
ref int itemIndex = ref _mapping[entityID];
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
if (_source.IsUsed(entityID) == false) { Throw.Ent_ThrowIsNotAlive(_source, entityID); }
|
||||||
if (itemIndex > 0) { EcsPoolThrowHelper.ThrowAlreadyHasComponent<T>(entityID); }
|
if (itemIndex > 0) { EcsPoolThrowHelper.ThrowAlreadyHasComponent<T>(entityID); }
|
||||||
if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); }
|
if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); }
|
||||||
#elif DRAGONECS_STABILITY_MODE
|
#elif DRAGONECS_STABILITY_MODE
|
||||||
if (itemIndex > 0) { return ref Get(entityID); }
|
if (itemIndex > 0) { return ref Get(entityID); }
|
||||||
if (_isLocked) { return ref _items[0]; }
|
if (_isLocked | _source.IsUsed(entityID) == false) { return ref _items[0]; }
|
||||||
#endif
|
#endif
|
||||||
itemIndex = GetFreeItemIndex(entityID);
|
itemIndex = GetFreeItemIndex(entityID);
|
||||||
_mediator.RegisterComponent(entityID, _componentTypeID, _maskBit);
|
_mediator.RegisterComponent(entityID, _componentTypeID, _maskBit);
|
||||||
@ -279,15 +280,7 @@ namespace DCFApixels.DragonECS
|
|||||||
_maskBit = EcsMaskChunck.FromID(componentTypeID);
|
_maskBit = EcsMaskChunck.FromID(componentTypeID);
|
||||||
|
|
||||||
_mapping = new int[world.Capacity];
|
_mapping = new int[world.Capacity];
|
||||||
Resize(ArrayUtility.NormalizeSizeToPowerOfTwo(world.Configs.GetWorldConfigOrDefault().PoolComponentsCapacity));
|
Resize(ArrayUtility.NextPow2(world.Configs.GetWorldConfigOrDefault().PoolComponentsCapacity));
|
||||||
//_capacity = ArrayUtility.NormalizeSizeToPowerOfTwo(world.Configs.GetWorldConfigOrDefault().PoolComponentsCapacity);
|
|
||||||
//_items = new T[_capacity];
|
|
||||||
//_sparseEntities = new int[_capacity];
|
|
||||||
//_denseEntitiesDelayed = new int[_capacity];
|
|
||||||
//for (int i = 0; i < _capacity; i++)
|
|
||||||
//{// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> free index-<2D> <20><><EFBFBD><EFBFBD> _denseEntitiesDelayed <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0, <20><> free index <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
// _denseEntitiesDelayed[i] = i;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
void IEcsPoolImplementation.OnWorldResize(int newSize)
|
void IEcsPoolImplementation.OnWorldResize(int newSize)
|
||||||
{
|
{
|
||||||
@ -314,7 +307,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
Add(entityID) = dataRaw == null ? default : (T)dataRaw;
|
Add(entityID) = dataRaw == null ? default : (T)dataRaw;
|
||||||
}
|
}
|
||||||
object IEcsReadonlyPool.GetRaw(int entityID) { return Get(entityID); }
|
object IEcsReadonlyPool.GetRaw(int entityID) { return Read(entityID); }
|
||||||
void IEcsPool.SetRaw(int entityID, object dataRaw)
|
void IEcsPool.SetRaw(int entityID, object dataRaw)
|
||||||
{
|
{
|
||||||
Get(entityID) = dataRaw == null ? default : (T)dataRaw;
|
Get(entityID) = dataRaw == null ? default : (T)dataRaw;
|
||||||
@ -515,14 +508,100 @@ namespace DCFApixels.DragonECS
|
|||||||
IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); }
|
IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region MarkersConverter
|
#region Convertors
|
||||||
public static implicit operator EcsPool<T>(IncludeMarker a) { return a.GetInstance<EcsPool<T>>(); }
|
public static implicit operator EcsPool<T>(IncludeMarker a) { return a.GetInstance<EcsPool<T>>(); }
|
||||||
public static implicit operator EcsPool<T>(ExcludeMarker a) { return a.GetInstance<EcsPool<T>>(); }
|
public static implicit operator EcsPool<T>(ExcludeMarker a) { return a.GetInstance<EcsPool<T>>(); }
|
||||||
public static implicit operator EcsPool<T>(OptionalMarker a) { return a.GetInstance<EcsPool<T>>(); }
|
public static implicit operator EcsPool<T>(OptionalMarker a) { return a.GetInstance<EcsPool<T>>(); }
|
||||||
public static implicit operator EcsPool<T>(EcsWorld.GetPoolInstanceMarker a) { return a.GetInstance<EcsPool<T>>(); }
|
public static implicit operator EcsPool<T>(EcsWorld.GetPoolInstanceMarker a) { return a.GetInstance<EcsPool<T>>(); }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Apply
|
||||||
|
public static void Apply(ref T component, int entityID, short worldID)
|
||||||
|
{
|
||||||
|
EcsWorld.GetPoolInstance<EcsPool<T>>(worldID).TryAddOrGet(entityID) = component;
|
||||||
|
}
|
||||||
|
public static void Apply(ref T component, int entityID, EcsPool<T> pool)
|
||||||
|
{
|
||||||
|
pool.TryAddOrGet(entityID) = component;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_IL2CPP
|
||||||
|
[Il2CppSetOption(Option.NullChecks, false)]
|
||||||
|
#endif
|
||||||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
|
public readonly struct ReadonlyEcsPool<T> : IEcsReadonlyPool //IEnumerable<T> - IntelliSense hack
|
||||||
|
where T : struct, IEcsComponent
|
||||||
|
{
|
||||||
|
private readonly EcsPool<T> _pool;
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
public int ComponentTypeID
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return _pool.ComponentTypeID; }
|
||||||
|
}
|
||||||
|
public Type ComponentType
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return _pool.ComponentType; }
|
||||||
|
}
|
||||||
|
public EcsWorld World
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return _pool.World; }
|
||||||
|
}
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return _pool.Count; }
|
||||||
|
}
|
||||||
|
public bool IsReadOnly
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return _pool.IsReadOnly; }
|
||||||
|
}
|
||||||
|
public ref readonly T this[int entityID]
|
||||||
|
{
|
||||||
|
get { return ref _pool.Read(entityID); }
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
internal ReadonlyEcsPool(EcsPool<T> pool)
|
||||||
|
{
|
||||||
|
_pool = pool;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool Has(int entityID) { return _pool.Has(entityID); }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public ref readonly T Get(int entityID) { return ref _pool.Read(entityID); }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public ref readonly T Read(int entityID) { return ref _pool.Read(entityID); }
|
||||||
|
object IEcsReadonlyPool.GetRaw(int entityID) { return _pool.Read(entityID); }
|
||||||
|
|
||||||
|
#if !DRAGONECS_DISABLE_POOLS_EVENTS
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void AddListener(IEcsPoolEventListener listener) { _pool.AddListener(listener); }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void RemoveListener(IEcsPoolEventListener listener) { _pool.AddListener(listener); }
|
||||||
|
#endif
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Convertors
|
||||||
|
public static implicit operator ReadonlyEcsPool<T>(EcsPool<T> a) { return new ReadonlyEcsPool<T>(a); }
|
||||||
|
public static implicit operator ReadonlyEcsPool<T>(IncludeMarker a) { return a.GetInstance<EcsPool<T>>(); }
|
||||||
|
public static implicit operator ReadonlyEcsPool<T>(ExcludeMarker a) { return a.GetInstance<EcsPool<T>>(); }
|
||||||
|
public static implicit operator ReadonlyEcsPool<T>(OptionalMarker a) { return a.GetInstance<EcsPool<T>>(); }
|
||||||
|
public static implicit operator ReadonlyEcsPool<T>(EcsWorld.GetPoolInstanceMarker a) { return a.GetInstance<EcsPool<T>>(); }
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class EcsPoolExtensions
|
public static class EcsPoolExtensions
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
@ -26,6 +26,13 @@ namespace DCFApixels.DragonECS.PoolsCore
|
|||||||
/// <typeparam name="T"> Component type. </typeparam>
|
/// <typeparam name="T"> Component type. </typeparam>
|
||||||
public interface IEcsPoolImplementation<T> : IEcsPoolImplementation { }
|
public interface IEcsPoolImplementation<T> : IEcsPoolImplementation { }
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
//public interface IEcsReadonlyPoolImplementation<TPool> : IEcsReadonlyPool
|
||||||
|
// where TPool : IEcsReadonlyPoolImplementation<TPool>
|
||||||
|
//{
|
||||||
|
// void Init(ref TPool pool);
|
||||||
|
//}
|
||||||
|
|
||||||
#region EcsPoolThrowHelper
|
#region EcsPoolThrowHelper
|
||||||
public static class EcsPoolThrowHelper
|
public static class EcsPoolThrowHelper
|
||||||
{
|
{
|
||||||
@ -74,7 +81,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "A placeholder type, an instance of this type replaces the null ref.")]
|
[MetaDescription(EcsConsts.AUTHOR, "A placeholder type, an instance of this type replaces the null ref.")]
|
||||||
[MetaTags(MetaTags.HIDDEN)]
|
[MetaTags(MetaTags.HIDDEN)]
|
||||||
[MetaID("460E547C9201227A4956AC297F67B484")]
|
[MetaID("DragonECS_460E547C9201227A4956AC297F67B484")]
|
||||||
[DebuggerDisplay("-")]
|
[DebuggerDisplay("-")]
|
||||||
public sealed class EcsNullPool : IEcsPoolImplementation<NullComponent>
|
public sealed class EcsNullPool : IEcsPoolImplementation<NullComponent>
|
||||||
{
|
{
|
||||||
@ -135,13 +142,13 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
throw new NullInstanceException();
|
throw new NullInstanceException();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void IEcsReadonlyPool.Copy(int fromEntityID, int toEntityID)
|
void IEcsPool.Copy(int fromEntityID, int toEntityID)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
throw new NullInstanceException();
|
throw new NullInstanceException();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void IEcsReadonlyPool.Copy(int fromEntityID, EcsWorld toWorld, int toEntityID)
|
void IEcsPool.Copy(int fromEntityID, EcsWorld toWorld, int toEntityID)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
throw new NullInstanceException();
|
throw new NullInstanceException();
|
||||||
@ -189,11 +196,10 @@ namespace DCFApixels.DragonECS
|
|||||||
#region Methods
|
#region Methods
|
||||||
bool Has(int entityID);
|
bool Has(int entityID);
|
||||||
object GetRaw(int entityID);
|
object GetRaw(int entityID);
|
||||||
void Copy(int fromEntityID, int toEntityID);
|
|
||||||
void Copy(int fromEntityID, EcsWorld toWorld, int toEntityID);
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#if !DRAGONECS_DISABLE_POOLS_EVENTS
|
#if !DRAGONECS_DISABLE_POOLS_EVENTS
|
||||||
|
|
||||||
#region Add/Remove Listeners
|
#region Add/Remove Listeners
|
||||||
void AddListener(IEcsPoolEventListener listener);
|
void AddListener(IEcsPoolEventListener listener);
|
||||||
void RemoveListener(IEcsPoolEventListener listener);
|
void RemoveListener(IEcsPoolEventListener listener);
|
||||||
@ -209,6 +215,8 @@ namespace DCFApixels.DragonECS
|
|||||||
void SetRaw(int entityID, object dataRaw);
|
void SetRaw(int entityID, object dataRaw);
|
||||||
void Del(int entityID);
|
void Del(int entityID);
|
||||||
void ClearAll();
|
void ClearAll();
|
||||||
|
void Copy(int fromEntityID, int toEntityID);
|
||||||
|
void Copy(int fromEntityID, EcsWorld toWorld, int toEntityID);
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,6 +269,12 @@ namespace DCFApixels.DragonECS
|
|||||||
entityID = self.World.NewEntity();
|
entityID = self.World.NewEntity();
|
||||||
return ref self.Add(entityID);
|
return ref self.Add(entityID);
|
||||||
}
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static ref T NewEntityLong<T>(this IEcsStructPool<T> self, out entlong entity) where T : struct
|
||||||
|
{
|
||||||
|
entity = self.World.NewEntityLong();
|
||||||
|
return ref self.Add(entity.GetIDUnchecked());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "Tag component or component without data.")]
|
[MetaDescription(EcsConsts.AUTHOR, "Tag component or component without data.")]
|
||||||
[MetaID("8D3E547C92013C6A2C2DFC8D2F1FA297")]
|
[MetaID("DragonECS_8D3E547C92013C6A2C2DFC8D2F1FA297")]
|
||||||
public interface IEcsTagComponent : IEcsMember { }
|
public interface IEcsTagComponent : IEcsComponentMember { }
|
||||||
|
|
||||||
/// <summary> Pool for IEcsTagComponent components. </summary>
|
/// <summary> Pool for IEcsTagComponent components. </summary>
|
||||||
#if ENABLE_IL2CPP
|
#if ENABLE_IL2CPP
|
||||||
@ -30,7 +30,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)]
|
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "Pool for IEcsTagComponent components. EcsTagPool is optimized for storing tag components or components without data.")]
|
[MetaDescription(EcsConsts.AUTHOR, "Pool for IEcsTagComponent components. EcsTagPool is optimized for storing tag components or components without data.")]
|
||||||
[MetaID("9D80547C9201E852E4F17324EAC1E15A")]
|
[MetaID("DragonECS_9D80547C9201E852E4F17324EAC1E15A")]
|
||||||
[DebuggerDisplay("Count: {Count} Type: {ComponentType}")]
|
[DebuggerDisplay("Count: {Count} Type: {ComponentType}")]
|
||||||
public sealed class EcsTagPool<T> : IEcsPoolImplementation<T>, IEcsStructPool<T>, IEnumerable<T> //IEnumerable<T> - IntelliSense hack
|
public sealed class EcsTagPool<T> : IEcsPoolImplementation<T>, IEcsStructPool<T>, IEnumerable<T> //IEnumerable<T> - IntelliSense hack
|
||||||
where T : struct, IEcsTagComponent
|
where T : struct, IEcsTagComponent
|
||||||
@ -104,10 +104,11 @@ namespace DCFApixels.DragonECS
|
|||||||
public void Add(int entityID)
|
public void Add(int entityID)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
if (_source.IsUsed(entityID) == false) { Throw.Ent_ThrowIsNotAlive(_source, entityID); }
|
||||||
if (Has(entityID)) { EcsPoolThrowHelper.ThrowAlreadyHasComponent<T>(entityID); }
|
if (Has(entityID)) { EcsPoolThrowHelper.ThrowAlreadyHasComponent<T>(entityID); }
|
||||||
if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); }
|
if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); }
|
||||||
#elif DRAGONECS_STABILITY_MODE
|
#elif DRAGONECS_STABILITY_MODE
|
||||||
if (Has(entityID) || _isLocked) { return; }
|
if (Has(entityID) | _source.IsUsed(entityID) == false | _isLocked) { return; }
|
||||||
#endif
|
#endif
|
||||||
_count++;
|
_count++;
|
||||||
_mapping[entityID] = true;
|
_mapping[entityID] = true;
|
||||||
@ -311,12 +312,99 @@ namespace DCFApixels.DragonECS
|
|||||||
IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); }
|
IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region MarkersConverter
|
#region Convertors
|
||||||
public static implicit operator EcsTagPool<T>(IncludeMarker a) { return a.GetInstance<EcsTagPool<T>>(); }
|
public static implicit operator EcsTagPool<T>(IncludeMarker a) { return a.GetInstance<EcsTagPool<T>>(); }
|
||||||
public static implicit operator EcsTagPool<T>(ExcludeMarker a) { return a.GetInstance<EcsTagPool<T>>(); }
|
public static implicit operator EcsTagPool<T>(ExcludeMarker a) { return a.GetInstance<EcsTagPool<T>>(); }
|
||||||
public static implicit operator EcsTagPool<T>(OptionalMarker a) { return a.GetInstance<EcsTagPool<T>>(); }
|
public static implicit operator EcsTagPool<T>(OptionalMarker a) { return a.GetInstance<EcsTagPool<T>>(); }
|
||||||
public static implicit operator EcsTagPool<T>(EcsWorld.GetPoolInstanceMarker a) { return a.GetInstance<EcsTagPool<T>>(); }
|
public static implicit operator EcsTagPool<T>(EcsWorld.GetPoolInstanceMarker a) { return a.GetInstance<EcsTagPool<T>>(); }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Apply
|
||||||
|
public static void Apply(ref T component, int entityID, short worldID)
|
||||||
|
{
|
||||||
|
EcsWorld.GetPoolInstance<EcsTagPool<T>>(worldID).TryAdd(entityID);
|
||||||
|
}
|
||||||
|
public static void Apply(ref T component, int entityID, EcsTagPool<T> pool)
|
||||||
|
{
|
||||||
|
pool.TryAdd(entityID);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ENABLE_IL2CPP
|
||||||
|
[Il2CppSetOption(Option.NullChecks, false)]
|
||||||
|
#endif
|
||||||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
|
public readonly struct ReadonlyEcsTagPool<T> : IEcsReadonlyPool //IEnumerable<T> - IntelliSense hack
|
||||||
|
where T : struct, IEcsTagComponent
|
||||||
|
{
|
||||||
|
private readonly EcsTagPool<T> _pool;
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
public int ComponentTypeID
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return _pool.ComponentTypeID; }
|
||||||
|
}
|
||||||
|
public Type ComponentType
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return _pool.ComponentType; }
|
||||||
|
}
|
||||||
|
public EcsWorld World
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return _pool.World; }
|
||||||
|
}
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return _pool.Count; }
|
||||||
|
}
|
||||||
|
public bool IsReadOnly
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return _pool.IsReadOnly; }
|
||||||
|
}
|
||||||
|
public bool this[int entityID]
|
||||||
|
{
|
||||||
|
get { return _pool.Has(entityID); }
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
internal ReadonlyEcsTagPool(EcsTagPool<T> pool)
|
||||||
|
{
|
||||||
|
_pool = pool;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool Has(int entityID) { return _pool.Has(entityID); }
|
||||||
|
object IEcsReadonlyPool.GetRaw(int entityID)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
if (Has(entityID) == false) { EcsPoolThrowHelper.ThrowNotHaveComponent<T>(entityID); }
|
||||||
|
#endif
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !DRAGONECS_DISABLE_POOLS_EVENTS
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void AddListener(IEcsPoolEventListener listener) { _pool.AddListener(listener); }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void RemoveListener(IEcsPoolEventListener listener) { _pool.AddListener(listener); }
|
||||||
|
#endif
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Convertors
|
||||||
|
public static implicit operator ReadonlyEcsTagPool<T>(EcsTagPool<T> a) { return new ReadonlyEcsTagPool<T>(a); }
|
||||||
|
public static implicit operator ReadonlyEcsTagPool<T>(IncludeMarker a) { return a.GetInstance<EcsTagPool<T>>(); }
|
||||||
|
public static implicit operator ReadonlyEcsTagPool<T>(ExcludeMarker a) { return a.GetInstance<EcsTagPool<T>>(); }
|
||||||
|
public static implicit operator ReadonlyEcsTagPool<T>(OptionalMarker a) { return a.GetInstance<EcsTagPool<T>>(); }
|
||||||
|
public static implicit operator ReadonlyEcsTagPool<T>(EcsWorld.GetPoolInstanceMarker a) { return a.GetInstance<EcsTagPool<T>>(); }
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EcsTagPoolExtensions
|
public static class EcsTagPoolExtensions
|
||||||
|
@ -13,7 +13,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaTags(MetaTags.HIDDEN)]
|
[MetaTags(MetaTags.HIDDEN)]
|
||||||
[MetaDescription(AUTHOR, "...")]
|
[MetaDescription(AUTHOR, "...")]
|
||||||
[MetaGroup(PACK_GROUP, OTHER_GROUP)]
|
[MetaGroup(PACK_GROUP, OTHER_GROUP)]
|
||||||
[MetaID("128D547C9201EEAC49B05F89E4A253DF")]
|
[MetaID("DragonECS_128D547C9201EEAC49B05F89E4A253DF")]
|
||||||
[MetaColor(MetaColor.DragonRose)]
|
[MetaColor(MetaColor.DragonRose)]
|
||||||
public class EcsPipelineTemplate : IEcsModule
|
public class EcsPipelineTemplate : IEcsModule
|
||||||
{
|
{
|
||||||
|
@ -118,6 +118,11 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
throw new InvalidOperationException($"The method {methodName} can only be executed before creating entities in the world.");
|
throw new InvalidOperationException($"The method {methodName} can only be executed before creating entities in the world.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
internal static void Ent_ThrowIsNotAlive(EcsWorld world, int entityID)
|
||||||
|
{
|
||||||
|
Ent_ThrowIsNotAlive((world, entityID));
|
||||||
|
}
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
internal static void Ent_ThrowIsNotAlive(entlong entity)
|
internal static void Ent_ThrowIsNotAlive(entlong entity)
|
||||||
{
|
{
|
||||||
|
@ -20,6 +20,20 @@ namespace DCFApixels.DragonECS
|
|||||||
self.Apply(worldID, entityID);
|
self.Apply(worldID, entityID);
|
||||||
return (EcsWorld.GetWorld(worldID), entityID);
|
return (EcsWorld.GetWorld(worldID), entityID);
|
||||||
}
|
}
|
||||||
|
public static void Apply(this ITemplateNode self, EcsWorld world, int entityID)
|
||||||
|
{
|
||||||
|
self.Apply(world.ID, entityID);
|
||||||
|
}
|
||||||
|
public static int ApplyAndReturn(this ITemplateNode self, EcsWorld world, int entityID)
|
||||||
|
{
|
||||||
|
self.Apply(world.ID, entityID);
|
||||||
|
return entityID;
|
||||||
|
}
|
||||||
|
public static entlong ApplyAndReturnLong(this ITemplateNode self, EcsWorld world, int entityID)
|
||||||
|
{
|
||||||
|
self.Apply(world.ID, entityID);
|
||||||
|
return (world, entityID);
|
||||||
|
}
|
||||||
public static int NewEntity(this EcsWorld world, ITemplateNode template)
|
public static int NewEntity(this EcsWorld world, ITemplateNode template)
|
||||||
{
|
{
|
||||||
int e = world.NewEntity();
|
int e = world.NewEntity();
|
||||||
|
@ -147,6 +147,20 @@ namespace DCFApixels.DragonECS
|
|||||||
return IsAlive;
|
return IsAlive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void Unpack(out int id)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
if (IsAlive == false) { Throw.Ent_ThrowIsNotAlive(this); }
|
||||||
|
#elif DRAGONECS_STABILITY_MODE
|
||||||
|
if (IsAlive == false)
|
||||||
|
{
|
||||||
|
id = EcsConsts.NULL_ENTITY_ID;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
id = _id;
|
||||||
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Unpack(out int id, out EcsWorld world)
|
public void Unpack(out int id, out EcsWorld world)
|
||||||
{
|
{
|
||||||
@ -216,6 +230,12 @@ namespace DCFApixels.DragonECS
|
|||||||
id = _id;
|
id = _id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool TryUnpack(out int id)
|
||||||
|
{
|
||||||
|
id = _id;
|
||||||
|
return IsAlive;
|
||||||
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool TryUnpack(out int id, out EcsWorld world)
|
public bool TryUnpack(out int id, out EcsWorld world)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user