mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
TEngine 6
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局对象必须继承于此。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">子类类型。</typeparam>
|
||||
public abstract class Singleton<T> : ISingleton where T : Singleton<T>, new()
|
||||
{
|
||||
protected static T _instance = default(T);
|
||||
|
||||
public static T Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == _instance)
|
||||
{
|
||||
_instance = new T();
|
||||
_instance.OnInit();
|
||||
SingletonSystem.Retain(_instance);
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsValid => _instance != null;
|
||||
|
||||
protected Singleton()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
string st = new StackTrace().ToString();
|
||||
// using const string to compare simply
|
||||
if (!st.Contains("GameLogic.Singleton`1[T].get_Instance"))
|
||||
{
|
||||
UnityEngine.Debug.LogError($"请必须通过Instance方法来实例化{typeof(T).FullName}类");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
protected virtual void OnInit()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Active()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Release()
|
||||
{
|
||||
OnRelease();
|
||||
if (_instance != null)
|
||||
{
|
||||
SingletonSystem.Release(_instance);
|
||||
_instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void OnRelease();
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7bb4cd9d323468dbaf9651bffb0c0a1
|
||||
timeCreated: 1735231561
|
@@ -0,0 +1,110 @@
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局MonoBehavior必须继承于此
|
||||
/// </summary>
|
||||
/// <typeparam name="T">子类类型</typeparam>
|
||||
public class SingletonBehaviour<T> : MonoBehaviour where T : SingletonBehaviour<T>
|
||||
{
|
||||
private static T _instance;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (CheckInstance())
|
||||
{
|
||||
OnLoad();
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckInstance()
|
||||
{
|
||||
if (this == Instance)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Object.Destroy(gameObject);
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual void OnLoad()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
if (this == _instance)
|
||||
{
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断对象是否有效
|
||||
/// </summary>
|
||||
public static bool IsValid
|
||||
{
|
||||
get { return _instance != null; }
|
||||
}
|
||||
|
||||
public static T Active()
|
||||
{
|
||||
return Instance;
|
||||
}
|
||||
|
||||
public static void Release()
|
||||
{
|
||||
if (_instance != null)
|
||||
{
|
||||
SingletonSystem.Release(_instance.gameObject, _instance);
|
||||
_instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实例
|
||||
/// </summary>
|
||||
public static T Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
System.Type thisType = typeof(T);
|
||||
string instName = thisType.Name;
|
||||
GameObject go = SingletonSystem.GetGameObject(instName);
|
||||
if (go == null)
|
||||
{
|
||||
go = GameObject.Find($"/{instName}");
|
||||
if (go == null)
|
||||
{
|
||||
go = new GameObject(instName);
|
||||
go.transform.position = Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
if (go != null)
|
||||
{
|
||||
_instance = go.GetComponent<T>();
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = go.AddComponent<T>();
|
||||
}
|
||||
}
|
||||
|
||||
if (_instance == null)
|
||||
{
|
||||
Log.Fatal($"Can't create SingletonBehaviour<{typeof(T)}>");
|
||||
}
|
||||
|
||||
SingletonSystem.Retain(go, _instance);
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a53eafeed174676b4aeb55ce8576233
|
||||
timeCreated: 1735231561
|
@@ -0,0 +1,369 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public interface ISingleton
|
||||
{
|
||||
/// <summary>
|
||||
/// 激活接口,通常用于在某个时机手动实例化
|
||||
/// </summary>
|
||||
void Active();
|
||||
|
||||
/// <summary>
|
||||
/// 释放接口
|
||||
/// </summary>
|
||||
void Release();
|
||||
}
|
||||
|
||||
public interface IUpdate
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏框架模块轮询。
|
||||
/// </summary>
|
||||
void OnUpdate();
|
||||
}
|
||||
|
||||
public interface IFixedUpdate
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏框架模块轮询。
|
||||
/// </summary>
|
||||
void OnFixedUpdate();
|
||||
}
|
||||
|
||||
public interface ILateUpdate
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏框架模块轮询。
|
||||
/// </summary>
|
||||
void OnLateUpdate();
|
||||
}
|
||||
|
||||
public interface IDrawGizmos
|
||||
{
|
||||
void OnDrawGizmos();
|
||||
}
|
||||
|
||||
public interface IDrawGizmosSelected
|
||||
{
|
||||
void OnDrawGizmosSelected();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 框架中的全局对象与Unity场景依赖相关的DontDestroyOnLoad需要统一管理,方便重启游戏时清除工作
|
||||
/// </summary>
|
||||
public static class SingletonSystem
|
||||
{
|
||||
private static IUpdateDriver _updateDriver;
|
||||
private static readonly List<ISingleton> _singletons = new List<ISingleton>();
|
||||
private static readonly List<IUpdate> _updates = new List<IUpdate>();
|
||||
private static readonly List<IFixedUpdate> _fixedUpdates = new List<IFixedUpdate>();
|
||||
private static readonly List<ILateUpdate> _lateUpdates = new List<ILateUpdate>();
|
||||
#if UNITY_EDITOR
|
||||
private static readonly List<IDrawGizmos> _drawGizmos = new List<IDrawGizmos>();
|
||||
private static readonly List<IDrawGizmosSelected> _drawGizmosSelecteds = new List<IDrawGizmosSelected>();
|
||||
#endif
|
||||
|
||||
private static readonly Dictionary<string, GameObject> _gameObjects = new Dictionary<string, GameObject>();
|
||||
|
||||
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 m_isInit = false;
|
||||
|
||||
private static void CheckInit()
|
||||
{
|
||||
if (m_isInit == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_isInit = true;
|
||||
|
||||
_updateDriver ??= ModuleSystem.GetModule<IUpdateDriver>();
|
||||
_updateDriver.AddUpdateListener(OnUpdate);
|
||||
_updateDriver.AddFixedUpdateListener(OnFixedUpdate);
|
||||
_updateDriver.AddLateUpdateListener(OnLateUpdate);
|
||||
#if UNITY_EDITOR
|
||||
_updateDriver.AddOnDrawGizmosListener(OnDrawGizmos);
|
||||
_updateDriver.AddOnDrawGizmosSelectedListener(OnDrawGizmosSelected);
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void DeInit()
|
||||
{
|
||||
if (m_isInit == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_isInit = false;
|
||||
|
||||
_updateDriver ??= ModuleSystem.GetModule<IUpdateDriver>();
|
||||
_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
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f62c29005dd4afcac0324f56012ece8
|
||||
timeCreated: 1735231561
|
Reference in New Issue
Block a user