refactoring

This commit is contained in:
Mikhail 2023-05-26 04:25:09 +08:00
parent caef8d8bae
commit ddb1eb1491
4 changed files with 52 additions and 65 deletions

View File

@ -5,11 +5,14 @@ namespace DCFApixels.DragonECS
{ {
public static class EcsDebugUtility public static class EcsDebugUtility
{ {
public static string GetGenericTypeFullName<T>(int maxDepth = 2) => GetGenericTypeFullName(typeof(T), maxDepth);
public static string GetGenericTypeFullName(Type type, int maxDepth = 2) => GetGenericTypeNameInternal(type, maxDepth, true);
public static string GetGenericTypeName<T>(int maxDepth = 2) => GetGenericTypeName(typeof(T), maxDepth); public static string GetGenericTypeName<T>(int maxDepth = 2) => GetGenericTypeName(typeof(T), maxDepth);
public static string GetGenericTypeName(Type type, int maxDepth = 2) public static string GetGenericTypeName(Type type, int maxDepth = 2) => GetGenericTypeNameInternal(type, maxDepth, false);
private static string GetGenericTypeNameInternal(Type type, int maxDepth, bool isFull)
{ {
#if (DEBUG && !DISABLE_DEBUG) #if (DEBUG && !DISABLE_DEBUG)
string friendlyName = type.Name; string friendlyName = isFull ? type.FullName : type.Name;
if (!type.IsGenericType || maxDepth == 0) if (!type.IsGenericType || maxDepth == 0)
return friendlyName; return friendlyName;
@ -21,7 +24,7 @@ namespace DCFApixels.DragonECS
Type[] typeParameters = type.GetGenericArguments(); Type[] typeParameters = type.GetGenericArguments();
for (int i = 0; i < typeParameters.Length; ++i) for (int i = 0; i < typeParameters.Length; ++i)
{ {
string typeParamName = GetGenericTypeName(typeParameters[i], maxDepth - 1); string typeParamName = GetGenericTypeNameInternal(typeParameters[i], maxDepth - 1, false);//чтобы строка не была слишком длинной, используются сокращенные имена для типов аргументов
friendlyName += (i == 0 ? typeParamName : "," + typeParamName); friendlyName += (i == 0 ? typeParamName : "," + typeParamName);
} }
friendlyName += ">"; friendlyName += ">";

View File

@ -1,13 +1,12 @@
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
using static DCFApixels.DragonECS.EcsGroup.ThrowHalper;
#endif
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
using static EcsGroup.ThrowHalper;
#endif
[StructLayout(LayoutKind.Sequential, Pack = 0, Size = 8)] [StructLayout(LayoutKind.Sequential, Pack = 0, Size = 8)]
public readonly ref struct EcsReadonlyGroup public readonly ref struct EcsReadonlyGroup
{ {

View File

@ -5,6 +5,7 @@ using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using static DCFApixels.DragonECS.EcsDebugUtility;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
@ -31,21 +32,19 @@ namespace DCFApixels.DragonECS
[EditorBrowsable(EditorBrowsableState.Never)] [EditorBrowsable(EditorBrowsableState.Never)]
public interface IEcsRunner public interface IEcsRunner
{ {
public EcsPipeline Source { get; } EcsPipeline Source { get; }
public Type Interface { get; } Type Interface { get; }
public IList Targets { get; } IList Targets { get; }
public object Filter { get; } object Filter { get; }
public bool IsHasFilter { get; } bool IsHasFilter { get; }
public bool IsDestroyed { get; } bool IsDestroyed { get; }
public bool IsEmpty { get; } bool IsEmpty { get; }
void Destroy();
public void Destroy();
} }
internal static class EcsRunnerActivator internal static class EcsRunnerActivator
{ {
private static Dictionary<Type, Type> _runnerHandlerTypes; //interface base type/Runner handler type pairs; private static Dictionary<Type, Type> _runnerHandlerTypes; //interface base type/Runner handler type pairs;
static EcsRunnerActivator() static EcsRunnerActivator()
{ {
List<Exception> delayedExceptions = new List<Exception>(); List<Exception> delayedExceptions = new List<Exception>();
@ -73,10 +72,8 @@ namespace DCFApixels.DragonECS
foreach (var item in runnerHandlerTypes) foreach (var item in runnerHandlerTypes)
{ {
Type interfaceType = item.BaseType.GenericTypeArguments[0]; Type interfaceType = item.BaseType.GenericTypeArguments[0];
// if(!_runnerHandlerTypes.ContainsKey(interfaceType.GUID))//TODO это кажется костыль, изначально все работало без этого ифа
_runnerHandlerTypes.Add(interfaceType.IsGenericType ? interfaceType.GetGenericTypeDefinition() : interfaceType, item); _runnerHandlerTypes.Add(interfaceType.IsGenericType ? interfaceType.GetGenericTypeDefinition() : interfaceType, item);
} }
if (delayedExceptions.Count > 0) if (delayedExceptions.Count > 0)
{ {
foreach (var item in delayedExceptions) EcsDebug.Print(EcsConsts.DEBUG_ERROR_TAG, item.Message); foreach (var item in delayedExceptions) EcsDebug.Print(EcsConsts.DEBUG_ERROR_TAG, item.Message);
@ -91,24 +88,23 @@ namespace DCFApixels.DragonECS
if (type.ReflectedType != null) if (type.ReflectedType != null)
{ {
return new EcsRunnerImplementationException($"{type.FullName}.ReflectedType must be Null, but equal to {type.ReflectedType.FullName}."); return new EcsRunnerImplementationException($"{GetGenericTypeFullName(type, 1)}.ReflectedType must be Null, but equal to {GetGenericTypeFullName(type.ReflectedType, 1)}.");
} }
if (!baseTypeArgument.IsInterface) if (!baseTypeArgument.IsInterface)
{ {
return new EcsRunnerImplementationException($"Argument T of class EcsRunner<T>, can only be an inetrface.The {baseTypeArgument.FullName} type is not an interface."); return new EcsRunnerImplementationException($"Argument T of class EcsRunner<T>, can only be an inetrface. The {GetGenericTypeFullName(baseTypeArgument, 1)} type is not an interface.");
} }
var interfaces = type.GetInterfaces(); var interfaces = type.GetInterfaces();
if (!interfaces.Any(o => o == baseTypeArgument)) if (!interfaces.Any(o => o == baseTypeArgument))
{ {
return new EcsRunnerImplementationException($"Runner {type.FullName} does not implement interface {baseTypeArgument.FullName}."); return new EcsRunnerImplementationException($"Runner {GetGenericTypeFullName(type, 1)} does not implement interface {GetGenericTypeFullName(baseTypeArgument, 1)}.");
} }
return null; return null;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void InitFor<TInterface>() where TInterface : IEcsSystem internal static void InitFor<TInterface>() where TInterface : IEcsSystem
{ {
@ -116,7 +112,7 @@ namespace DCFApixels.DragonECS
if (!_runnerHandlerTypes.TryGetValue(interfaceType.IsGenericType ? interfaceType.GetGenericTypeDefinition() : interfaceType, out Type runnerType)) if (!_runnerHandlerTypes.TryGetValue(interfaceType.IsGenericType ? interfaceType.GetGenericTypeDefinition() : interfaceType, out Type runnerType))
{ {
throw new Exception(); throw new EcsRunnerImplementationException($"There is no implementation of a runner for the {GetGenericTypeFullName<TInterface>(1)} interface.");
} }
if (interfaceType.IsGenericType) if (interfaceType.IsGenericType)
{ {
@ -192,9 +188,7 @@ namespace DCFApixels.DragonECS
#region Instantiate #region Instantiate
private static TInterface Instantiate(EcsPipeline source, TInterface[] targets, bool isHasFilter, object filter) private static TInterface Instantiate(EcsPipeline source, TInterface[] targets, bool isHasFilter, object filter)
{ {
if (_subclass == null) if (_subclass == null) EcsRunnerActivator.InitFor<TInterface>();
EcsRunnerActivator.InitFor<TInterface>();
var instance = (EcsRunner<TInterface>)Activator.CreateInstance(_subclass); var instance = (EcsRunner<TInterface>)Activator.CreateInstance(_subclass);
return (TInterface)(IEcsSystem)instance.Set(source, targets, isHasFilter, filter); return (TInterface)(IEcsSystem)instance.Set(source, targets, isHasFilter, filter);
} }
@ -235,7 +229,6 @@ namespace DCFApixels.DragonECS
OnSetup(); OnSetup();
return this; return this;
} }
internal void Rebuild() internal void Rebuild()
{ {
if (_isHasFilter) if (_isHasFilter)
@ -243,7 +236,6 @@ namespace DCFApixels.DragonECS
else else
Set(_source, FilterSystems(_source.AllSystems, _filter), _isHasFilter, _filter); Set(_source, FilterSystems(_source.AllSystems, _filter), _isHasFilter, _filter);
} }
public void Destroy() public void Destroy()
{ {
_isDestroyed = true; _isDestroyed = true;
@ -254,11 +246,11 @@ namespace DCFApixels.DragonECS
_filter = null; _filter = null;
OnDestroy(); OnDestroy();
} }
protected virtual void OnSetup() { } protected virtual void OnSetup() { }
protected virtual void OnDestroy() { } protected virtual void OnDestroy() { }
} }
} }
#region Extensions #region Extensions
public static class EcsRunner public static class EcsRunner
{ {

View File

@ -1,4 +1,5 @@
using System; #pragma warning disable IDE1006
using System;
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -6,9 +7,7 @@ using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
using static entlong.ThrowHalper; using static entlong.ThrowHalper;
// uniqueID - 32 bits // [ id 32 | gen 16 | world 16 ]
// gen - 16 bits
// world - 16 bits
/// <summary>Strong identifier/Permanent entity identifier</summary> /// <summary>Strong identifier/Permanent entity identifier</summary>
[StructLayout(LayoutKind.Explicit, Pack = 2, Size = 8)] [StructLayout(LayoutKind.Explicit, Pack = 2, Size = 8)]
public readonly struct entlong : IEquatable<long>, IEquatable<entlong> public readonly struct entlong : IEquatable<long>, IEquatable<entlong>
@ -34,12 +33,6 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => this == NULL; get => this == NULL;
} }
[EditorBrowsable(EditorBrowsableState.Never)]
public bool IsNotNull
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => this != NULL;
}
[EditorBrowsable(EditorBrowsableState.Never)] [EditorBrowsable(EditorBrowsableState.Never)]
public int ID public int ID
@ -135,7 +128,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode() => unchecked((int)full) ^ (int)(full >> 32); public override int GetHashCode() => unchecked((int)full) ^ (int)(full >> 32);
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override string ToString() => $"entity(id:{id} g:{gen} w:{world} {(IsAlive ? "alive" : "not alive")})"; public override string ToString() => $"entity(id:{id} g:{gen} w:{world} {(IsNull ? "null" : IsAlive ? "alive" : "not alive")})";
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(object obj) => obj is entlong other && full == other.full; public override bool Equals(object obj) => obj is entlong other && full == other.full;
#endregion #endregion
@ -159,9 +152,9 @@ namespace DCFApixels.DragonECS
public static void ThrowIsNotAlive(entlong entity) public static void ThrowIsNotAlive(entlong entity)
{ {
if (entity.IsNull) if (entity.IsNull)
throw new EcsFrameworkException("The entity identifier is null."); throw new EcsFrameworkException($"The {entity} is null.");
else else
throw new EcsFrameworkException("The entity is not alive."); throw new EcsFrameworkException($"The {entity} is not alive.");
} }
} }
#endregion #endregion