using System; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using HarmonyLib; using Svelto.DataStructures; using Svelto.ECS; namespace TechbloxModdingAPI.Utility.ECS { public static partial class NativeApiExtensions { [SuppressMessage("ReSharper", "StaticMemberInGenericType")] private static class EntitiesDBHelper where T : unmanaged, IEntityComponent { // Each type gets a new set of fields here (that's what the ReSharper warning is about too) public static readonly Lazy EntityStream = new(() => AccessTools.PropertyGetter(typeof(EntitiesDB), "_entityStream")); public static readonly Lazy Streams = new(() => AccessTools.Field(EntityStream.Value.ReturnType, "_streams")); public static readonly Lazy Consumers = new(() => AccessTools.Field(typeof(EntityStream), "_consumers")); public static readonly Lazy TryGetValue = new(AccessTools.Method(Streams.Value.FieldType, "TryGetValue")); public static readonly Lazy RingBuffer = new(() => AccessTools.Field(typeof(Consumer), "_ringBuffer")); } private static EntityStream GetEntityStream(this EntitiesDB entitiesDB) where T : unmanaged, IEntityComponent { // EntitiesStreams (internal) var entitiesStreams = EntitiesDBHelper.EntityStream.Value.Invoke(entitiesDB, Array.Empty()); // FasterDictionary (interface is internal) var streams = EntitiesDBHelper.Streams.Value.GetValue(entitiesStreams); var parameters = new object[] { TypeRefWrapper.wrapper, null }; var success = EntitiesDBHelper.TryGetValue.Value.Invoke(streams, parameters); if (!(bool)success) return null; // There is no entity stream for this type return (EntityStream)parameters[1]; } private static ThreadSafeFasterList> GetConsumers(this EntityStream stream) where T : unmanaged, IEntityComponent { return (ThreadSafeFasterList>)EntitiesDBHelper.Consumers.Value.GetValue(stream); } private static RingBuffer<(T, EGID)> GetRingBuffer(this Consumer consumer) where T : unmanaged, IEntityComponent { return (RingBuffer<(T, EGID)>)EntitiesDBHelper.RingBuffer.Value.GetValue(consumer); } } }