From ef0ef50048e564747565c72d9424b5c6a4701a11 Mon Sep 17 00:00:00 2001 From: Travis Scott Date: Thu, 21 Jul 2016 20:40:21 -0500 Subject: [PATCH] Refactored to use arrays instead of lists --- Zephyr/AdvancedMonoBehaviour/GameRunner.cs | 48 ----- Zephyr/AdvancedMonoBehaviour/IStartable.cs | 6 - Zephyr/AdvancedMonoBehaviour/IUpdateable.cs | 6 - Zephyr/EventSystem/Core/EventManager.cs | 2 +- Zephyr/EventSystem/Core/EventManagerModel.cs | 10 +- .../AdvanceMonobehvaiourRunner.cs | 181 ++++++++++++++++++ .../AdvancedMonoBehaviour.cs | 18 +- Zephyr/MonoBehaviourAdditions/IUpdateable.cs | 10 + Zephyr/Singletons/SimpleSingleton.cs | 2 +- Zephyr/Singletons/SingletonAsComponent.cs | 2 +- Zephyr/Zephyr.csproj | 7 +- 11 files changed, 212 insertions(+), 80 deletions(-) delete mode 100644 Zephyr/AdvancedMonoBehaviour/GameRunner.cs delete mode 100644 Zephyr/AdvancedMonoBehaviour/IStartable.cs delete mode 100644 Zephyr/AdvancedMonoBehaviour/IUpdateable.cs create mode 100644 Zephyr/MonoBehaviourAdditions/AdvanceMonobehvaiourRunner.cs rename Zephyr/{AdvancedMonoBehaviour => MonoBehaviourAdditions}/AdvancedMonoBehaviour.cs (63%) create mode 100644 Zephyr/MonoBehaviourAdditions/IUpdateable.cs diff --git a/Zephyr/AdvancedMonoBehaviour/GameRunner.cs b/Zephyr/AdvancedMonoBehaviour/GameRunner.cs deleted file mode 100644 index e407126..0000000 --- a/Zephyr/AdvancedMonoBehaviour/GameRunner.cs +++ /dev/null @@ -1,48 +0,0 @@ -using UnityEngine; -using System.Collections.Generic; -using Zephyr.Singletons; - -namespace Zephyr.MonoBehaviours -{ - - /// - /// In charge of running the update loop. This update loop is more efficient then the unity built update loop. Later this class should be extended to include high priority update items adnd such to cusomize the level of priority - /// items in the update loop have. - /// - public class GameRunner : SingletonAsComponent - { - public static GameRunner Instance { get { return (GameRunner) _Instance; } set { _Instance = value; } } - - private List _updateableObjects = new List(); - - /// - /// Registers an updateable object into the Update loop - /// - /// The object to register into the update loop - public void RegisterUpdateableObject(IUpdateable obj) - { - if (!_updateableObjects.Contains(obj)) - _updateableObjects.Add(obj); - } - - /// - /// Unregisters an updateable component from the update loop - /// - /// The object to remove from the Update loop - public void UnregisterUpdateableObject(IUpdateable obj) - { - if (_updateableObjects.Contains(obj)) - _updateableObjects.Remove(obj); - } - - /// - /// Updates once a frame. - /// - private void Update() - { - var delta = Time.deltaTime; - for (var i = 0; i < Instance._updateableObjects.Count; ++i) - _updateableObjects[i].OnUpdate(delta); - } - } -} diff --git a/Zephyr/AdvancedMonoBehaviour/IStartable.cs b/Zephyr/AdvancedMonoBehaviour/IStartable.cs deleted file mode 100644 index 416a410..0000000 --- a/Zephyr/AdvancedMonoBehaviour/IStartable.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Zephyr.MonoBehaviours { - public interface IStartable - { - void OnStart(); - } -} diff --git a/Zephyr/AdvancedMonoBehaviour/IUpdateable.cs b/Zephyr/AdvancedMonoBehaviour/IUpdateable.cs deleted file mode 100644 index 8acbef6..0000000 --- a/Zephyr/AdvancedMonoBehaviour/IUpdateable.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Zephyr.MonoBehaviours { - public interface IUpdateable - { - void OnUpdate(float delta); - } -} diff --git a/Zephyr/EventSystem/Core/EventManager.cs b/Zephyr/EventSystem/Core/EventManager.cs index bc3f524..77870cc 100644 --- a/Zephyr/EventSystem/Core/EventManager.cs +++ b/Zephyr/EventSystem/Core/EventManager.cs @@ -1,4 +1,4 @@ -using Zephyr.MonoBehaviours; +using Zephyr.MonoBehaviourAdditions; namespace Zephyr.EventSystem.Core { diff --git a/Zephyr/EventSystem/Core/EventManagerModel.cs b/Zephyr/EventSystem/Core/EventManagerModel.cs index fc442a7..aecdc53 100644 --- a/Zephyr/EventSystem/Core/EventManagerModel.cs +++ b/Zephyr/EventSystem/Core/EventManagerModel.cs @@ -1,6 +1,4 @@ -#if UNIT_TEST -using System; -#else +#if !UNIT_TEST using UnityEngine; #endif using System.Collections.Generic; @@ -370,17 +368,17 @@ public class Debug { public static void Log(string s) { - Console.WriteLine(s); + System.Console.WriteLine(s); } public static void LogWarning(string s) { - Console.WriteLine(s); + System.Console.WriteLine(s); } public static void LogError(string s) { - Console.WriteLine(s); + System.Console.WriteLine(s); } public static bool isDebugBuild = true; diff --git a/Zephyr/MonoBehaviourAdditions/AdvanceMonobehvaiourRunner.cs b/Zephyr/MonoBehaviourAdditions/AdvanceMonobehvaiourRunner.cs new file mode 100644 index 0000000..10e872a --- /dev/null +++ b/Zephyr/MonoBehaviourAdditions/AdvanceMonobehvaiourRunner.cs @@ -0,0 +1,181 @@ +using System; +using UnityEngine; +using Zephyr.Singletons; + +namespace Zephyr.MonoBehaviourAdditions +{ + /// + /// In charge of running the update loop. This update loop is more efficient then the unity built update loop. Later this class should be extended to include high priority update items adnd such to cusomize the level of priority + /// items in the update loop have. + /// + public class AdvanceMonoBehvaiourRunner : SingletonAsComponent + { + #region Constants + + private const int UpdateableSize = 200; + private const int UpdateableScaleFactor = 2; + + #endregion + + #region Private Attributes + + private IUpdateable[] _updateableObjects = new IUpdateable[UpdateableSize]; + private int _index; + private float _timePassed; + private bool _isNeedingCleanup; + + #endregion + + #region Properties + + public static AdvanceMonoBehvaiourRunner Instance + { + get { return (AdvanceMonoBehvaiourRunner) _Instance; } + set { _Instance = value; } + } + + #endregion + + #region Public Methods + + /// + /// Registers an updateable object into the Update loop + /// + /// The object to register into the update loop + public void RegisterUpdateableObject(IUpdateable obj) + { + AddNewUpdateable(obj); + obj.OnAwake(); + obj.OnStart(); + } + + /// + /// Unregisters an update-able component from the update loop + /// + /// The object to remove from the Update loop + public bool UnregisterUpdateableObject(IUpdateable obj) + { + for (var i = 0; i < _index; i++) + { + if (_updateableObjects[i] != obj) continue; + + _updateableObjects[i] = null; + _isNeedingCleanup = true; + return true; + } + return false; + } + + + /// + /// Updates once a frame. + /// + public void Update() + { + var delta = Time.deltaTime; + for (var i = 0; i < Instance._updateableObjects.Length; i++) + if (_updateableObjects[i] != null) + _updateableObjects[i].OnUpdate(delta); + + if (!_isNeedingCleanup) return; + + _timePassed += delta; + + if (_timePassed < 1) return; + + _timePassed = 0; + CleanUpUpdateables(); + } + + #endregion + + #region Private Methods + + /// + /// Adds a new updateable object to the updateables list. If needed, it will also increase the size + /// of the updateables array. + /// + /// The updatable object to add to the array. + private void AddNewUpdateable(IUpdateable obj) + { + if (_index == _updateableObjects.Length - 1) + Array.Resize(ref _updateableObjects, _updateableObjects.Length*UpdateableScaleFactor); + + _updateableObjects[_index] = obj; + _index++; + } + + /// + /// Cleans up the Updateables by removing the empty references and moving the objects up the array for faster + /// traversal and setting the new index. + /// + private void CleanUpUpdateables() + { + var placementIndex = FindFirstNull(); + + if (placementIndex == -1) return; + + ShiftDownUpdateables(ref placementIndex); + + ClearRemainingUpdateables(placementIndex + 1); + + _index = placementIndex; + } + + /// + /// Clears all positions between the new Index and old index as all items have been squeezed downwards in + /// the array. + /// + /// The newIndex to clear from + private void ClearRemainingUpdateables(int newIndex) + { + for (var i = newIndex; i < _index; i++) + _updateableObjects[i] = null; + } + + /// + /// Shifts all elements down the array to be at the start for faster traversal and memory management + /// + /// The position to start the moving down from. + private void ShiftDownUpdateables(ref int placementIndex) + { + for (var i = placementIndex + 1; i < _index; i++) + { + if (_updateableObjects[i] == null) + continue; + + _updateableObjects[placementIndex] = _updateableObjects[i]; + placementIndex++; + } + } + + /// + /// Finds the first null in the updateable array and returns the index. + /// + /// The first null position. If not found, returns -1. + private int FindFirstNull() + { + for (var i = 0; i < _index; i++) + { + if (_updateableObjects[i] == null) + return _index; + } + return -1; + } + + #endregion + + #region Inherited Members + + /// + /// Called when this object is destroyed. + /// + protected override void OnDestroy() + { + base.OnDestroy(); + _updateableObjects = null; + } + + #endregion + } +} \ No newline at end of file diff --git a/Zephyr/AdvancedMonoBehaviour/AdvancedMonoBehaviour.cs b/Zephyr/MonoBehaviourAdditions/AdvancedMonoBehaviour.cs similarity index 63% rename from Zephyr/AdvancedMonoBehaviour/AdvancedMonoBehaviour.cs rename to Zephyr/MonoBehaviourAdditions/AdvancedMonoBehaviour.cs index 586dfd1..615ad4a 100644 --- a/Zephyr/AdvancedMonoBehaviour/AdvancedMonoBehaviour.cs +++ b/Zephyr/MonoBehaviourAdditions/AdvancedMonoBehaviour.cs @@ -1,16 +1,15 @@ using UnityEngine; -namespace Zephyr.MonoBehaviours +namespace Zephyr.MonoBehaviourAdditions { - public class AdvancedMonoBehaviour : MonoBehaviour, IUpdateable, IStartable + public class AdvancedMonoBehaviour : MonoBehaviour, IUpdateable { /// /// Runs on Start for all objects. /// - private void Start() + private void Awake() { - OnStart(); - GameRunner.Instance.RegisterUpdateableObject(this); + AdvanceMonoBehvaiourRunner.Instance.RegisterUpdateableObject(this); } /// @@ -18,8 +17,8 @@ private void Start() /// protected virtual void OnDestroy() { - if (GameRunner.IsAlive) - GameRunner.Instance.UnregisterUpdateableObject(this); + if (AdvanceMonoBehvaiourRunner.IsAlive) + AdvanceMonoBehvaiourRunner.Instance.UnregisterUpdateableObject(this); } /// @@ -32,5 +31,10 @@ public virtual void OnUpdate(float delta) { } /// Must be used instead of Start in an AdvancedMonobehaviour. Acts in the place of start. /// public virtual void OnStart() { } + + /// + /// Must be used instead of Awake in an AdvancedMonobehaviour. Acts in the place of start. + /// + public virtual void OnAwake() { } } } diff --git a/Zephyr/MonoBehaviourAdditions/IUpdateable.cs b/Zephyr/MonoBehaviourAdditions/IUpdateable.cs new file mode 100644 index 0000000..7712a2b --- /dev/null +++ b/Zephyr/MonoBehaviourAdditions/IUpdateable.cs @@ -0,0 +1,10 @@ +namespace Zephyr.MonoBehaviourAdditions { + public interface IUpdateable + { + void OnUpdate(float delta); + + void OnStart(); + + void OnAwake(); + } +} diff --git a/Zephyr/Singletons/SimpleSingleton.cs b/Zephyr/Singletons/SimpleSingleton.cs index 38fdeb9..1d05dfa 100644 --- a/Zephyr/Singletons/SimpleSingleton.cs +++ b/Zephyr/Singletons/SimpleSingleton.cs @@ -1,5 +1,5 @@ using UnityEngine; -using Zephyr.MonoBehaviours; +using Zephyr.MonoBehaviourAdditions; namespace Zephyr.Singletons diff --git a/Zephyr/Singletons/SingletonAsComponent.cs b/Zephyr/Singletons/SingletonAsComponent.cs index 7ed28cd..eafc126 100644 --- a/Zephyr/Singletons/SingletonAsComponent.cs +++ b/Zephyr/Singletons/SingletonAsComponent.cs @@ -1,5 +1,5 @@ using UnityEngine; -using Zephyr.MonoBehaviours; +using Zephyr.MonoBehaviourAdditions; namespace Zephyr.Singletons { diff --git a/Zephyr/Zephyr.csproj b/Zephyr/Zephyr.csproj index 2e36de7..8b629b1 100644 --- a/Zephyr/Zephyr.csproj +++ b/Zephyr/Zephyr.csproj @@ -47,10 +47,9 @@ - - - - + + +