diff --git a/Assets/GameFramework/Runtime/EventSystem.meta b/Assets/GameFramework/Runtime/EventSystem.meta new file mode 100644 index 0000000..f88cbde --- /dev/null +++ b/Assets/GameFramework/Runtime/EventSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 26cf5e3096559174b90385ee2f3d88b0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameFramework/Runtime/EventSystem/EventBus.cs b/Assets/GameFramework/Runtime/EventSystem/EventBus.cs new file mode 100644 index 0000000..22ba67d --- /dev/null +++ b/Assets/GameFramework/Runtime/EventSystem/EventBus.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using System; +using UnityEngine; + +public static class EventBus +{ + + private static readonly Dictionary _eventHandlers = new Dictionary(); + private static readonly object _lock = new object(); + + public static void Register(IEventHandler handler) where TEvent : IEvent + { + lock (_lock) + { + Type eventType = typeof(TEvent); + if (!_eventHandlers.ContainsKey(eventType)) + { + _eventHandlers[eventType] = new List>(); + } + + var handlers = _eventHandlers[eventType] as List>; + if (handler != null && !handlers.Contains(handler)) + { + handlers.Add(handler); + } + } + } + + public static void Unregister(IEventHandler handler) where TEvent : IEvent + { + lock (_lock) + { + Type eventType = typeof(TEvent); + if (_eventHandlers.ContainsKey(eventType)) + { + var handlers = _eventHandlers[eventType] as List>; + handlers?.Remove(handler); + + if (handlers != null && handlers.Count == 0) + { + _eventHandlers.Remove(eventType); + } + } + } + } + + public static void Publish(TEvent eventData) where TEvent : IEvent + { + List> handlersToInvoke = null; + + lock (_lock) + { + Type eventType = typeof(TEvent); + if (_eventHandlers.ContainsKey(eventType)) + { + var handlers = _eventHandlers[eventType] as List>; + if (handlers != null && handlers.Count > 0) + { + handlersToInvoke = new List>(handlers); + } + } + } + + // 在锁外执行事件处理,避免死锁 + if (handlersToInvoke != null) + { + foreach (var handler in handlersToInvoke) + { + try + { + handler?.HandleEvent(eventData); + } + catch (Exception e) + { + Debug.LogError($"Event handling error in {handler.GetType().Name}: {e}"); + } + } + } + } + + public static void Clear() + { + lock (_lock) + { + _eventHandlers.Clear(); + } + } +} diff --git a/Assets/GameFramework/Runtime/EventSystem/EventBus.cs.meta b/Assets/GameFramework/Runtime/EventSystem/EventBus.cs.meta new file mode 100644 index 0000000..4dee067 --- /dev/null +++ b/Assets/GameFramework/Runtime/EventSystem/EventBus.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 182f32b2a26cc364fa0e982e86b2a730 \ No newline at end of file diff --git a/Assets/GameFramework/Runtime/EventSystem/IEvent.cs b/Assets/GameFramework/Runtime/EventSystem/IEvent.cs new file mode 100644 index 0000000..1afd3e6 --- /dev/null +++ b/Assets/GameFramework/Runtime/EventSystem/IEvent.cs @@ -0,0 +1,27 @@ +public interface IEvent { } + +public interface IEventHandler where TEvent : IEvent +{ + void HandleEvent(TEvent eventData); +} + +public struct ApplicationFocusEvent : IEvent +{ + public bool HasFocus; +} + +public struct SceneLoadEvent : IEvent +{ + public string SceneName; + public float Progress; +} + +public abstract class EventHandler : IEventHandler where TEvent : IEvent +{ + public void HandleEvent(TEvent eventData) + { + OnEvent(eventData); + } + + protected abstract void OnEvent(TEvent eventData); +} diff --git a/Assets/GameFramework/Runtime/EventSystem/IEvent.cs.meta b/Assets/GameFramework/Runtime/EventSystem/IEvent.cs.meta new file mode 100644 index 0000000..fefbc3e --- /dev/null +++ b/Assets/GameFramework/Runtime/EventSystem/IEvent.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: e7820fef43b561e4ea2ac8370cb7e831 \ No newline at end of file