1 Star 3 Fork 0

凉鞋/SingletonKit

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
SingletonKit.cs 16.86 KB
一键复制 编辑 原始数据 按行查看 历史
凉鞋 提交于 2021-12-08 09:22 . Update SingletonKit.cs
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
/****************************************************************************
* Copyright (c) 2017 ~ 2021 liangxie MIT License
*
* https://github.com/liangxiegame/SingletonKit
****************************************************************************/
using System;
using System.Reflection;
using UnityEngine;
namespace QFramework
{
/// <summary>
/// 单例接口
/// </summary>
public interface ISingleton
{
/// <summary>
/// 单例初始化(继承当前接口的类都需要实现该方法)
/// </summary>
void OnSingletonInit();
}
/// <summary>
/// 普通类的单例
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class Singleton<T> : ISingleton where T : Singleton<T>
{
/// <summary>
/// 静态实例
/// </summary>
protected static T mInstance;
/// <summary>
/// 标签锁:确保当一个线程位于代码的临界区时,另一个线程不进入临界区。
/// 如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放
/// </summary>
static object mLock = new object();
/// <summary>
/// 静态属性
/// </summary>
public static T Instance
{
get
{
lock (mLock)
{
if (mInstance == null)
{
mInstance = SingletonCreator.CreateSingleton<T>();
}
}
return mInstance;
}
}
/// <summary>
/// 资源释放
/// </summary>
public virtual void Dispose()
{
mInstance = null;
}
/// <summary>
/// 单例初始化方法
/// </summary>
public virtual void OnSingletonInit()
{
}
}
/// <summary>
/// 属性单例类
/// </summary>
/// <typeparam name="T"></typeparam>
public static class SingletonProperty<T> where T : class, ISingleton
{
/// <summary>
/// 静态实例
/// </summary>
private static T mInstance;
/// <summary>
/// 标签锁
/// </summary>
private static readonly object mLock = new object();
/// <summary>
/// 静态属性
/// </summary>
public static T Instance
{
get
{
lock (mLock)
{
if (mInstance == null)
{
mInstance = SingletonCreator.CreateSingleton<T>();
}
}
return mInstance;
}
}
/// <summary>
/// 资源释放
/// </summary>
public static void Dispose()
{
mInstance = null;
}
}
/// <summary>
/// 普通单例创建类
/// </summary>
internal static class SingletonCreator
{
static T CreateNonPublicConstructorObject<T>() where T : class
{
var type = typeof(T);
// 获取私有构造函数
var constructorInfos = type.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
// 获取无参构造函数
var ctor = Array.Find(constructorInfos, c => c.GetParameters().Length == 0);
if (ctor == null)
{
throw new Exception("Non-Public Constructor() not found! in " + type);
}
return ctor.Invoke(null) as T;
}
public static T CreateSingleton<T>() where T : class, ISingleton
{
var type = typeof(T);
var monoBehaviourType = typeof(MonoBehaviour);
if (monoBehaviourType.IsAssignableFrom(type))
{
return CreateMonoSingleton<T>();
}
else
{
var instance = CreateNonPublicConstructorObject<T>();
instance.OnSingletonInit();
return instance;
}
}
/// <summary>
/// 单元测试模式 标签
/// </summary>
public static bool IsUnitTestMode { get; set; }
/// <summary>
/// 查找Obj(一个嵌套查找Obj的过程)
/// </summary>
/// <param name="root">父节点</param>
/// <param name="subPath">拆分后的路径节点</param>
/// <param name="index">下标</param>
/// <param name="build">true</param>
/// <param name="dontDestroy">不要销毁 标签</param>
/// <returns></returns>
private static GameObject FindGameObject(GameObject root, string[] subPath, int index, bool build,
bool dontDestroy)
{
GameObject client = null;
if (root == null)
{
client = GameObject.Find(subPath[index]);
}
else
{
var child = root.transform.Find(subPath[index]);
if (child != null)
{
client = child.gameObject;
}
}
if (client == null)
{
if (build)
{
client = new GameObject(subPath[index]);
if (root != null)
{
client.transform.SetParent(root.transform);
}
if (dontDestroy && index == 0 && !IsUnitTestMode)
{
GameObject.DontDestroyOnLoad(client);
}
}
}
if (client == null)
{
return null;
}
return ++index == subPath.Length ? client : FindGameObject(client, subPath, index, build, dontDestroy);
}
/// <summary>
/// 泛型方法:创建MonoBehaviour单例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T CreateMonoSingleton<T>() where T : class, ISingleton
{
T instance = null;
var type = typeof(T);
//判断T实例存在的条件是否满足
if (!IsUnitTestMode && !Application.isPlaying)
return instance;
//判断当前场景中是否存在T实例
instance = UnityEngine.Object.FindObjectOfType(type) as T;
if (instance != null)
{
instance.OnSingletonInit();
return instance;
}
//MemberInfo:获取有关成员属性的信息并提供对成员元数据的访问
MemberInfo info = typeof(T);
//获取T类型 自定义属性,并找到相关路径属性,利用该属性创建T实例
var attributes = info.GetCustomAttributes(true);
foreach (var atribute in attributes)
{
var defineAttri = atribute as MonoSingletonPath;
if (defineAttri == null)
{
continue;
}
instance = CreateComponentOnGameObject<T>(defineAttri.PathInHierarchy, true);
break;
}
//如果还是无法找到instance 则主动去创建同名Obj 并挂载相关脚本 组件
if (instance == null)
{
var obj = new GameObject(typeof(T).Name);
if (!IsUnitTestMode)
UnityEngine.Object.DontDestroyOnLoad(obj);
instance = obj.AddComponent(typeof(T)) as T;
}
instance.OnSingletonInit();
return instance;
}
/// <summary>
/// 在GameObject上创建T组件(脚本)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path">路径(应该就是Hierarchy下的树结构路径)</param>
/// <param name="dontDestroy">不要销毁 标签</param>
/// <returns></returns>
private static T CreateComponentOnGameObject<T>(string path, bool dontDestroy) where T : class
{
var obj = FindGameObject(path, true, dontDestroy);
if (obj == null)
{
obj = new GameObject("Singleton of " + typeof(T).Name);
if (dontDestroy && !IsUnitTestMode)
{
UnityEngine.Object.DontDestroyOnLoad(obj);
}
}
return obj.AddComponent(typeof(T)) as T;
}
/// <summary>
/// 查找Obj(对于路径 进行拆分)
/// </summary>
/// <param name="path">路径</param>
/// <param name="build">true</param>
/// <param name="dontDestroy">不要销毁 标签</param>
/// <returns></returns>
private static GameObject FindGameObject(string path, bool build, bool dontDestroy)
{
if (string.IsNullOrEmpty(path))
{
return null;
}
var subPath = path.Split('/');
if (subPath == null || subPath.Length == 0)
{
return null;
}
return FindGameObject(null, subPath, 0, build, dontDestroy);
}
}
/// <summary>
/// 静态类:MonoBehaviour类的单例
/// 泛型类:Where约束表示T类型必须继承MonoSingleton<T>
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class MonoSingleton<T> : MonoBehaviour, ISingleton where T : MonoSingleton<T>
{
/// <summary>
/// 静态实例
/// </summary>
protected static T mInstance;
/// <summary>
/// 静态属性:封装相关实例对象
/// </summary>
public static T Instance
{
get
{
if (mInstance == null && !mOnApplicationQuit)
{
mInstance = SingletonCreator.CreateMonoSingleton<T>();
}
return mInstance;
}
}
/// <summary>
/// 实现接口的单例初始化
/// </summary>
public virtual void OnSingletonInit()
{
}
/// <summary>
/// 资源释放
/// </summary>
public virtual void Dispose()
{
if (SingletonCreator.IsUnitTestMode)
{
var curTrans = transform;
do
{
var parent = curTrans.parent;
DestroyImmediate(curTrans.gameObject);
curTrans = parent;
} while (curTrans != null);
mInstance = null;
}
else
{
Destroy(gameObject);
}
}
/// <summary>
/// 当前应用程序是否结束 标签
/// </summary>
protected static bool mOnApplicationQuit = false;
/// <summary>
/// 应用程序退出:释放当前对象并销毁相关GameObject
/// </summary>
protected virtual void OnApplicationQuit()
{
mOnApplicationQuit = true;
if (mInstance == null) return;
Destroy(mInstance.gameObject);
mInstance = null;
}
/// <summary>
/// 释放当前对象
/// </summary>
protected virtual void OnDestroy()
{
mInstance = null;
}
/// <summary>
/// 判断当前应用程序是否退出
/// </summary>
public static bool IsApplicationQuit
{
get { return mOnApplicationQuit; }
}
}
/// <summary>
/// MonoSingleton路径
/// </summary>
[AttributeUsage(AttributeTargets.Class)] //这个特性只能标记在Class上
public class MonoSingletonPath : Attribute
{
private string mPathInHierarchy;
public MonoSingletonPath(string pathInHierarchy)
{
mPathInHierarchy = pathInHierarchy;
}
public string PathInHierarchy
{
get { return mPathInHierarchy; }
}
}
/// <summary>
/// 继承Mono的属性单例?
/// </summary>
/// <typeparam name="T"></typeparam>
public static class MonoSingletonProperty<T> where T : MonoBehaviour, ISingleton
{
private static T mInstance;
public static T Instance
{
get
{
if (null == mInstance)
{
mInstance = SingletonCreator.CreateMonoSingleton<T>();
}
return mInstance;
}
}
public static void Dispose()
{
if (SingletonCreator.IsUnitTestMode)
{
UnityEngine.Object.DestroyImmediate(mInstance.gameObject);
}
else
{
UnityEngine.Object.Destroy(mInstance.gameObject);
}
mInstance = null;
}
}
/// <summary>
/// 如果跳转到新的场景里已经有了实例,则不创建新的单例(或者创建新的单例后会销毁掉新的单例)
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class PersistentMonoSingleton<T> : MonoBehaviour where T : Component
{
protected static T mInstance;
protected bool mEnabled;
/// <summary>
/// Singleton design pattern
/// </summary>
/// <value>The instance.</value>
public static T Instance
{
get
{
if (mInstance == null)
{
mInstance = FindObjectOfType<T>();
if (mInstance == null)
{
var obj = new GameObject();
mInstance = obj.AddComponent<T>();
}
}
return mInstance;
}
}
/// <summary>
/// On awake, we check if there's already a copy of the object in the scene. If there's one, we destroy it.
/// </summary>
protected virtual void Awake()
{
if (!Application.isPlaying)
{
return;
}
if (mInstance == null)
{
//If I am the first instance, make me the Singleton
mInstance = this as T;
DontDestroyOnLoad(transform.gameObject);
mEnabled = true;
}
else
{
//If a Singleton already exists and you find
//another reference in scene, destroy it!
if (this != mInstance)
{
Destroy(this.gameObject);
}
}
}
}
/// <summary>
/// 如果跳转到新的场景里已经有了实例,则删除已有示例,再创建新的实例
/// </summary>
/// <typeparam name="T"></typeparam>
public class ReplaceableMonoSingleton<T> : MonoBehaviour where T : Component
{
protected static T mInstance;
public float InitializationTime;
/// <summary>
/// Singleton design pattern
/// </summary>
/// <value>The instance.</value>
public static T Instance
{
get
{
if (mInstance == null)
{
mInstance = FindObjectOfType<T>();
if (mInstance == null)
{
GameObject obj = new GameObject();
obj.hideFlags = HideFlags.HideAndDontSave;
mInstance = obj.AddComponent<T>();
}
}
return mInstance;
}
}
/// <summary>
/// On awake, we check if there's already a copy of the object in the scene. If there's one, we destroy it.
/// </summary>
protected virtual void Awake()
{
if (!Application.isPlaying)
{
return;
}
InitializationTime = Time.time;
DontDestroyOnLoad(this.gameObject);
// we check for existing objects of the same type
T[] check = FindObjectsOfType<T>();
foreach (T searched in check)
{
if (searched != this)
{
// if we find another object of the same type (not this), and if it's older than our current object, we destroy it.
if (searched.GetComponent<ReplaceableMonoSingleton<T>>().InitializationTime < InitializationTime)
{
Destroy(searched.gameObject);
}
}
}
if (mInstance == null)
{
mInstance = this as T;
}
}
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C#
1
https://gitee.com/liangxiegame/SingletonKit.git
git@gitee.com:liangxiegame/SingletonKit.git
liangxiegame
SingletonKit
SingletonKit
main

搜索帮助

0d507c66 1850385 C8b1a773 1850385