using System; using System.Collections.Generic; using TEngine; using UnityEngine; using UnityEngine.SceneManagement; using Object = UnityEngine.Object; namespace GameLogic { public interface ISingleton { /// /// 激活接口,通常用于在某个时机手动实例化 /// void Active(); /// /// 释放接口 /// void Release(); } public interface IUpdate { /// /// 游戏框架模块轮询。 /// void OnUpdate(); } public interface IFixedUpdate { /// /// 游戏框架模块轮询。 /// void OnFixedUpdate(); } public interface ILateUpdate { /// /// 游戏框架模块轮询。 /// void OnLateUpdate(); } public interface IDrawGizmos { void OnDrawGizmos(); } public interface IDrawGizmosSelected { void OnDrawGizmosSelected(); } /// /// 框架中的全局对象与Unity场景依赖相关的DontDestroyOnLoad需要统一管理,方便重启游戏时清除工作 /// public static class SingletonSystem { private static IUpdateDriver _updateDriver; private static readonly List _singletons = new List(); private static readonly List _updates = new List(); private static readonly List _fixedUpdates = new List(); private static readonly List _lateUpdates = new List(); #if UNITY_EDITOR private static readonly List _drawGizmos = new List(); private static readonly List _drawGizmosSelecteds = new List(); #endif private static readonly Dictionary _gameObjects = new Dictionary(); public static void Retain(ISingleton singleton) { CheckInit(); _singletons.Add(singleton); BuildLifeCycle(singleton); } public static void Retain(GameObject go, object singleton) { CheckInit(); if (_gameObjects.TryAdd(go.name, go)) { if (Application.isPlaying) { Object.DontDestroyOnLoad(go); } BuildLifeCycle(singleton); } } private static void BuildLifeCycle(object singleton) { Type iUpdate = typeof(IUpdate); bool needUpdate = iUpdate.IsInstanceOfType(singleton); if (needUpdate && singleton is IUpdate update) { _updates.Add(update); } Type iFixedUpdate = typeof(IFixedUpdate); bool needFixedUpdate = iFixedUpdate.IsInstanceOfType(singleton); if (needFixedUpdate && singleton is IFixedUpdate fixedUpdate) { _fixedUpdates.Add(fixedUpdate); } Type iLateUpdate = typeof(ILateUpdate); bool needLateUpdate = iLateUpdate.IsInstanceOfType(singleton); if (needLateUpdate && singleton is ILateUpdate lateUpdate) { _lateUpdates.Add(lateUpdate); } #if UNITY_EDITOR Type iDrawGizmos = typeof(IDrawGizmos); bool needDrawGizmos = iDrawGizmos.IsInstanceOfType(singleton); if (needDrawGizmos && singleton is IDrawGizmos drawGizmos) { _drawGizmos.Add(drawGizmos); } Type iDrawGizmosSelected = typeof(IDrawGizmosSelected); bool needDrawGizmosSelected = iDrawGizmosSelected.IsInstanceOfType(singleton); if (needDrawGizmosSelected && singleton is IDrawGizmosSelected drawGizmosSelected) { _drawGizmosSelecteds.Add(drawGizmosSelected); } #endif } public static void Release(GameObject go, object singleton) { if (_gameObjects != null && _gameObjects.ContainsKey(go.name)) { _gameObjects.Remove(go.name); Object.Destroy(go); ReleaseLifeCycle(singleton); } } public static void Release(ISingleton singleton) { if (_singletons != null && _singletons.Contains(singleton)) { _singletons.Remove(singleton); ReleaseLifeCycle(singleton); } } private static void ReleaseLifeCycle(object singleton) { Type iUpdate = typeof(IUpdate); bool needUpdate = iUpdate.IsInstanceOfType(singleton); if (needUpdate && singleton is IUpdate update) { if (_updates.Contains(update)) { _updates.Remove(update); } } Type iFixedUpdate = typeof(IFixedUpdate); bool needFixedUpdate = iFixedUpdate.IsInstanceOfType(singleton); if (needFixedUpdate && singleton is IFixedUpdate fixedUpdate) { if (_fixedUpdates.Contains(fixedUpdate)) { _fixedUpdates.Remove(fixedUpdate); } } Type iLateUpdate = typeof(ILateUpdate); bool needLateUpdate = iLateUpdate.IsInstanceOfType(singleton); if (needLateUpdate && singleton is ILateUpdate lateUpdate) { if (_lateUpdates.Contains(lateUpdate)) { _lateUpdates.Remove(lateUpdate); } } #if UNITY_EDITOR Type iDrawGizmos = typeof(IDrawGizmos); bool needDrawGizmos = iDrawGizmos.IsInstanceOfType(singleton); if (needDrawGizmos && singleton is IDrawGizmos drawGizmos) { if (_drawGizmos.Contains(drawGizmos)) { _drawGizmos.Remove(drawGizmos); } } Type iDrawGizmosSelected = typeof(IDrawGizmosSelected); bool needDrawGizmosSelected = iDrawGizmosSelected.IsInstanceOfType(singleton); if (needDrawGizmosSelected && singleton is IDrawGizmosSelected drawGizmosSelected) { if (_drawGizmosSelecteds.Contains(drawGizmosSelected)) { _drawGizmosSelecteds.Remove(drawGizmosSelected); } } #endif } public static void Release() { if (_gameObjects != null) { foreach (var item in _gameObjects) { Object.Destroy(item.Value); } _gameObjects.Clear(); } if (_singletons != null) { for (int i = _singletons.Count - 1; i >= 0; i--) { _singletons[i].Release(); } _singletons.Clear(); } Resources.UnloadUnusedAssets(); } public static GameObject GetGameObject(string name) { GameObject go = null; if (_gameObjects != null) { _gameObjects.TryGetValue(name, out go); } return go; } internal static bool ContainsKey(string name) { if (_gameObjects != null) { return _gameObjects.ContainsKey(name); } return false; } public static void Restart() { if (Camera.main != null) { Camera.main.gameObject.SetActive(false); } Release(); SceneManager.LoadScene(0); } internal static ISingleton GetSingleton(string name) { for (int i = 0; i < _singletons.Count; ++i) { if (_singletons[i].ToString() == name) { return _singletons[i]; } } return null; } #region 生命周期 private static bool _isInit = false; private static void CheckInit() { if (_isInit == true) { return; } _isInit = true; _updateDriver ??= ModuleSystem.GetModule(); _updateDriver.AddUpdateListener(OnUpdate); _updateDriver.AddFixedUpdateListener(OnFixedUpdate); _updateDriver.AddLateUpdateListener(OnLateUpdate); #if UNITY_EDITOR _updateDriver.AddOnDrawGizmosListener(OnDrawGizmos); _updateDriver.AddOnDrawGizmosSelectedListener(OnDrawGizmosSelected); #endif } private static void DeInit() { if (_isInit == false) { return; } _isInit = false; _updateDriver ??= ModuleSystem.GetModule(); _updateDriver.RemoveUpdateListener(OnUpdate); _updateDriver.RemoveFixedUpdateListener(OnFixedUpdate); _updateDriver.RemoveLateUpdateListener(OnLateUpdate); #if UNITY_EDITOR _updateDriver.RemoveOnDrawGizmosListener(OnDrawGizmos); _updateDriver.RemoveOnDrawGizmosSelectedListener(OnDrawGizmosSelected); #endif } private static void OnUpdate() { foreach (var update in _updates) { update.OnUpdate(); } } private static void OnFixedUpdate() { foreach (var fixedUpdate in _fixedUpdates) { fixedUpdate.OnFixedUpdate(); } } private static void OnLateUpdate() { foreach (var lateUpdate in _lateUpdates) { lateUpdate.OnLateUpdate(); } } private static void OnDrawGizmos() { #if UNITY_EDITOR foreach (var drawGizmo in _drawGizmos) { drawGizmo.OnDrawGizmos(); } #endif } private static void OnDrawGizmosSelected() { #if UNITY_EDITOR foreach (var drawGizmosSelected in _drawGizmosSelecteds) { drawGizmosSelected.OnDrawGizmosSelected(); } #endif } #endregion } }