diff --git a/Documentation~/Global System.pdf b/Documentation~/Global System.pdf new file mode 100644 index 0000000..a87e12b Binary files /dev/null and b/Documentation~/Global System.pdf differ diff --git a/Documentation~/Global System.xmind b/Documentation~/Global System.xmind new file mode 100644 index 0000000..9e45969 Binary files /dev/null and b/Documentation~/Global System.xmind differ diff --git a/Documentation~/GlobalBehaviour.pdf b/Documentation~/GlobalBehaviour.pdf deleted file mode 100644 index c1d5621..0000000 Binary files a/Documentation~/GlobalBehaviour.pdf and /dev/null differ diff --git a/Documentation~/GlobalBehaviour.xmind b/Documentation~/GlobalBehaviour.xmind deleted file mode 100644 index 375b19b..0000000 Binary files a/Documentation~/GlobalBehaviour.xmind and /dev/null differ diff --git a/README.md b/README.md index c066f07..002f60d 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,14 @@ -# Global module +# Global System + ## class GlobalBehavioour & BehaviourManager ### Descript Simulate monobehaviour's methods like 'Awake/OnEnable/Update/OnDisable/OnDestroy'. -### Usage -See Assets/Example and source code. +## class GlobalTime +### Descript +Global system time information. + ## class ScriptableObjectAssetsCreator ### Descript Create ScriptableObject asset. ### Usage -Right click ScriptableObject script file and click menu "Create -> ScriptableObject To Asset". -## class Singleton -### Descript -Makes MonoBehaviour singleton. -### Usage -See class BehaviourUpdater. \ No newline at end of file +Right click ScriptableObject script file and click menu "Create -> ScriptableObject To Asset". \ No newline at end of file diff --git a/Runtime/BehaviourManager.cs b/Runtime/BehaviourManager.cs index 83349f8..6e10530 100644 --- a/Runtime/BehaviourManager.cs +++ b/Runtime/BehaviourManager.cs @@ -1,9 +1,8 @@ using System; using System.Collections.Generic; -using UnityEngine; using System.Linq; +using UnityEngine; #if UNITY_EDITOR -using UnityEditor; #endif namespace E @@ -25,21 +24,9 @@ public sealed partial class BehaviourManager public static bool IsReady { get => instance.m_IsReady; } /// - /// Use which method to update. - /// see - /// - public static GlobalSettings.UpdateMethod UpdateMethod { get => GlobalSettings.Method; } - - /// - /// Update delta time. - /// see - /// - public static float DeltaTime { get => GlobalSettings.DeltaTime; } - - /// - /// Get instance of . + /// Get instance of . /// - public static BehaviourUpdater MonoBehaviour { get => BehaviourUpdater.Instance; } + public static GlobalUpdater Updater { get => GlobalUpdater.Instance; } /// /// Call before auto create instances, @@ -61,23 +48,23 @@ public sealed partial class BehaviourManager public static event Func OverrideCreateInstanceCallback; /// - /// Call by . + /// Call by . /// public static event Action FixedUpdateCallback; /// - /// Call . + /// Call . /// public static event Action UpdateCallback; /// - /// Call by . + /// Call by . /// public static event Action LateUpdateCallback; #if UNITY_EDITOR /// - /// Call by . + /// Call by . /// public static event Action OnDrawGizmosCallback; #endif @@ -92,6 +79,8 @@ public sealed partial class BehaviourManager private bool m_IsReady; + private bool m_FirstUpdated; + /// /// All 's /// @@ -102,16 +91,6 @@ public sealed partial class BehaviourManager /// private BehaviourCollection m_Collection; - /// - /// For calculate time. - /// - private System.Diagnostics.Stopwatch m_Stopwatch; - - /// - /// Last update time. - /// - private double m_LastTime; - /// /// Use to queue 's id need to enable. /// @@ -147,6 +126,7 @@ private enum StateToCheck /// public static T CreateInstance() where T : GlobalBehaviour { + if (!instance.m_IsReady) return default; return instance.InternalCreateInstance(); } @@ -157,6 +137,7 @@ public static T CreateInstance() where T : GlobalBehaviour /// public static GlobalBehaviour CreateInstance(in Type type) { + if (!instance.m_IsReady) return default; return instance.InternalCreateInstance(type); } @@ -167,6 +148,7 @@ public static GlobalBehaviour CreateInstance(in Type type) /// public static T GetInstance() where T : GlobalBehaviour { + if (!instance.m_IsReady) return default; return instance.InternalGetInstance(); } @@ -177,6 +159,7 @@ public static T GetInstance() where T : GlobalBehaviour /// public static GlobalBehaviour GetInstance(in Type type) { + if (!instance.m_IsReady) return default; return instance.InternalGetInstance(type); } @@ -187,6 +170,7 @@ public static GlobalBehaviour GetInstance(in Type type) /// public static T[] GetInstances() where T : GlobalBehaviour { + if (!instance.m_IsReady) return default; return instance.InternalGetInstances(); } @@ -197,6 +181,7 @@ public static T[] GetInstances() where T : GlobalBehaviour /// public static GlobalBehaviour[] GetInstances(in Type type) { + if (!instance.m_IsReady) return default; return instance.InternalGetInstances(type); } @@ -206,6 +191,7 @@ public static GlobalBehaviour[] GetInstances(in Type type) /// public static void DestroyInstance(in GlobalBehaviour behaviour) { + if (!instance.m_IsReady) return; instance.InternalDestroyInstance(behaviour); } @@ -222,79 +208,9 @@ private BehaviourManager() { } ~BehaviourManager() { Destroy(); } -#if UNITY_EDITOR - // Execute these editor methods by <1> <2> <3> order. - - [InitializeOnLoadMethod] - private static void InitializeOnLoadInEditor() - { - // <1> Execute when - // - EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; - EditorApplication.playModeStateChanged += OnPlayModeStateChanged; - EditorApplication.update -= CheckBehaviourUpdater; - EditorApplication.update += CheckBehaviourUpdater; - } + internal static void InitializeOnLoad() => instance.Initialize(); - [UnityEditor.Callbacks.DidReloadScripts] - private static void DidReloadScripts() - { - // <2> Execute when - // - // - // - // - DestroyOnExit(); - InitializeOnLoad(); - } - - private static void OnPlayModeStateChanged(PlayModeStateChange stateChange) - { - // <3> Execute when - // - // - // - // - switch (stateChange) - { - case PlayModeStateChange.EnteredEditMode: - case PlayModeStateChange.EnteredPlayMode: - InitializeOnLoad(); - break; - case PlayModeStateChange.ExitingEditMode: - case PlayModeStateChange.ExitingPlayMode: - DestroyOnExit(); - break; - } - } - - private static void CheckBehaviourUpdater() - { - BehaviourUpdater.CreateInstance(); - } -#else - // Execute at runtime after builded - - [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] - private static void InitializeOnLoadAtRuntime() - { - InitializeOnLoad(); - Application.quitting -= DestroyOnExit; - Application.quitting += DestroyOnExit; - } -#endif - - private static void InitializeOnLoad() - { - instance.Initialize(); - // Create BehaviourUpdater for update. - BehaviourUpdater.CreateInstance(); - } - - private static void DestroyOnExit() - { - instance.Destroy(); - } + internal static void DestroyOnExit() => instance.Destroy(); private void Initialize() { @@ -302,11 +218,11 @@ private void Initialize() { // make sure Initialize only once if (m_IsReady) return; - CreateStopwatch(); CreateLifeCycleQueues(); IEnumerable types = GetAllTypes(); ExecuteBefore(types); CreateTypeInfos(types); + m_FirstUpdated = false; m_IsReady = true; } catch (Exception e) @@ -324,11 +240,11 @@ private void Destroy() { // make sure Destroy only once if (!m_IsReady) return; + m_FirstUpdated = false; ReleaseCollection(); ReleaseTypeInfos(); ReleaseLifeCycleQueues(); ClearCallbacks(); - ClearStopwatch(); m_IsReady = false; } catch (Exception e) @@ -341,20 +257,6 @@ private void Destroy() } } - private void CreateStopwatch() - { - m_LastTime = 0; - m_Stopwatch = new System.Diagnostics.Stopwatch(); - m_Stopwatch.Start(); - } - - private void ClearStopwatch() - { - m_Stopwatch.Stop(); - m_Stopwatch = null; - m_LastTime = 0; - } - private IEnumerable GetAllTypes() { return AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()); @@ -579,20 +481,17 @@ private bool GetTypeInfo(int typeHashCode, out TypeInfo typeInfo) return true; } - internal void FixedUpdate() - { CallUpdate(GlobalSettings.UpdateMethod.FixedUpdate, FixedUpdateCallback); } + internal void FixedUpdate(bool allowUpdate) => CallUpdate(allowUpdate, FixedUpdateCallback); - internal void Update() - { CallUpdate(GlobalSettings.UpdateMethod.Update, UpdateCallback); } + internal void Update(bool allowUpdate) => CallUpdate(allowUpdate, UpdateCallback); - internal void LateUpdate() - { CallUpdate(GlobalSettings.UpdateMethod.LateUpdate, LateUpdateCallback); } + internal void LateUpdate(bool allowUpdate) => CallUpdate(allowUpdate, LateUpdateCallback); - private void CallUpdate(GlobalSettings.UpdateMethod updateMethod, in Action updateCallback) + private void CallUpdate(bool allowUpdate, in Action updateCallback) { if (m_IsReady) { - if (UpdateMethod == updateMethod) UpdateLifeCycle(); + if (allowUpdate) UpdateLifeCycle(); LogTryCatchEvent(updateCallback); } } @@ -619,19 +518,14 @@ private void LogTryCatchEvent(in Action action) private void UpdateLifeCycle() { - double seconds = m_Stopwatch.Elapsed.TotalSeconds; - if (seconds - m_LastTime >= DeltaTime) + if (!m_FirstUpdated) { - if(m_LastTime == 0) - { - //first frame. - AutoCreateInstances(); - } - m_LastTime = seconds; - ClearLifeCycleQueues(); - CheckAllLifeCycleState(); - InternalLifeCycleBody(); + AutoCreateInstances(); + m_FirstUpdated = true; } + ClearLifeCycleQueues(); + CheckAllLifeCycleState(); + InternalLifeCycleBody(); } private void CheckAllLifeCycleState() diff --git a/Runtime/GlobalBehaviour.cs b/Runtime/GlobalBehaviour.cs index ce1415c..09568d1 100644 --- a/Runtime/GlobalBehaviour.cs +++ b/Runtime/GlobalBehaviour.cs @@ -2,7 +2,7 @@ { /// /// Simulate 's life circle, - /// all s are in one single . + /// all s are in one single . /// See also: /// , /// , diff --git a/Runtime/GlobalSettings.cs b/Runtime/GlobalSettings.cs index 5a6ae7f..3b77ce3 100644 --- a/Runtime/GlobalSettings.cs +++ b/Runtime/GlobalSettings.cs @@ -2,6 +2,9 @@ namespace E { + /// + /// Settings of global system. + /// public class GlobalSettings : ScriptableObject { public enum UpdateMethod @@ -31,7 +34,7 @@ private static GlobalSettings Instance /// /// Update delta time. /// - public static float DeltaTime { get => Instance.m_DeltaTime; set => Instance.m_DeltaTime = value; } + public static double DeltaTime { get => Instance.m_DeltaTime; set => Instance.m_DeltaTime = value; } /// /// Use which method to update. @@ -43,7 +46,7 @@ private static GlobalSettings Instance public static bool AllowLogError { get => Instance.m_AllowLogError; set => Instance.m_AllowLogError = value; } [SerializeField, Min(0.001f)] - private float m_DeltaTime = 1f / 130f; + private double m_DeltaTime = 1f / 130f; [SerializeField] private UpdateMethod m_Method = UpdateMethod.Update; diff --git a/Runtime/GlobalTime.cs b/Runtime/GlobalTime.cs new file mode 100644 index 0000000..820d727 --- /dev/null +++ b/Runtime/GlobalTime.cs @@ -0,0 +1,131 @@ +namespace E +{ + /// + /// Global system time information base on and . + /// + public class GlobalTime + { + #region Public properties + + /// + /// true if initialized. + /// + public static bool IsReady => instance.m_IsReady; + + /// + /// The time in seconds at the beginning of this frame + /// based on and + /// since the global system initialized. + /// + public static double Time => instance.m_Time; + + /// + /// The interval in seconds from the last frame to the current one + /// based on and + /// since the global system initialized. + /// + public static double DeltaTime => instance.m_DeltaTime; + + /// + /// The real time in seconds right now + /// since the global system initialized. + /// + public static double RealTime => instance.m_IsReady ? instance.m_Stopwatch.Elapsed.TotalSeconds : 0; + + /// + /// The real time in milliseconds right now + /// since the global system initialized. + /// + public static long Milliseconds => instance.m_IsReady ? instance.m_Stopwatch.ElapsedMilliseconds : 0; + + /// + /// The frame count + /// based on and + /// since the global system initialized. + /// + public static ulong FrameCount => instance.m_IsReady ? instance.m_FrameCount : 0; + + #endregion + + #region Private properties + + /// + /// This instance. + /// + internal static readonly GlobalTime instance; + + private bool m_IsReady; + + private System.Diagnostics.Stopwatch m_Stopwatch; + + private double m_Time, m_LastTime, m_DeltaTime; + + private ulong m_FrameCount; + + #endregion + + #region Initialize & Dispose + + static GlobalTime() => instance = new GlobalTime(); + + private GlobalTime() { } + + ~GlobalTime() { Destroy(); } + + internal static void InitializeOnLoad() => instance.Initialize(); + + internal static void DestroyOnExit() => instance.Destroy(); + + private void Initialize() + { + if (m_IsReady) return; + m_Time = m_LastTime = m_DeltaTime = 0; + m_FrameCount = 0; + m_Stopwatch = new System.Diagnostics.Stopwatch(); + m_Stopwatch.Start(); + m_IsReady = true; + } + + private void Destroy() + { + if (!m_IsReady) return; + if (m_Stopwatch != null) + { + m_Stopwatch.Stop(); + m_Stopwatch = null; + } + m_FrameCount = 0; + m_Time = m_LastTime = m_DeltaTime = 0; + m_IsReady = false; + } + + #endregion + + #region Life Cycle methods + + internal bool FixedUpdate() => CallUpdate(GlobalSettings.UpdateMethod.FixedUpdate); + + internal bool Update() => CallUpdate(GlobalSettings.UpdateMethod.Update); + + internal bool LateUpdate() => CallUpdate(GlobalSettings.UpdateMethod.LateUpdate); + + private bool CallUpdate(GlobalSettings.UpdateMethod updateMethod) + { + if (m_IsReady && GlobalSettings.Method == updateMethod) + { + double realTime = m_Stopwatch.Elapsed.TotalSeconds; + if (realTime - m_LastTime >= GlobalSettings.DeltaTime) + { + m_Time = realTime; + m_DeltaTime = m_Time - m_LastTime; + m_LastTime = m_Time; + ++m_FrameCount; + return true; + } + } + return false; + } + + #endregion + } +} \ No newline at end of file diff --git a/Runtime/Time.cs.meta b/Runtime/GlobalTime.cs.meta similarity index 100% rename from Runtime/Time.cs.meta rename to Runtime/GlobalTime.cs.meta diff --git a/Runtime/BehaviourUpdater.cs b/Runtime/GlobalUpdater.cs similarity index 55% rename from Runtime/BehaviourUpdater.cs rename to Runtime/GlobalUpdater.cs index 61561cb..b73b9ce 100644 --- a/Runtime/BehaviourUpdater.cs +++ b/Runtime/GlobalUpdater.cs @@ -3,7 +3,7 @@ namespace E { /// - /// Update GlobalBehaviours at runtime, + /// Update global system at runtime, /// do not delete this gameobject. /// // Update in editor mode. @@ -12,24 +12,27 @@ namespace E [AddComponentMenu("")] // Make sure only one updater. [Singleton( - Name = "[Behaviour Updater]", + Name = "[Global Updater]", Persistent = true, HideFlags = HideFlags.HideInInspector)] - public sealed partial class BehaviourUpdater : Singleton + public sealed partial class GlobalUpdater : Singleton { private void FixedUpdate() { - BehaviourManager.instance.FixedUpdate(); + bool allowUpdate = GlobalTime.instance.FixedUpdate(); + BehaviourManager.instance.FixedUpdate(allowUpdate); } private void Update() { - BehaviourManager.instance.Update(); + bool allowUpdate = GlobalTime.instance.Update(); + BehaviourManager.instance.Update(allowUpdate); } private void LateUpdate() { - BehaviourManager.instance.LateUpdate(); + bool allowUpdate = GlobalTime.instance.LateUpdate(); + BehaviourManager.instance.LateUpdate(allowUpdate); } #if UNITY_EDITOR diff --git a/Runtime/BehaviourUpdater.cs.meta b/Runtime/GlobalUpdater.cs.meta similarity index 100% rename from Runtime/BehaviourUpdater.cs.meta rename to Runtime/GlobalUpdater.cs.meta diff --git a/Runtime/InitializeSystem.cs b/Runtime/InitializeSystem.cs new file mode 100644 index 0000000..f68f1e8 --- /dev/null +++ b/Runtime/InitializeSystem.cs @@ -0,0 +1,104 @@ +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace E +{ + /// + /// Control when to initialize or destroy global system. + /// + internal static class InitializeSystem + { +#if UNITY_EDITOR + // Execute these editor methods by <1> <2> <3> <4> <5> order. + + [InitializeOnLoadMethod] + private static void InitializeOnLoadInEditor() + { + // <1> Execute when + // + EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; + EditorApplication.playModeStateChanged += OnPlayModeStateChanged; + EditorApplication.update -= CheckUpdater; + EditorApplication.update += CheckUpdater; + } + + [UnityEditor.Callbacks.DidReloadScripts] + private static void DidReloadScripts() + { + // <2> Execute when + // + // + // + // + DestroyOnExit(); + InitializeOnLoad(); + } + + private static void OnPlayModeStateChanged(PlayModeStateChange stateChange) + { + // <3> Execute when + // + // + // + // + switch (stateChange) + { + case PlayModeStateChange.EnteredEditMode: + case PlayModeStateChange.EnteredPlayMode: + InitializeOnLoad(); + break; + case PlayModeStateChange.ExitingEditMode: + case PlayModeStateChange.ExitingPlayMode: + DestroyOnExit(); + break; + } + } + + [UnityEditor.Callbacks.PostProcessBuild] + public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) + { + // <4> Execute when + // + DestroyOnExit(); + InitializeOnLoad(); + } + + private static void CheckUpdater() + { + // <5> Execute when + // + GlobalUpdater.CreateInstance(); + } +#else + // Execute at runtime after builded + + [UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.AfterSceneLoad)] + private static void InitializeOnLoadAtRuntime() + { + InitializeOnLoad(); + UnityEngine.Application.quitting -= DestroyOnExit; + UnityEngine.Application.quitting += DestroyOnExit; + } +#endif + + /// + /// Call on initialize game. + /// + private static void InitializeOnLoad() + { + GlobalTime.InitializeOnLoad(); + BehaviourManager.InitializeOnLoad(); + GlobalUpdater.CreateInstance(); + } + + /// + /// Call on exit game. + /// + private static void DestroyOnExit() + { + BehaviourManager.DestroyOnExit(); + GlobalTime.DestroyOnExit(); + } + } +} \ No newline at end of file diff --git a/Runtime/InitializeSystem.cs.meta b/Runtime/InitializeSystem.cs.meta new file mode 100644 index 0000000..8c5060e --- /dev/null +++ b/Runtime/InitializeSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de0fb97e552cdd847a7ce2b40a7838d2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Time.cs b/Runtime/Time.cs deleted file mode 100644 index cce455e..0000000 --- a/Runtime/Time.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace E -{ - /// - /// Time information. - /// - public static class Time - { - public static double time; - public static double deltaTime; - public static double realTime; - - } -} \ No newline at end of file diff --git a/Runtime/Utility.cs b/Runtime/Utility.cs index b494e0a..619ed56 100644 --- a/Runtime/Utility.cs +++ b/Runtime/Utility.cs @@ -9,14 +9,6 @@ namespace E { internal static class Utility { - private static int m_GlobalIDOrder = 0; - - internal static unsafe uint UniqueRuntimeGlobalID() - { - Interlocked.Add(ref m_GlobalIDOrder, 1); - return (uint)m_GlobalIDOrder; - } - #if UNITY_EDITOR public static void CreateAssetIfNotExists() where T : ScriptableObject { diff --git a/package.json b/package.json index 632d169..ff28bf3 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "com.e.global", "displayName": "Global", "description": "Simulate monobehaviour's methods like 'Awake/OnEnable/Update/OnDisable/OnDestroy',and some other tools.", - "version": "1.0.7", + "version": "1.1.0", "unity": "2019.3", "license": "MIT", "keywords": [