85 lines
3.1 KiB
C#
85 lines
3.1 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Reflection;
|
||
using asap.core;
|
||
using cfg;
|
||
using UnityEngine;
|
||
|
||
namespace Activity
|
||
{
|
||
public class ActivitySentryManager
|
||
{
|
||
private static Dictionary<(int, int), Type> _activitySentryTypes;
|
||
|
||
/// <summary>
|
||
/// 类型键缓存:Sentry 类型 → (EventType, EventSubType)
|
||
/// 用于按钮快速获取类型键,避免重复反射
|
||
/// </summary>
|
||
private static readonly Dictionary<Type, (int EventType, int EventSubType)> TypeKeyCache = new();
|
||
|
||
private static Dictionary<(int, int), Type> ActivitySentryTypes
|
||
{
|
||
get
|
||
{
|
||
if (_activitySentryTypes != null) return _activitySentryTypes;
|
||
InitActivitySentryTypes();
|
||
|
||
return _activitySentryTypes;
|
||
}
|
||
}
|
||
|
||
private static void InitActivitySentryTypes()
|
||
{
|
||
try
|
||
{
|
||
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
|
||
InitActivitySentryType(type);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError($"[ActivitySentryManager] Fatal error during Sentry type initialization: {e.Message}\n{e.StackTrace}");
|
||
}
|
||
}
|
||
public static void InitActivitySentryType(Type type)
|
||
{
|
||
_activitySentryTypes ??= new Dictionary<(int, int), Type>();
|
||
try
|
||
{
|
||
var res = typeof(IActivitySentry).IsAssignableFrom(type) && type.IsClass;
|
||
if (!res) return;
|
||
var attribute = type.GetCustomAttribute<ActivitySentryAttribute>();
|
||
if (attribute == null) return;
|
||
|
||
var key = (attribute.EventType, attribute.EventSubType);
|
||
if (_activitySentryTypes.TryGetValue(key, out var sentryType))
|
||
{
|
||
Debug.LogWarning( $"[ActivitySentryManager] Duplicate Sentry registration for EventType={attribute.EventType}, EventSubType={attribute.EventSubType}. Existing: {sentryType.Name}, New: {type.Name}");
|
||
return;
|
||
}
|
||
|
||
_activitySentryTypes.Add(key, type);
|
||
|
||
// 缓存类型键,避免按钮注册时重复反射
|
||
TypeKeyCache[type] = key;
|
||
|
||
GContext.container.Register(typeof(IActivitySentry), type.Name, type).PerScope();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError($"[ActivitySentryManager] Error processing type {type.Name}: {e.Message}");
|
||
}
|
||
}
|
||
public static Type GetActivitySentryType(FishingEvent fishingEvent)
|
||
{
|
||
return ActivitySentryTypes.GetValueOrDefault((fishingEvent.Type, fishingEvent.SubType));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取 Sentry 类型的类型键(从缓存中读取,无反射开销)
|
||
/// </summary>
|
||
public static (int EventType, int EventSubType)? GetTypeKey(Type sentryType)
|
||
{
|
||
return TypeKeyCache.GetValueOrDefault(sentryType);
|
||
}
|
||
}
|
||
} |