From c850ec359c08457552d866a769b7bec2637d1da2 Mon Sep 17 00:00:00 2001
From: ALEXTANG <574809918@qq.com>
Date: Thu, 20 Apr 2023 19:34:37 +0800
Subject: [PATCH] [+] SingletonSystem
[+] SingletonSystem
---
.../HotFix/GameBase/Singleton.meta | 3 +
.../HotFix/GameBase/Singleton/TSingleton.cs | 214 ++++++++++++++++++
.../GameBase/Singleton/TSingleton.cs.meta | 3 +
.../GameBase/Singleton/UnitySingleton.cs | 111 +++++++++
.../GameBase/Singleton/UnitySingleton.cs.meta | 3 +
5 files changed, 334 insertions(+)
create mode 100644 Assets/GameScripts/HotFix/GameBase/Singleton.meta
create mode 100644 Assets/GameScripts/HotFix/GameBase/Singleton/TSingleton.cs
create mode 100644 Assets/GameScripts/HotFix/GameBase/Singleton/TSingleton.cs.meta
create mode 100644 Assets/GameScripts/HotFix/GameBase/Singleton/UnitySingleton.cs
create mode 100644 Assets/GameScripts/HotFix/GameBase/Singleton/UnitySingleton.cs.meta
diff --git a/Assets/GameScripts/HotFix/GameBase/Singleton.meta b/Assets/GameScripts/HotFix/GameBase/Singleton.meta
new file mode 100644
index 00000000..614abc11
--- /dev/null
+++ b/Assets/GameScripts/HotFix/GameBase/Singleton.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 00565f0d362f4c36836804455e19c3df
+timeCreated: 1681990210
\ No newline at end of file
diff --git a/Assets/GameScripts/HotFix/GameBase/Singleton/TSingleton.cs b/Assets/GameScripts/HotFix/GameBase/Singleton/TSingleton.cs
new file mode 100644
index 00000000..7a1f0fb0
--- /dev/null
+++ b/Assets/GameScripts/HotFix/GameBase/Singleton/TSingleton.cs
@@ -0,0 +1,214 @@
+using System.Collections.Generic;
+using TEngine;
+using UnityEngine;
+using UnityEngine.SceneManagement;
+
+namespace GameBase
+{
+ ///
+ /// 单例接口。
+ ///
+ public interface ISingleton
+ {
+ void Active();
+
+ void Release();
+ }
+
+ ///
+ /// 单例管理器(统一化持久和释放)。
+ ///
+ public static class SingletonMgr
+ {
+ private static List _singletonList;
+ private static Dictionary _gameObjects;
+ private static GameObject _root;
+
+ public static GameObject Root
+ {
+ get
+ {
+ if (_root == null)
+ {
+ _root = GameObject.Find("[SingletonMgr]");
+
+ if (_root == null)
+ {
+ _root = new GameObject("[SingletonMgr]")
+ {
+ transform =
+ {
+ position = Vector3.zero
+ }
+ };
+ }
+ UnityEngine.Object.DontDestroyOnLoad(_root);
+ }
+ return _root;
+ }
+ }
+
+ public static void Retain(ISingleton go)
+ {
+ if (_singletonList == null)
+ {
+ _singletonList = new List();
+ }
+
+ _singletonList.Add(go);
+ }
+
+ public static void Retain(GameObject go)
+ {
+ if (_gameObjects == null)
+ {
+ _gameObjects = new Dictionary();
+ }
+
+ if (!_gameObjects.ContainsKey(go.name))
+ {
+ _gameObjects.Add(go.name, go);
+ if (Application.isPlaying)
+ {
+ UnityEngine.Object.DontDestroyOnLoad(go);
+ }
+ }
+ }
+
+ public static void Release(GameObject go)
+ {
+ if (_gameObjects != null && _gameObjects.ContainsKey(go.name))
+ {
+ _gameObjects.Remove(go.name);
+ UnityEngine.Object.Destroy(go);
+ }
+ }
+
+ public static void Release(ISingleton go)
+ {
+ if (_singletonList != null && _singletonList.Contains(go))
+ {
+ _singletonList.Remove(go);
+ }
+ }
+
+ public static void Release()
+ {
+ if (_gameObjects != null)
+ {
+ foreach (var item in _gameObjects)
+ {
+ UnityEngine.Object.Destroy(item.Value);
+ }
+
+ _gameObjects.Clear();
+ }
+
+ if (_singletonList != null)
+ {
+ for (int i = 0; i < _singletonList.Count; ++i)
+ {
+ _singletonList[i].Release();
+ }
+
+ _singletonList.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;
+ }
+
+ internal static ISingleton GetSingleton(string name)
+ {
+ for (int i = 0; i < _singletonList.Count; ++i)
+ {
+ if (_singletonList[i].ToString() == name)
+ {
+ return _singletonList[i];
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// 释放所有单例。
+ ///
+ public static void ReStart()
+ {
+ Release();
+
+ SceneManager.LoadScene(0);
+ }
+ }
+
+ ///
+ /// 全局单例对象(非线程安全)。
+ ///
+ /// 泛型T。
+ public abstract class TSingleton : ISingleton where T : TSingleton, new()
+ {
+ private static T _instance;
+
+ public static T Instance
+ {
+ get
+ {
+ if (null == _instance)
+ {
+ _instance = new T();
+ _instance.Init();
+#if UNITY_EDITOR
+ Log.Info($"TSingleton Instance:{typeof(T).Name}");
+#endif
+ SingletonMgr.Retain(_instance);
+ }
+
+ return _instance;
+ }
+ }
+
+ public static bool IsValid => _instance != null;
+
+ protected TSingleton()
+ {
+ }
+
+ protected virtual void Init()
+ {
+ }
+
+ public virtual void Active()
+ {
+ }
+
+ public virtual void Release()
+ {
+ if (_instance != null)
+ {
+ SingletonMgr.Release(_instance);
+ _instance = null;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/GameScripts/HotFix/GameBase/Singleton/TSingleton.cs.meta b/Assets/GameScripts/HotFix/GameBase/Singleton/TSingleton.cs.meta
new file mode 100644
index 00000000..70380313
--- /dev/null
+++ b/Assets/GameScripts/HotFix/GameBase/Singleton/TSingleton.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: aa2cb5bb622045d7a6f2a4c4faea3ca6
+timeCreated: 1681989590
\ No newline at end of file
diff --git a/Assets/GameScripts/HotFix/GameBase/Singleton/UnitySingleton.cs b/Assets/GameScripts/HotFix/GameBase/Singleton/UnitySingleton.cs
new file mode 100644
index 00000000..db28b292
--- /dev/null
+++ b/Assets/GameScripts/HotFix/GameBase/Singleton/UnitySingleton.cs
@@ -0,0 +1,111 @@
+using TEngine;
+using UnityEngine;
+
+namespace GameBase
+{
+ ///
+ /// 具备Unity完整生命周期的单例。
+ ///
+ ///
+ public abstract class UnitySingleton : MonoBehaviour where T : MonoBehaviour
+ {
+ private static T _instance;
+
+ public static T Instance
+ {
+ get
+ {
+ if (_instance == null)
+ {
+ var ins = UnityEngine.Object.FindObjectOfType();
+ if (ins != null)
+ {
+ var obj = ins.gameObject;
+ obj.name = typeof(T).Name;
+ _instance = ins;
+ SingletonMgr.Retain(obj);
+ return Instance;
+ }
+
+ System.Type thisType = typeof(T);
+ string instName = thisType.Name;
+ GameObject go = SingletonMgr.GetGameObject(instName);
+ if (go == null)
+ {
+ go = GameObject.Find($"{instName}");
+ if (go == null)
+ {
+ go = new GameObject(instName);
+ go.transform.position = Vector3.zero;
+ }
+ }
+
+ _instance = go.GetComponent();
+ if (_instance == null)
+ {
+ _instance = go.AddComponent();
+ }
+
+ if (_instance == null)
+ {
+ Log.Error($"Can't create UnitySingleton<{typeof(T)}>");
+ }
+ }
+
+ return _instance;
+ }
+ }
+
+ public static T Active()
+ {
+ return Instance;
+ }
+
+ public static bool IsValid => _instance != null;
+
+ private bool CheckInstance()
+ {
+ if (this == Instance)
+ {
+ return true;
+ }
+
+ GameObject.Destroy(gameObject);
+ return false;
+ }
+
+ protected virtual void OnLoad()
+ {
+ }
+
+ public virtual void Awake()
+ {
+ if (CheckInstance())
+ {
+ OnLoad();
+ }
+#if UNITY_EDITOR
+ Log.Debug($"UnitySingleton Instance:{typeof(T).Name}");
+#endif
+ GameObject tEngine = SingletonMgr.Root;
+ if (tEngine != null)
+ {
+ this.gameObject.transform.SetParent(tEngine.transform);
+ }
+ }
+
+ protected virtual void OnDestroy()
+ {
+ Release();
+ }
+
+ public static void Release()
+ {
+ if (_instance != null)
+ {
+ SingletonMgr.Release(_instance.gameObject);
+ _instance = null;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/GameScripts/HotFix/GameBase/Singleton/UnitySingleton.cs.meta b/Assets/GameScripts/HotFix/GameBase/Singleton/UnitySingleton.cs.meta
new file mode 100644
index 00000000..c0330e3f
--- /dev/null
+++ b/Assets/GameScripts/HotFix/GameBase/Singleton/UnitySingleton.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 25c99243aa534df5870e36fdf9d36afd
+timeCreated: 1681990223
\ No newline at end of file