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; /// /// 类型键缓存:Sentry 类型 → (EventType, EventSubType) /// 用于按钮快速获取类型键,避免重复反射 /// private static readonly Dictionary 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(); 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)); } /// /// 获取 Sentry 类型的类型键(从缓存中读取,无反射开销) /// public static (int EventType, int EventSubType)? GetTypeKey(Type sentryType) { return TypeKeyCache.GetValueOrDefault(sentryType); } } }