|
- 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<T> 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<MethodInfo> EntityStream =
- new(() => AccessTools.PropertyGetter(typeof(EntitiesDB), "_entityStream"));
-
- public static readonly Lazy<FieldInfo> Streams = new(() =>
- AccessTools.Field(EntityStream.Value.ReturnType, "_streams"));
-
- public static readonly Lazy<FieldInfo> Consumers = new(() =>
- AccessTools.Field(typeof(EntityStream<T>), "_consumers"));
-
- public static readonly Lazy<MethodInfo> TryGetValue =
- new(AccessTools.Method(Streams.Value.FieldType, "TryGetValue"));
-
- public static readonly Lazy<FieldInfo> RingBuffer =
- new(() => AccessTools.Field(typeof(Consumer<T>), "_ringBuffer"));
- }
-
- private static EntityStream<T> GetEntityStream<T>(this EntitiesDB entitiesDB) where T : unmanaged, IEntityComponent
- {
- // EntitiesStreams (internal)
- var entitiesStreams = EntitiesDBHelper<T>.EntityStream.Value.Invoke(entitiesDB, Array.Empty<object>());
- // FasterDictionary<RefWrapperType, ITypeSafeStream> (interface is internal)
- var streams = EntitiesDBHelper<T>.Streams.Value.GetValue(entitiesStreams);
-
- var parameters = new object[] { TypeRefWrapper<T>.wrapper, null };
- var success = EntitiesDBHelper<T>.TryGetValue.Value.Invoke(streams, parameters);
- if (!(bool)success)
- return null; // There is no entity stream for this type
- return (EntityStream<T>)parameters[1];
- }
-
- private static ThreadSafeFasterList<Consumer<T>> GetConsumers<T>(this EntityStream<T> stream) where T : unmanaged, IEntityComponent
- {
- return (ThreadSafeFasterList<Consumer<T>>)EntitiesDBHelper<T>.Consumers.Value.GetValue(stream);
- }
-
- private static RingBuffer<(T, EGID)> GetRingBuffer<T>(this Consumer<T> consumer) where T : unmanaged, IEntityComponent
- {
- return (RingBuffer<(T, EGID)>)EntitiesDBHelper<T>.RingBuffer.Value.GetValue(consumer);
- }
- }
- }
|