diff --git a/CodeGen/Editor/EventBusILPostProcessor.cs b/CodeGen/Editor/EventBusILPostProcessor.cs index c6b86a7..a0fb6bd 100644 --- a/CodeGen/Editor/EventBusILPostProcessor.cs +++ b/CodeGen/Editor/EventBusILPostProcessor.cs @@ -11,18 +11,17 @@ namespace ShrinkEventBus.CodeGen { public class EventBusILPostProcessor : ILPostProcessor { - private readonly List _diagnostics = new(); private PostProcessorAssemblyResolver _assemblyResolver; private MethodReference _autoRegisterMethodRef; + private MethodReference _unregisterInstanceMethodRef; public override ILPostProcessor GetInstance() => this; public override bool WillProcess(ICompiledAssembly compiledAssembly) { - var result = compiledAssembly.References.Any( + return compiledAssembly.References.Any( r => Path.GetFileNameWithoutExtension(r) == "ShrinkEventBus.Runtime"); - return result; } public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly) @@ -41,6 +40,7 @@ namespace ShrinkEventBus.CodeGen if (!InheritsFromMonoBehaviour(type)) continue; InjectAutoRegister(type, mainModule); + InjectAutoUnregister(type, mainModule); } return GetResult(assemblyDefinition, _diagnostics); @@ -60,14 +60,36 @@ namespace ShrinkEventBus.CodeGen } var processor = awake.Body.GetILProcessor(); - var instructions = new List { processor.Create(OpCodes.Ldarg_0), processor.Create(OpCodes.Call, _autoRegisterMethodRef), processor.Create(OpCodes.Nop) }; + instructions.Reverse(); + instructions.ForEach(i => processor.Body.Instructions.Insert(0, i)); + } + private void InjectAutoUnregister(TypeDefinition type, ModuleDefinition module) + { + var onDestroy = type.Methods.FirstOrDefault(m => m.Name == "OnDestroy" && !m.IsStatic); + if (onDestroy == null) + { + onDestroy = new MethodDefinition("OnDestroy", + MethodAttributes.Private | MethodAttributes.HideBySig, + module.TypeSystem.Void); + var il = onDestroy.Body.GetILProcessor(); + il.Emit(OpCodes.Ret); + type.Methods.Add(onDestroy); + } + + var processor = onDestroy.Body.GetILProcessor(); + var instructions = new List + { + processor.Create(OpCodes.Ldarg_0), + processor.Create(OpCodes.Call, _unregisterInstanceMethodRef), + processor.Create(OpCodes.Nop) + }; instructions.Reverse(); instructions.ForEach(i => processor.Body.Instructions.Insert(0, i)); } @@ -75,12 +97,12 @@ namespace ShrinkEventBus.CodeGen private void ImportReferences(ModuleDefinition module) { var runtimeModule = FindRuntimeModule(module); - var eventBusType = runtimeModule.GetAllTypes() - .First(t => t.Name == "EventBus"); - var autoRegisterMethod = eventBusType.Methods - .First(m => m.Name == "AutoRegister"); + var eventBusType = runtimeModule.GetAllTypes().First(t => t.Name == "EventBus"); - _autoRegisterMethodRef = module.ImportReference(autoRegisterMethod); + _autoRegisterMethodRef = module.ImportReference( + eventBusType.Methods.First(m => m.Name == "AutoRegister")); + _unregisterInstanceMethodRef = module.ImportReference( + eventBusType.Methods.First(m => m.Name == "UnregisterInstance")); } private ModuleDefinition FindRuntimeModule(ModuleDefinition module) diff --git a/Runtime/EventAutoRegHelper.cs b/Runtime/EventAutoRegHelper.cs index 628548e..592a832 100644 --- a/Runtime/EventAutoRegHelper.cs +++ b/Runtime/EventAutoRegHelper.cs @@ -1,22 +1,12 @@ -using System; -using System.Collections.Concurrent; -using System.Reflection; -using UnityEngine; +using UnityEngine; namespace ShrinkEventBus { public static class EventAutoRegHelper { - private static readonly ConcurrentDictionary SubscriberTypes = new(); private static readonly object InitLock = new(); public static bool IsInitialized { get; private set; } - [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] - private static void PreInitializeReflection() - { - if (SubscriberTypes.Count == 0) ScanEventBusSubscribers(); - } - [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] private static void InitializeAfterSceneLoad() { @@ -29,108 +19,18 @@ namespace ShrinkEventBus lock (InitLock) { if (IsInitialized) return; - ScanEventBusSubscribers(); - ScanExistingObjects(); IsInitialized = true; } } - private static void ScanExistingObjects() - { - if (SubscriberTypes.Count == 0) - { -#if UNITY_2023_1_OR_NEWER - var allMonoBehaviours = - UnityEngine.Object.FindObjectsByType(UnityEngine.FindObjectsInactive.Include, - UnityEngine.FindObjectsSortMode.None); -#else - var allMonoBehaviours = UnityEngine.Object.FindObjectsOfType(true); -#endif - foreach (var mb in allMonoBehaviours) ProcessNodeRegistration(mb); - return; - } - - foreach (var targetType in SubscriberTypes.Keys) - { -#if UNITY_2023_1_OR_NEWER - var objects = UnityEngine.Object.FindObjectsByType(targetType, UnityEngine.FindObjectsInactive.Include, - UnityEngine.FindObjectsSortMode.None); -#else - var objects = UnityEngine.Object.FindObjectsOfType(targetType, true); -#endif - foreach (var obj in objects) ProcessNodeRegistration(obj); - } - } - - private static void ScanEventBusSubscribers() - { - if (SubscriberTypes.Count > 0) return; - var assemblies = AppDomain.CurrentDomain.GetAssemblies(); - foreach (var assembly in assemblies) - { - if (IsSystemAssembly(assembly)) continue; - try - { - foreach (var type in assembly.GetTypes()) - { - if (type.GetCustomAttribute() != null && - typeof(MonoBehaviour).IsAssignableFrom(type)) - SubscriberTypes.TryAdd(type, true); - } - } - catch (ReflectionTypeLoadException ex) - { - foreach (var type in ex.Types) - { - if (type?.GetCustomAttribute() != null && - typeof(MonoBehaviour).IsAssignableFrom(type)) - SubscriberTypes.TryAdd(type, true); - } - } - catch - { - // ignored - } - } - } - - private static bool IsSystemAssembly(Assembly assembly) - { - var name = assembly.FullName ?? ""; - return name.StartsWith("System.") || name.StartsWith("Microsoft.") || name.StartsWith("mscorlib") || - name.StartsWith("UnityEngine.") || name.StartsWith("UnityEditor."); - } - - private static bool ProcessNodeRegistration(object node) - { - if (node == null) return false; - var nodeType = node.GetType(); - - if (SubscriberTypes.Count == 0 && nodeType.GetCustomAttribute() != null) - SubscriberTypes.TryAdd(nodeType, true); - - if (!SubscriberTypes.ContainsKey(nodeType)) return false; - if (EventBus.IsInstanceRegistered(node)) return false; - - EventBus.AutoRegister(node); - return true; - } - - public static void UnregisterNode(object node) - { - if (node == null) return; - EventBus.UnregisterInstance(node); - } - - public static void ForceScanCurrentScene() => ScanExistingObjects(); - public static void Cleanup() { lock (InitLock) { - SubscriberTypes.Clear(); IsInitialized = false; } + + EventBus.UnregisterAllEvents(); } } } \ No newline at end of file diff --git a/Runtime/EventBus.cs b/Runtime/EventBus.cs index 4fee5c6..2e0103e 100644 --- a/Runtime/EventBus.cs +++ b/Runtime/EventBus.cs @@ -126,9 +126,7 @@ namespace ShrinkEventBus lock (EventHandlers) { if (EventHandlers.Remove(eventType)) - { EventCache.List = null; - } } } @@ -164,19 +162,6 @@ namespace ShrinkEventBus } UnregisterAllEventsForObject(targetObject); - if (targetObject is not MonoBehaviour mb || !mb) return; - try - { - if (!mb.gameObject || - !mb.gameObject.TryGetComponent(out var listener)) return; - if (listener) - { - UnityEngine.Object.Destroy(listener); - } - } - catch (MissingReferenceException) - { - } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -375,8 +360,8 @@ namespace ShrinkEventBus var eventType = typeof(TEvent); lock (EventHandlers) { - if (EventHandlers.TryGetValue(eventType, out var collection)) return collection; - return new ListenerList(); + EventHandlers.TryGetValue(eventType, out var collection); + return collection; } } @@ -384,7 +369,6 @@ namespace ShrinkEventBus public static void AutoRegister(object target) { if (target == null) return; - if (IsInstanceRegistered(target)) return; EventBusRegHelper.RegisterEventHandlers(target); @@ -393,16 +377,6 @@ namespace ShrinkEventBus { if (!RegisteredInstances.Add(target)) return; } - - if (target is MonoBehaviour mb && mb && mb.gameObject) - { - if (!mb.gameObject.TryGetComponent(out _)) - { - var listener = mb.gameObject.AddComponent(); - listener.Target = target; - listener.hideFlags = HideFlags.HideAndDontSave; - } - } } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Runtime/EventBusDestroyListener.cs b/Runtime/EventBusDestroyListener.cs deleted file mode 100644 index a0246bf..0000000 --- a/Runtime/EventBusDestroyListener.cs +++ /dev/null @@ -1,18 +0,0 @@ -using UnityEngine; - -namespace ShrinkEventBus -{ - [DisallowMultipleComponent] - public class EventBusDestroyListener : MonoBehaviour - { - public object Target { get; set; } - - private void OnDestroy() - { - if (Target != null) - { - EventBus.UnregisterInstance(Target); - } - } - } -} \ No newline at end of file diff --git a/Runtime/EventBusDestroyListener.cs.meta b/Runtime/EventBusDestroyListener.cs.meta deleted file mode 100644 index 1862c27..0000000 --- a/Runtime/EventBusDestroyListener.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 0fd1c9ba32a842199e4285383d83b3b3 -timeCreated: 1772889501 \ No newline at end of file diff --git a/Runtime/ListenerList.cs b/Runtime/ListenerList.cs index 7890de0..4823ffa 100644 --- a/Runtime/ListenerList.cs +++ b/Runtime/ListenerList.cs @@ -48,6 +48,7 @@ namespace ShrinkEventBus return true; } } + return false; } } @@ -65,6 +66,7 @@ namespace ShrinkEventBus removed = true; } } + if (removed) _dirty = true; } } @@ -78,13 +80,17 @@ namespace ShrinkEventBus _snapshot = _list.ToArray(); _dirty = false; } + return _snapshot; } } public int Count { - get { lock (_lock) return _list.Count; } + get + { + lock (_lock) return _list.Count; + } } public void Clear()