diff --git a/sources/Assets/Scenes/GameEvents.unity b/sources/Assets/Scenes/GameEvents.unity new file mode 100644 index 0000000..6a7951e Binary files /dev/null and b/sources/Assets/Scenes/GameEvents.unity differ diff --git a/sources/Assets/Scenes/GameEvents.unity.meta b/sources/Assets/Scenes/GameEvents.unity.meta new file mode 100644 index 0000000..8a55e2c --- /dev/null +++ b/sources/Assets/Scenes/GameEvents.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 58edc6589a70740239cd0aa7d1710487 +timeCreated: 1501912731 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/sources/Assets/Scripts/Tests/GameEvents.meta b/sources/Assets/Scripts/Tests/GameEvents.meta new file mode 100644 index 0000000..2346adc --- /dev/null +++ b/sources/Assets/Scripts/Tests/GameEvents.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 06d94a32d0ec942c4b28d98eeaac6cb7 +folderAsset: yes +timeCreated: 1501912770 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/sources/Assets/Scripts/Tests/GameEvents/EventsNotificator.cs b/sources/Assets/Scripts/Tests/GameEvents/EventsNotificator.cs new file mode 100644 index 0000000..8ea9ad7 --- /dev/null +++ b/sources/Assets/Scripts/Tests/GameEvents/EventsNotificator.cs @@ -0,0 +1,26 @@ +using UnityEngine; +using Assets.Scripts.Utils.GameEvents; +using UnityEngine.UI; + +namespace Assets.Scripts.Tests.GameEvents +{ + public class EventsNotificator : MonoBehaviour + { + public Text NotificationText; + public float FadeOutTime; + + public void Awake() + { + this.Subscribe(MetagameEvents.NewGameStarted, () => ShowText("New Game Started")); + this.Subscribe(MetagameEvents.CoinsGot, _ => ShowText("Got coins: " + _)); + this.Subscribe(MetagameEvents.GameFinished, _ => ShowText("Game finished, reason: " + _.Reason + ", score: " + _.Score)); + } + + private void ShowText(string text) + { + NotificationText.text = text; + NotificationText.canvasRenderer.SetAlpha(1f); + NotificationText.CrossFadeAlpha(0f, FadeOutTime, true); + } + } +} diff --git a/sources/Assets/Scripts/Utils/GameEvents/GameEventCallback.cs.meta b/sources/Assets/Scripts/Tests/GameEvents/EventsNotificator.cs.meta similarity index 53% rename from sources/Assets/Scripts/Utils/GameEvents/GameEventCallback.cs.meta rename to sources/Assets/Scripts/Tests/GameEvents/EventsNotificator.cs.meta index cbd4073..7e45e0f 100644 --- a/sources/Assets/Scripts/Utils/GameEvents/GameEventCallback.cs.meta +++ b/sources/Assets/Scripts/Tests/GameEvents/EventsNotificator.cs.meta @@ -1,8 +1,12 @@ fileFormatVersion: 2 -guid: 1b0d6086131cfb44fb1114e2c1ccba99 +guid: a15a44ee63dfa45729c3b2e43001ad0a +timeCreated: 1501916235 +licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: + assetBundleName: + assetBundleVariant: diff --git a/sources/Assets/Scripts/Tests/GameEvents/MetagameEvents.cs b/sources/Assets/Scripts/Tests/GameEvents/MetagameEvents.cs new file mode 100644 index 0000000..15449d2 --- /dev/null +++ b/sources/Assets/Scripts/Tests/GameEvents/MetagameEvents.cs @@ -0,0 +1,30 @@ +using Assets.Scripts.Utils.GameEvents; + +namespace Assets.Scripts.Tests.GameEvents +{ + public static class MetagameEvents + { + public static GameEvent NewGameStarted = new GameEvent(); + public static GameEvent CoinsGot = new GameEvent(); + public static GameEvent GameFinished = new GameEvent(); + } + + public class GameFinishedArgs + { + public GameFinishedReason Reason { get; private set; } + public int Score { get; private set; } + + public GameFinishedArgs(GameFinishedReason reason, int score = 0) + { + Reason = reason; + Score = score; + } + } + + public enum GameFinishedReason + { + Win, + Lose, + Restart + } +} diff --git a/sources/Assets/Scripts/Utils/GameEvents/CommandMonoBehaviour.cs.meta b/sources/Assets/Scripts/Tests/GameEvents/MetagameEvents.cs.meta similarity index 53% rename from sources/Assets/Scripts/Utils/GameEvents/CommandMonoBehaviour.cs.meta rename to sources/Assets/Scripts/Tests/GameEvents/MetagameEvents.cs.meta index 342f09e..8e5fc71 100644 --- a/sources/Assets/Scripts/Utils/GameEvents/CommandMonoBehaviour.cs.meta +++ b/sources/Assets/Scripts/Tests/GameEvents/MetagameEvents.cs.meta @@ -1,8 +1,12 @@ fileFormatVersion: 2 -guid: 5b2b5f40f6871a64f9b0a1828edb3059 +guid: 8b5b7f2889ebc42d5a0e7247fa4c13d6 +timeCreated: 1501913281 +licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: + assetBundleName: + assetBundleVariant: diff --git a/sources/Assets/Scripts/Tests/GameEvents/UIManager.cs b/sources/Assets/Scripts/Tests/GameEvents/UIManager.cs new file mode 100644 index 0000000..dcfee8f --- /dev/null +++ b/sources/Assets/Scripts/Tests/GameEvents/UIManager.cs @@ -0,0 +1,33 @@ +using Assets.Scripts.Utils.GameEvents; +using UnityEngine; + +namespace Assets.Scripts.Tests.GameEvents +{ + public class UIManager : MonoBehaviour + { + public void RaiseNewGameStarted() + { + MetagameEvents.NewGameStarted.Publish(); + } + + public void RaiseCoinsGotEvent() + { + MetagameEvents.CoinsGot.Publish(Random.Range(10, 100)); + } + + public void RaiseGameWinEvent() + { + MetagameEvents.GameFinished.Publish(new GameFinishedArgs(GameFinishedReason.Win, Random.Range(1, 10))); + } + + public void RaiseGameLoseEvent() + { + MetagameEvents.GameFinished.Publish(new GameFinishedArgs(GameFinishedReason.Lose)); + } + + public void RaiseGameRestartEvent() + { + MetagameEvents.GameFinished.Publish(new GameFinishedArgs(GameFinishedReason.Restart)); + } + } +} \ No newline at end of file diff --git a/sources/Assets/Scripts/Utils/GameEvents/PendingCommand.cs.meta b/sources/Assets/Scripts/Tests/GameEvents/UIManager.cs.meta similarity index 53% rename from sources/Assets/Scripts/Utils/GameEvents/PendingCommand.cs.meta rename to sources/Assets/Scripts/Tests/GameEvents/UIManager.cs.meta index c8ea6f0..5d8bc70 100644 --- a/sources/Assets/Scripts/Utils/GameEvents/PendingCommand.cs.meta +++ b/sources/Assets/Scripts/Tests/GameEvents/UIManager.cs.meta @@ -1,8 +1,12 @@ fileFormatVersion: 2 -guid: 72650369e2f33dd4a9d2bfbd201b65b3 +guid: e826a469cf75747d88e97dba47431246 +timeCreated: 1501912783 +licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: + assetBundleName: + assetBundleVariant: diff --git a/sources/Assets/Scripts/Utils/GameEvents/CommandMonoBehaviour.cs b/sources/Assets/Scripts/Utils/GameEvents/CommandMonoBehaviour.cs deleted file mode 100644 index 462565e..0000000 --- a/sources/Assets/Scripts/Utils/GameEvents/CommandMonoBehaviour.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Assets.Scripts.Utils.GameEvents -{ - public abstract class CommandMonoBehaviour : MonoBehaviourBase - { - private readonly Queue _pendingCommands; - private readonly int _subscriberId; - private static int _counter; - - protected CommandMonoBehaviour() - { - _pendingCommands = new Queue(); - _subscriberId = ++_counter; - } - - public virtual void Update() - { - while (_pendingCommands.Any()) - { - _pendingCommands.Dequeue().Execute(); - } - } - - protected void Subscribe(GameEvent gameEvent, Action action) - where TEventArgs : GameEventArgs - { - gameEvent.Subscribe(_subscriberId, args => EnqueuePendingCommand(action, args)); - } - - private void EnqueuePendingCommand(Action action, TEventArgs args) - where TEventArgs : GameEventArgs - { - _pendingCommands.Enqueue(new PendingCommand(action, args)); - } - - protected void UnSubscribe(GameEvent gameEvent) - where TEventArgs : GameEventArgs - { - gameEvent.UnSubscribe(_subscriberId); - } - } - -} diff --git a/sources/Assets/Scripts/Utils/GameEvents/EventsListener.cs b/sources/Assets/Scripts/Utils/GameEvents/EventsListener.cs new file mode 100644 index 0000000..a1e1a99 --- /dev/null +++ b/sources/Assets/Scripts/Utils/GameEvents/EventsListener.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections; +using UnityEngine; + +namespace Assets.Scripts.Utils.GameEvents +{ + public class EventsListener : MonoBehaviour + { + private readonly int _subscriberId; + private static int _counter; + + public EventsListener() + { + _subscriberId = ++_counter; + } + + public void Subscribe(GameEvent gameEvent, Action callback) + { + gameEvent.Subscribe(_subscriberId, callback); + } + + public void Subscribe(GameEvent gameEvent, Action callback) + { + gameEvent.Subscribe(_subscriberId, callback); + } + + public void SubscribeWithDelay(GameEvent gameEvent, Action callback, float delay) + { + gameEvent.Subscribe(_subscriberId, () => + { + StartCoroutine(ExecuteAfterDelay(callback, delay)); + }); + } + + public void SubscribeWithDelay(GameEvent gameEvent, Action callback, float delay) + { + gameEvent.Subscribe(_subscriberId, eventArgs => + { + StartCoroutine(ExecuteAfterDelay(callback, eventArgs, delay)); + }); + } + + private IEnumerator ExecuteAfterDelay(Action callback, float delay) + { + yield return new WaitForSeconds(delay); + callback(); + } + + private IEnumerator ExecuteAfterDelay(Action callback, TEventArgs eventArgs, float delay) + { + yield return new WaitForSeconds(delay); + callback(eventArgs); + } + + protected void UnSubscribe(GameEvent gameEvent) + { + gameEvent.UnSubscribe(_subscriberId); + } + + protected void UnSubscribe(GameEvent gameEvent) + { + gameEvent.UnSubscribe(_subscriberId); + } + } + +} diff --git a/sources/Assets/Scripts/Utils/GameEvents/GameEventArgs.cs.meta b/sources/Assets/Scripts/Utils/GameEvents/EventsListener.cs.meta similarity index 53% rename from sources/Assets/Scripts/Utils/GameEvents/GameEventArgs.cs.meta rename to sources/Assets/Scripts/Utils/GameEvents/EventsListener.cs.meta index 46a2d9b..f9203b0 100644 --- a/sources/Assets/Scripts/Utils/GameEvents/GameEventArgs.cs.meta +++ b/sources/Assets/Scripts/Utils/GameEvents/EventsListener.cs.meta @@ -1,8 +1,12 @@ fileFormatVersion: 2 -guid: 865ac5d3a2912d54ea304a9fef1028af +guid: 4222b26dc6b964cbabe2d55b49542c3b +timeCreated: 1501912239 +licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: + assetBundleName: + assetBundleVariant: diff --git a/sources/Assets/Scripts/Utils/GameEvents/Extensions.cs b/sources/Assets/Scripts/Utils/GameEvents/Extensions.cs new file mode 100644 index 0000000..594c702 --- /dev/null +++ b/sources/Assets/Scripts/Utils/GameEvents/Extensions.cs @@ -0,0 +1,36 @@ +using System; +using UnityEngine; + +namespace Assets.Scripts.Utils.GameEvents +{ + public static class Extensions + { + public static void Subscribe(this MonoBehaviour monoBehaviour, GameEvent gameEvent, Action action) + { + EventsListener eventsListener = monoBehaviour.GetComponent() ?? + monoBehaviour.gameObject.AddComponent(); + eventsListener.Subscribe(gameEvent, action); + } + + public static void Subscribe(this MonoBehaviour monoBehaviour, GameEvent gameEvent, Action action) + { + EventsListener eventsListener = monoBehaviour.GetComponent() ?? + monoBehaviour.gameObject.AddComponent(); + eventsListener.Subscribe(gameEvent, action); + } + + public static void SubscribeWithDelay(this MonoBehaviour monoBehaviour, GameEvent gameEvent, Action action, float delay) + { + EventsListener eventsListener = monoBehaviour.GetComponent() ?? + monoBehaviour.gameObject.AddComponent(); + eventsListener.SubscribeWithDelay(gameEvent, action, delay); + } + + public static void SubscribeWithDelay(this MonoBehaviour monoBehaviour, GameEvent gameEvent, Action action, float delay) + { + EventsListener eventsListener = monoBehaviour.GetComponent() ?? + monoBehaviour.gameObject.AddComponent(); + eventsListener.SubscribeWithDelay(gameEvent, action, delay); + } + } +} diff --git a/sources/Assets/Scripts/Utils/GameEvents/Extensions.cs.meta b/sources/Assets/Scripts/Utils/GameEvents/Extensions.cs.meta new file mode 100644 index 0000000..9b6da84 --- /dev/null +++ b/sources/Assets/Scripts/Utils/GameEvents/Extensions.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 07e7feb3e2b4e4e7aaebd720f33df51d +timeCreated: 1501912394 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/sources/Assets/Scripts/Utils/GameEvents/GameEvent.cs b/sources/Assets/Scripts/Utils/GameEvents/GameEvent.cs index 1f8ef4b..ea53467 100644 --- a/sources/Assets/Scripts/Utils/GameEvents/GameEvent.cs +++ b/sources/Assets/Scripts/Utils/GameEvents/GameEvent.cs @@ -3,31 +3,65 @@ namespace Assets.Scripts.Utils.GameEvents { - public class GameEvent where TEventArgs : GameEventArgs + public class GameEvent { - private readonly List> _callbacks; + private readonly List _subscriberIds = new List(); + private readonly List _callbacks = new List(); - public GameEvent() + public void Subscribe(int subscriberId, Action callback) { - _callbacks = new List>(); + _subscriberIds.Add(subscriberId); + _callbacks.Add(callback); } - public void Subscribe(int subscriberId, Action callback) + public void Publish() + { + for (int i = 0; i < _callbacks.Count; i++) + _callbacks[i](); + } + + public void UnSubscribe(int subscriberId) { - _callbacks.Add(new GameEventCallback(subscriberId, callback)); + for (int i = 0; i < _callbacks.Count; i++) + { + if (_subscriberIds[i] == subscriberId) + { + _callbacks.RemoveAt(i); + _subscriberIds.RemoveAt(i); + i--; + } + } } + } + + public class GameEvent + { + private readonly List _subscriberIds = new List(); + private readonly List> _callbacks = new List>(); - public void Publish(TEventArgs eventArgs) - { - foreach (GameEventCallback callback in _callbacks) - callback.Callback(eventArgs); - } + public void Subscribe(int subscriberId, Action callback) + { + _subscriberIds.Add(subscriberId); + _callbacks.Add(callback); + } - public void UnSubscribe(int subscriberId) + public void Publish(TEventArgs eventArgs) { - foreach(GameEventCallback callback in _callbacks.ToArray()) - if (callback.SubscriberId == subscriberId) - _callbacks.Remove(callback); - } - } + for (int i = 0; i < _callbacks.Count; i++) + _callbacks[i](eventArgs); + } + + public void UnSubscribe(int subscriberId) + { + for (int i = 0; i < _callbacks.Count; i++) + { + if(_subscriberIds[i] == subscriberId) + { + _callbacks.RemoveAt(i); + _subscriberIds.RemoveAt(i); + i--; + } + } + } + } } diff --git a/sources/Assets/Scripts/Utils/GameEvents/GameEventArgs.cs b/sources/Assets/Scripts/Utils/GameEvents/GameEventArgs.cs deleted file mode 100644 index 294c59f..0000000 --- a/sources/Assets/Scripts/Utils/GameEvents/GameEventArgs.cs +++ /dev/null @@ -1,39 +0,0 @@ - -namespace Assets.Scripts.Utils.GameEvents -{ - public class GameEventArgs - { - private static GameEventArgs _empty; - public static GameEventArgs Empty - { - get - { - if (_empty == null) - _empty = new GameEventArgs(); - return _empty; - } - } - } - - public class GameEventArgs : GameEventArgs - { - public T Value { get; private set; } - - public GameEventArgs(T value) - { - Value = value; - } - } - - public class GameEventArgs : GameEventArgs - { - public T1 Value1 { get; private set; } - public T2 Value2 { get; private set; } - - public GameEventArgs(T1 value1, T2 value2) - { - Value1 = value1; - Value2 = value2; - } - } -} diff --git a/sources/Assets/Scripts/Utils/GameEvents/GameEventCallback.cs b/sources/Assets/Scripts/Utils/GameEvents/GameEventCallback.cs deleted file mode 100644 index 71828e2..0000000 --- a/sources/Assets/Scripts/Utils/GameEvents/GameEventCallback.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace Assets.Scripts.Utils.GameEvents -{ - public class GameEventCallback where TEventArgs : GameEventArgs - { - public int SubscriberId { get; private set; } - public Action Callback { get; private set; } - - public GameEventCallback(int subscriberId, Action callback) - { - SubscriberId = subscriberId; - Callback = callback; - } - } -} diff --git a/sources/Assets/Scripts/Utils/GameEvents/PendingCommand.cs b/sources/Assets/Scripts/Utils/GameEvents/PendingCommand.cs deleted file mode 100644 index 23214b7..0000000 --- a/sources/Assets/Scripts/Utils/GameEvents/PendingCommand.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; - -namespace Assets.Scripts.Utils.GameEvents -{ - public abstract class PendingCommand - { - public abstract void Execute(); - } - - public class PendingCommand : PendingCommand - where TEventArgs : GameEventArgs - { - private readonly Action _callback; - - public TEventArgs Args { get; private set; } - - public PendingCommand(Action callback, TEventArgs args) - { - _callback = callback; - Args = args; - } - - public override void Execute() - { - _callback(Args); - } - } -} diff --git a/sources/ProjectSettings/ProjectSettings.asset b/sources/ProjectSettings/ProjectSettings.asset index 656f248..884450e 100644 Binary files a/sources/ProjectSettings/ProjectSettings.asset and b/sources/ProjectSettings/ProjectSettings.asset differ diff --git a/sources/ProjectSettings/ProjectVersion.txt b/sources/ProjectSettings/ProjectVersion.txt index c4684cd..ca1aa05 100644 --- a/sources/ProjectSettings/ProjectVersion.txt +++ b/sources/ProjectSettings/ProjectVersion.txt @@ -1,2 +1 @@ -m_EditorVersion: 5.3.4f1 -m_StandardAssetsVersion: 0 +m_EditorVersion: 2017.1.0f3