using System; using System.Linq; using System.Runtime.CompilerServices; using static DCFApixels.DragonECS.Internal.DataInterfaceHalper; namespace DCFApixels.DragonECS.Internal { #region DataInterfaceHalper public static class DataInterfaceHalper { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void CheckFakeInstanceValide(T fakeInstnace) { #if DEBUG if (fakeInstnace.Equals(default) == false) { throw new Exception("Не правильное применение интерфейса, менять нужно передаваемое по ref значение"); } #endif } } #endregion } namespace DCFApixels.DragonECS { #region IEcsWorldComponent public interface IEcsWorldComponent { void Init(ref T component, EcsWorld world); void OnDestroy(ref T component, EcsWorld world); } public static class EcsWorldComponentHandler { public static readonly IEcsWorldComponent instance; public static readonly bool isHasHandler; static EcsWorldComponentHandler() { Type targetType = typeof(T); isHasHandler = targetType.GetInterfaces().Contains(typeof(IEcsWorldComponent<>).MakeGenericType(targetType)); if (isHasHandler) { instance = (IEcsWorldComponent)Activator.CreateInstance(typeof(WorldComponentHandler<>).MakeGenericType(targetType)); } else { instance = new DummyHandler(); } } private class DummyHandler : IEcsWorldComponent { [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Init(ref T component, EcsWorld world) { } public void OnDestroy(ref T component, EcsWorld world) { } } } internal sealed class WorldComponentHandler : IEcsWorldComponent where T : struct, IEcsWorldComponent { private T _fakeInstnace = default; [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Init(ref T component, EcsWorld world) { _fakeInstnace.Init(ref component, world); CheckFakeInstanceValide(_fakeInstnace); } public void OnDestroy(ref T component, EcsWorld world) { _fakeInstnace.OnDestroy(ref component, world); CheckFakeInstanceValide(_fakeInstnace); } } #endregion #region IEcsComponentReset public interface IEcsComponentReset { void Reset(ref T component); } public static class EcsComponentResetHandler { public static readonly IEcsComponentReset instance; public static readonly bool isHasHandler; static EcsComponentResetHandler() { Type targetType = typeof(T); isHasHandler = targetType.GetInterfaces().Contains(typeof(IEcsComponentReset<>).MakeGenericType(targetType)); if (isHasHandler) { instance = (IEcsComponentReset)Activator.CreateInstance(typeof(ComponentResetHandler<>).MakeGenericType(targetType)); } else { instance = new DummyHandler(); } } private sealed class DummyHandler : IEcsComponentReset { [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Reset(ref T component) => component = default; } } internal sealed class ComponentResetHandler : IEcsComponentReset where T : IEcsComponentReset { private T _fakeInstnace = default; [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Reset(ref T component) { _fakeInstnace.Reset(ref component); CheckFakeInstanceValide(_fakeInstnace); } } #endregion #region IEcsComponentCopy public interface IEcsComponentCopy { void Copy(ref T from, ref T to); } public static class EcsComponentCopyHandler { public static readonly IEcsComponentCopy instance; public static readonly bool isHasHandler; static EcsComponentCopyHandler() { Type targetType = typeof(T); isHasHandler = targetType.GetInterfaces().Contains(typeof(IEcsComponentCopy<>).MakeGenericType(targetType)); if (isHasHandler) { instance = (IEcsComponentCopy)Activator.CreateInstance(typeof(ComponentCopyHandler<>).MakeGenericType(targetType)); } else { instance = new DummyHandler(); } } private sealed class DummyHandler : IEcsComponentCopy { [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Copy(ref T from, ref T to) => to = from; } } internal sealed class ComponentCopyHandler : IEcsComponentCopy where T : IEcsComponentCopy { private T _fakeInstnace = default; [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Copy(ref T from, ref T to) { _fakeInstnace.Copy(ref from, ref to); CheckFakeInstanceValide(_fakeInstnace); } } #endregion }