6
StarHorizon_Public/Content.Server/_Horizon/SubscribeExtensions.cs
2025-11-03 10:15:18 +03:00

66 lines
2.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Starlight sys
using System.Linq;
using System.Reflection;
using Robust.Shared.Reflection;
namespace Content.Server._Horizon;
public static class SubscribeExtensions
{
private static MethodInfo? s_subscribeMethodRefHandler;
// The load from this reflection is negligible.
// It would make sense to redo everything like this,
// but we dont have multiple subscriptions—needs more thought
public static void SubscribeAllComponents<TInterface, TEvent>(
this EntitySystem system,
IReflectionManager reflection,
MethodInfo eventHandler,
Type[]? before = null,
Type[]? after = null
)
where TEvent : notnull
{
if (s_subscribeMethodRefHandler == null)
{
s_subscribeMethodRefHandler = typeof(EntitySystem)
.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
.Where(m => m.Name == "SubscribeLocalEvent"
&& m.IsGenericMethodDefinition
&& m.GetParameters().Length > 0
&& m.GetParameters()[0].ParameterType.IsGenericType
&& m.GetParameters()[0].ParameterType
.GetGenericTypeDefinition() == typeof(EntityEventRefHandler<,>)
)
.FirstOrDefault();
if (s_subscribeMethodRefHandler == null)
throw new InvalidOperationException("SubscribeLocalEvent<TComp,TEvent>(EntityEventRefHandler<TComp,TEvent> not found");
}
var compTypes = reflection.GetAllChildren<TInterface>();
foreach (var compType in compTypes)
{
if (!typeof(IComponent).IsAssignableFrom(compType))
continue;
var closedSubscribe = s_subscribeMethodRefHandler
.MakeGenericMethod(compType, typeof(TEvent));
var closedHandler = eventHandler
.MakeGenericMethod(compType);
var delegateType = typeof(EntityEventRefHandler<,>)
.MakeGenericType(compType, typeof(TEvent));
var handlerDelegate = Delegate
.CreateDelegate(delegateType, system, closedHandler);
closedSubscribe.Invoke(
system,
[handlerDelegate, before, after]
);
}
}
}