diff --git a/Assets/Fungus/Scripts/Components/Clickable2D.cs b/Assets/Fungus/Scripts/Components/Clickable2D.cs index e36d2434..a4493525 100644 --- a/Assets/Fungus/Scripts/Components/Clickable2D.cs +++ b/Assets/Fungus/Scripts/Components/Clickable2D.cs @@ -39,7 +39,9 @@ namespace Fungus return; } - EventDispatcher.Raise(new ObjectClicked.ObjectClickedEvent(this)); + var eventDispatcher = FungusManager.Instance.EventDispatcher; + + eventDispatcher.Raise(new ObjectClicked.ObjectClickedEvent(this)); } protected virtual void DoPointerEnter() diff --git a/Assets/Fungus/Scripts/Components/Draggable2D.cs b/Assets/Fungus/Scripts/Components/Draggable2D.cs index ad6f227e..41fee724 100644 --- a/Assets/Fungus/Scripts/Components/Draggable2D.cs +++ b/Assets/Fungus/Scripts/Components/Draggable2D.cs @@ -75,7 +75,10 @@ namespace Fungus { return; } - EventDispatcher.Raise(new DragEntered.DragEnteredEvent(this, other)); + + var eventDispatcher = FungusManager.Instance.EventDispatcher; + + eventDispatcher.Raise(new DragEntered.DragEnteredEvent(this, other)); } protected virtual void OnTriggerExit2D(Collider2D other) @@ -84,7 +87,10 @@ namespace Fungus { return; } - EventDispatcher.Raise(new DragExited.DragExitedEvent(this, other)); + + var eventDispatcher = FungusManager.Instance.EventDispatcher; + + eventDispatcher.Raise(new DragExited.DragExitedEvent(this, other)); } protected virtual void DoBeginDrag() @@ -97,7 +103,9 @@ namespace Fungus startingPosition = transform.position; - EventDispatcher.Raise(new DragStarted.DragStartedEvent(this)); + var eventDispatcher = FungusManager.Instance.EventDispatcher; + + eventDispatcher.Raise(new DragStarted.DragStartedEvent(this)); } protected virtual void DoDrag() @@ -123,6 +131,7 @@ namespace Fungus return; } + var eventDispatcher = FungusManager.Instance.EventDispatcher; bool dragCompleted = false; for (int i = 0; i < dragCompletedHandlers.Count; i++) @@ -133,14 +142,15 @@ namespace Fungus if (handler.IsOverTarget()) { dragCompleted = true; - EventDispatcher.Raise(new DragCompleted.DragCompletedEvent(this)); + + eventDispatcher.Raise(new DragCompleted.DragCompletedEvent(this)); } } } if (!dragCompleted) { - EventDispatcher.Raise(new DragCancelled.DragCancelledEvent(this)); + eventDispatcher.Raise(new DragCancelled.DragCancelledEvent(this)); if (returnOnCancelled) { diff --git a/Assets/Fungus/Scripts/Components/EventHandler.cs b/Assets/Fungus/Scripts/Components/EventHandler.cs index 39881ae5..602c8eb7 100644 --- a/Assets/Fungus/Scripts/Components/EventHandler.cs +++ b/Assets/Fungus/Scripts/Components/EventHandler.cs @@ -41,38 +41,6 @@ namespace Fungus [FormerlySerializedAs("parentSequence")] [SerializeField] protected Block parentBlock; - #region Unity Messages Propagation - protected virtual void UnityOnEnable() - { - - } - - protected virtual void UnityOnDisable() - { - - } - - protected virtual void UnityStart() - { - - } - - void OnEnable() - { - UnityOnEnable(); - } - - void OnDisable() - { - UnityOnDisable(); - } - - void Start() - { - UnityStart(); - } - #endregion - #region Public members /// diff --git a/Assets/Fungus/Scripts/Components/FungusManager.cs b/Assets/Fungus/Scripts/Components/FungusManager.cs index 33345f14..bf320ef7 100644 --- a/Assets/Fungus/Scripts/Components/FungusManager.cs +++ b/Assets/Fungus/Scripts/Components/FungusManager.cs @@ -11,6 +11,7 @@ namespace Fungus /// [RequireComponent(typeof(CameraManager))] [RequireComponent(typeof(MusicManager))] + [RequireComponent(typeof(EventDispatcher))] #if UNITY_5_3_OR_NEWER [RequireComponent(typeof(SaveManager))] #endif @@ -24,6 +25,7 @@ namespace Fungus { CameraManager = GetComponent(); MusicManager = GetComponent(); + EventDispatcher = GetComponent(); #if UNITY_5_3_OR_NEWER SaveManager = GetComponent(); #endif @@ -54,6 +56,11 @@ namespace Fungus /// public MusicManager MusicManager { get; private set; } + /// + /// Gets the event dispatcher singleton instance. + /// + public EventDispatcher EventDispatcher { get; private set; } + #if UNITY_5_3_OR_NEWER /// /// Gets the save manager singleton instance. diff --git a/Assets/Fungus/Scripts/EventHandlers/DragCancelled.cs b/Assets/Fungus/Scripts/EventHandlers/DragCancelled.cs index 4bf4b01a..afc517de 100644 --- a/Assets/Fungus/Scripts/EventHandlers/DragCancelled.cs +++ b/Assets/Fungus/Scripts/EventHandlers/DragCancelled.cs @@ -26,22 +26,27 @@ namespace Fungus [Tooltip("Draggable object to listen for drag events on")] [SerializeField] protected Draggable2D draggableObject; - protected override void UnityOnEnable() + protected EventDispatcher eventDispatcher; + + protected virtual void OnEnable() { - base.UnityOnEnable(); - EventDispatcher.AddListener(OnDragCancelledEvent); + eventDispatcher = FungusManager.Instance.EventDispatcher; + + eventDispatcher.AddListener(OnDragCancelledEvent); } - protected override void UnityOnDisable() + protected virtual void OnDisable() { - base.UnityOnDisable(); - EventDispatcher.RemoveListener(OnDragCancelledEvent); + eventDispatcher.RemoveListener(OnDragCancelledEvent); + + eventDispatcher = null; } - void OnDragCancelledEvent(DragCancelledEvent evt) + protected virtual void OnDragCancelledEvent(DragCancelledEvent evt) { OnDragCancelled(evt.DraggableObject); } + #region Public members public virtual void OnDragCancelled(Draggable2D draggableObject) diff --git a/Assets/Fungus/Scripts/EventHandlers/DragCompleted.cs b/Assets/Fungus/Scripts/EventHandlers/DragCompleted.cs index 140b71af..e0c42514 100644 --- a/Assets/Fungus/Scripts/EventHandlers/DragCompleted.cs +++ b/Assets/Fungus/Scripts/EventHandlers/DragCompleted.cs @@ -32,12 +32,15 @@ namespace Fungus // we have to listen to the callbacks and track the touching state ourselves. protected bool overTarget = false; - protected override void UnityOnEnable() + protected EventDispatcher eventDispatcher; + + protected virtual void OnEnable() { - base.UnityOnEnable(); - EventDispatcher.AddListener(OnDragCompletedEvent); - EventDispatcher.AddListener(OnDragEnteredEvent); - EventDispatcher.AddListener(OnDragExitedEvent); + eventDispatcher = FungusManager.Instance.EventDispatcher; + + eventDispatcher.AddListener(OnDragCompletedEvent); + eventDispatcher.AddListener(OnDragEnteredEvent); + eventDispatcher.AddListener(OnDragExitedEvent); if(draggableObject != null) { @@ -45,17 +48,18 @@ namespace Fungus } } - protected override void UnityOnDisable() + protected virtual void OnDisable() { - base.UnityOnDisable(); - EventDispatcher.RemoveListener(OnDragCompletedEvent); - EventDispatcher.RemoveListener(OnDragEnteredEvent); - EventDispatcher.RemoveListener(OnDragExitedEvent); + eventDispatcher.RemoveListener(OnDragCompletedEvent); + eventDispatcher.RemoveListener(OnDragEnteredEvent); + eventDispatcher.RemoveListener(OnDragExitedEvent); if(draggableObject != null) { draggableObject.UnregisterHandler(this); } + + eventDispatcher = null; } void OnDragCompletedEvent(DragCompletedEvent evt) diff --git a/Assets/Fungus/Scripts/EventHandlers/DragEntered.cs b/Assets/Fungus/Scripts/EventHandlers/DragEntered.cs index c55cf46c..9c486b75 100644 --- a/Assets/Fungus/Scripts/EventHandlers/DragEntered.cs +++ b/Assets/Fungus/Scripts/EventHandlers/DragEntered.cs @@ -33,16 +33,20 @@ namespace Fungus [Tooltip("Drag target object to listen for drag events on")] [SerializeField] protected Collider2D targetObject; - protected override void UnityOnEnable() + protected EventDispatcher eventDispatcher; + + protected virtual void OnEnable() { - base.UnityOnEnable(); - EventDispatcher.AddListener(OnDragEnteredEvent); + eventDispatcher = FungusManager.Instance.EventDispatcher; + + eventDispatcher.AddListener(OnDragEnteredEvent); } - protected override void UnityOnDisable() + protected virtual void OnDisable() { - base.UnityOnDisable(); - EventDispatcher.RemoveListener(OnDragEnteredEvent); + eventDispatcher.RemoveListener(OnDragEnteredEvent); + + eventDispatcher = null; } void OnDragEnteredEvent(DragEnteredEvent evt) diff --git a/Assets/Fungus/Scripts/EventHandlers/DragExited.cs b/Assets/Fungus/Scripts/EventHandlers/DragExited.cs index 711a9505..446a0c9d 100644 --- a/Assets/Fungus/Scripts/EventHandlers/DragExited.cs +++ b/Assets/Fungus/Scripts/EventHandlers/DragExited.cs @@ -2,9 +2,6 @@ // It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE) using UnityEngine; -using System; -using System.Collections; -using System.Collections.Generic; namespace Fungus { @@ -34,16 +31,20 @@ namespace Fungus [Tooltip("Drag target object to listen for drag events on")] [SerializeField] protected Collider2D targetObject; - protected override void UnityOnEnable() + protected EventDispatcher eventDispatcher; + + protected virtual void OnEnable() { - base.UnityOnEnable(); - EventDispatcher.AddListener(OnDragEnteredEvent); + eventDispatcher = FungusManager.Instance.EventDispatcher; + + eventDispatcher.AddListener(OnDragEnteredEvent); } - protected override void UnityOnDisable() + protected virtual void OnDisable() { - base.UnityOnDisable(); - EventDispatcher.RemoveListener(OnDragEnteredEvent); + eventDispatcher.RemoveListener(OnDragEnteredEvent); + + eventDispatcher = null; } void OnDragEnteredEvent(DragExitedEvent evt) diff --git a/Assets/Fungus/Scripts/EventHandlers/DragStarted.cs b/Assets/Fungus/Scripts/EventHandlers/DragStarted.cs index 95f14570..49134dbb 100644 --- a/Assets/Fungus/Scripts/EventHandlers/DragStarted.cs +++ b/Assets/Fungus/Scripts/EventHandlers/DragStarted.cs @@ -25,16 +25,20 @@ namespace Fungus [SerializeField] protected Draggable2D draggableObject; - protected override void UnityOnEnable() + protected EventDispatcher eventDispatcher; + + protected virtual void OnEnable() { - base.UnityOnEnable(); - EventDispatcher.AddListener(OnDragStartedEvent); + eventDispatcher = FungusManager.Instance.EventDispatcher; + + eventDispatcher.AddListener(OnDragStartedEvent); } - protected override void UnityOnDisable() + protected virtual void OnDisable() { - base.UnityOnDisable(); - EventDispatcher.RemoveListener(OnDragStartedEvent); + eventDispatcher.RemoveListener(OnDragStartedEvent); + + eventDispatcher = null; } void OnDragStartedEvent(DragStartedEvent evt) diff --git a/Assets/Fungus/Scripts/EventHandlers/EventDispatcher.cs b/Assets/Fungus/Scripts/EventHandlers/EventDispatcher.cs deleted file mode 100644 index 4f999570..00000000 --- a/Assets/Fungus/Scripts/EventHandlers/EventDispatcher.cs +++ /dev/null @@ -1,174 +0,0 @@ -using System.Collections.Generic; -using System; - -namespace Fungus -{ - public class EventDispatcher - { - public delegate void TypedDelegate(T e) where T : class; - - #region Statics - static EventDispatcher _instance; - public static EventDispatcher Instance - { - get - { - if(_instance == null) - { - _instance = new EventDispatcher(); - } - return _instance; - } - } - - public static void AddLog(Action log) - { - Instance.addLog(log); - } - - public static void RemoveLog(Action log) - { - Instance.removeLog(log); - } - - public static void AddListener(TypedDelegate listener) where T : class - { - Instance.addListener(listener); - } - - public static void RemoveListener(TypedDelegate listener) where T : class - { - Instance.removeListener(listener); - } - - public static void Raise(T evt) where T : class - { - Instance.raise(evt); - } - - public static void Raise() where T : class, new() - { - Instance.raise(new T()); - } - - public static void UnregisterAll() - { - Instance.unregisterAll(); - } - #endregion - - #region Private Members - readonly Dictionary> _delegates; - event Action _onLog; - #endregion - - #region Private Functions - private EventDispatcher() - { - _delegates = new Dictionary>(); - } - /// - /// Gets the delegate list copy. - /// - /// - /// As listener can modify the list while iterating it, it is better to iterate a copy of the delegates list instead of a reference. - /// - /// A copy of the delegates list if found. Null if the dictionary does not contain a delegate list for this event. - /// Event instance. - /// Type of the received event. - List getDelegateListCopy(T evt) - { - var type = typeof(T); - return _delegates.ContainsKey(type) ? new List(_delegates[type]) : null; - } - - void log(string message) - { - if(_onLog != null) - { - _onLog(message); - } - } - #endregion - - #region Public Functions - public void addLog(Action log) - { - _onLog += log; - } - - public void removeLog(Action log) - { - _onLog -= log; - } - - public void addListener(TypedDelegate listener) where T : class - { - var type = typeof(T); - if(!_delegates.ContainsKey(type)) - { - _delegates.Add(type, new List()); - } - - var list = _delegates[type]; - if(!list.Contains(listener)) - { - list.Add(listener); - } - } - - public void removeListener(TypedDelegate listener) where T : class - { - var type = typeof(T); - if(_delegates.ContainsKey(type)) - { - _delegates[type].Remove(listener); - return; - } - } - - public void raise(T evt) where T : class - { - if(evt == null) - { - log("Raised a null event"); - return; - } - - var list = getDelegateListCopy(evt); - if(list == null || list.Count < 1) - { - log("Raised an event with no listeners"); - return; - } - - for(int i = 0; i < list.Count; ++i) - { - var callback = list[i] as TypedDelegate; - - if(callback != null) - { - try - { - callback(evt); - } - catch(Exception gotcha) - { - log(gotcha.Message); - } - } - } - } - - public void raise() where T : class, new() - { - raise(new T()); - } - - public void unregisterAll() - { - _delegates.Clear(); - } - #endregion - } -} \ No newline at end of file diff --git a/Assets/Fungus/Scripts/EventHandlers/FlowchartEnabled.cs b/Assets/Fungus/Scripts/EventHandlers/FlowchartEnabled.cs index 72c95c05..18c10305 100644 --- a/Assets/Fungus/Scripts/EventHandlers/FlowchartEnabled.cs +++ b/Assets/Fungus/Scripts/EventHandlers/FlowchartEnabled.cs @@ -14,9 +14,8 @@ namespace Fungus [AddComponentMenu("")] public class FlowchartEnabled : EventHandler { - protected override void UnityOnEnable() + protected virtual void OnEnable() { - base.UnityOnEnable(); // Blocks use coroutines to schedule command execution, but Unity's coroutines are // sometimes unreliable when enabling / disabling objects. // To workaround this we execute the block on the next frame. diff --git a/Assets/Fungus/Scripts/EventHandlers/GameStarted.cs b/Assets/Fungus/Scripts/EventHandlers/GameStarted.cs index dd793ec9..3f4c0fa9 100644 --- a/Assets/Fungus/Scripts/EventHandlers/GameStarted.cs +++ b/Assets/Fungus/Scripts/EventHandlers/GameStarted.cs @@ -18,9 +18,8 @@ namespace Fungus [Tooltip("Wait for a number of frames after startup before executing the Block. Can help fix startup order issues.")] [SerializeField] protected int waitForFrames = 1; - protected override void UnityStart() + protected virtual void Start() { - base.UnityStart(); StartCoroutine(GameStartCoroutine()); } diff --git a/Assets/Fungus/Scripts/EventHandlers/ObjectClicked.cs b/Assets/Fungus/Scripts/EventHandlers/ObjectClicked.cs index e326e6b0..20b72d7d 100644 --- a/Assets/Fungus/Scripts/EventHandlers/ObjectClicked.cs +++ b/Assets/Fungus/Scripts/EventHandlers/ObjectClicked.cs @@ -30,17 +30,20 @@ namespace Fungus [Tooltip("Wait for a number of frames before executing the block.")] [SerializeField] protected int waitFrames = 1; + protected EventDispatcher eventDispatcher; - protected override void UnityOnEnable() + protected virtual void OnEnable() { - base.UnityOnEnable(); - EventDispatcher.AddListener(OnObjectClickedEvent); + eventDispatcher = FungusManager.Instance.EventDispatcher; + + eventDispatcher.AddListener(OnObjectClickedEvent); } - protected override void UnityOnDisable() + protected virtual void OnDisable() { - base.UnityOnDisable(); - EventDispatcher.RemoveListener(OnObjectClickedEvent); + eventDispatcher.RemoveListener(OnObjectClickedEvent); + + eventDispatcher = null; } void OnObjectClickedEvent(ObjectClickedEvent evt) diff --git a/Assets/Fungus/Scripts/Utils/EventDispatcher.cs b/Assets/Fungus/Scripts/Utils/EventDispatcher.cs new file mode 100644 index 00000000..36b46ee7 --- /dev/null +++ b/Assets/Fungus/Scripts/Utils/EventDispatcher.cs @@ -0,0 +1,150 @@ +// This code is part of the Fungus library (http://fungusgames.com) maintained by Chris Gregan (http://twitter.com/gofungus). +// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE) + +using UnityEngine; +using System.Collections.Generic; +using System; + +namespace Fungus +{ + /// + /// A simple efficient event dispatcher with logging support. + /// + public class EventDispatcher : MonoBehaviour + { + protected readonly Dictionary> delegates = new Dictionary>(); + + protected virtual event Action onLog; + + /// + /// Gets the delegate list copy. + /// + /// + /// As listener can modify the list while iterating it, it is better to iterate a copy of the delegates list instead of a reference. + /// + /// A copy of the delegates list if found. Null if the dictionary does not contain a delegate list for this event. + /// Event instance. + /// Type of the received event. + protected virtual List GetDelegateListCopy(T evt) + { + var type = typeof(T); + return delegates.ContainsKey(type) ? new List(delegates[type]) : null; + } + + protected virtual void Log(string message) + { + if(onLog != null) + { + onLog(message); + } + } + + #region Public members + + /// + /// A typed delegate which contains information about the event. + /// + public delegate void TypedDelegate(T e) where T : class; + + /// + /// Adds a log callback action. + /// + public virtual void AddLog(Action log) + { + onLog += log; + } + + /// + /// Removes a log callback action. + /// + public virtual void RemoveLog(Action log) + { + onLog -= log; + } + + /// + /// Adds a listener for a specified event type. + /// + public virtual void AddListener(TypedDelegate listener) where T : class + { + var type = typeof(T); + if(!delegates.ContainsKey(type)) + { + delegates.Add(type, new List()); + } + + var list = delegates[type]; + if(!list.Contains(listener)) + { + list.Add(listener); + } + } + + /// + /// Removes a listener for a specified event type. + /// + public virtual void RemoveListener(TypedDelegate listener) where T : class + { + var type = typeof(T); + if(delegates.ContainsKey(type)) + { + delegates[type].Remove(listener); + return; + } + } + + /// + /// Raise an event of a specified type. + /// + public virtual void Raise(T evt) where T : class + { + if(evt == null) + { + Log("Raised a null event"); + return; + } + + var list = GetDelegateListCopy(evt); + if(list == null || list.Count < 1) + { + Log("Raised an event with no listeners"); + return; + } + + for(int i = 0; i < list.Count; ++i) + { + var callback = list[i] as TypedDelegate; + + if(callback != null) + { + try + { + callback(evt); + } + catch(Exception gotcha) + { + Log(gotcha.Message); + } + } + } + } + + /// + /// Raise an event of a specified type, creates an instance of the type automatically. + /// + public virtual void Raise() where T : class, new() + { + Raise(new T()); + } + + /// + /// Unregisters all event listeners. + /// + public virtual void UnregisterAll() + { + delegates.Clear(); + } + + #endregion + } +} \ No newline at end of file diff --git a/Assets/Fungus/Scripts/EventHandlers/EventDispatcher.cs.meta b/Assets/Fungus/Scripts/Utils/EventDispatcher.cs.meta similarity index 100% rename from Assets/Fungus/Scripts/EventHandlers/EventDispatcher.cs.meta rename to Assets/Fungus/Scripts/Utils/EventDispatcher.cs.meta