using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEngine; namespace QFramework { #region API /// /// Unity 游戏框架搭建 (十九) 简易对象池:http://qframework.io/post/24/ 的例子 /// /// internal class SimpleObjectPool : Pool { readonly Action mResetMethod; public SimpleObjectPool(Func factoryMethod, Action resetMethod = null,int initCount = 0) { mFactory = new CustomObjectFactory(factoryMethod); mResetMethod = resetMethod; for (int i = 0; i < initCount; i++) { mCacheStack.Push(mFactory.Create()); } } public override bool Recycle(T obj) { if (mResetMethod != null) { mResetMethod.Invoke(obj); } mCacheStack.Push(obj); return true; } } /// /// Object pool. /// internal class SafeObjectPool : Pool, ISingleton where T : IPoolable, new() { #region Singleton void ISingleton.OnSingletonInit() {} protected SafeObjectPool() { mFactory = new DefaultObjectFactory(); } public static SafeObjectPool Instance { get { return SingletonProperty>.Instance; } } public void Dispose() { SingletonProperty>.Dispose(); } #endregion /// /// Init the specified maxCount and initCount. /// /// Max Cache count. /// Init Cache count. public void Init(int maxCount, int initCount) { MaxCacheCount = maxCount; if (maxCount > 0) { initCount = Math.Min(maxCount, initCount); } if (CurCount < initCount) { for (var i = CurCount; i < initCount; ++i) { Recycle(new T()); } } } /// /// Gets or sets the max cache count. /// /// The max cache count. public int MaxCacheCount { get { return mMaxCount; } set { mMaxCount = value; if (mCacheStack != null) { if (mMaxCount > 0) { if (mMaxCount < mCacheStack.Count) { int removeCount = mCacheStack.Count - mMaxCount; while (removeCount > 0) { mCacheStack.Pop(); --removeCount; } } } } } } /// /// Allocate T instance. /// public override T Allocate() { var result = base.Allocate(); result.IsRecycled = false; return result; } /// /// Recycle the T instance /// /// T. public override bool Recycle(T t) { if (t == null || t.IsRecycled) { return false; } if (mMaxCount > 0) { if (mCacheStack.Count >= mMaxCount) { t.OnRecycled(); return false; } } t.IsRecycled = true; t.OnRecycled(); mCacheStack.Push(t); return true; } } /// /// Object pool 4 class who no public constructor /// such as SingletonClass.QEventSystem /// internal class NonPublicObjectPool :Pool,ISingleton where T : class,IPoolable { #region Singleton public void OnSingletonInit(){} public static NonPublicObjectPool Instance { get { return SingletonProperty>.Instance; } } protected NonPublicObjectPool() { mFactory = new NonPublicObjectFactory(); } public void Dispose() { SingletonProperty>.Dispose(); } #endregion /// /// Init the specified maxCount and initCount. /// /// Max Cache count. /// Init Cache count. public void Init(int maxCount, int initCount) { if (maxCount > 0) { initCount = Math.Min(maxCount, initCount); } if (CurCount >= initCount) return; for (var i = CurCount; i < initCount; ++i) { Recycle(mFactory.Create()); } } /// /// Gets or sets the max cache count. /// /// The max cache count. public int MaxCacheCount { get { return mMaxCount; } set { mMaxCount = value; if (mCacheStack == null) return; if (mMaxCount <= 0) return; if (mMaxCount >= mCacheStack.Count) return; var removeCount = mMaxCount - mCacheStack.Count; while (removeCount > 0) { mCacheStack.Pop(); --removeCount; } } } /// /// Allocate T instance. /// public override T Allocate() { var result = base.Allocate(); result.IsRecycled = false; return result; } /// /// Recycle the T instance /// /// T. public override bool Recycle(T t) { if (t == null || t.IsRecycled) { return false; } if (mMaxCount > 0) { if (mCacheStack.Count >= mMaxCount) { t.OnRecycled(); return false; } } t.IsRecycled = true; t.OnRecycled(); mCacheStack.Push(t); return true; } } internal abstract class AbstractPool where T : AbstractPool, new() { private static Stack mPool = new Stack(10); protected bool mInPool = false; public static T Allocate() { var node = mPool.Count == 0 ? new T() : mPool.Pop(); node.mInPool = false; return node; } public void Recycle2Cache() { OnRecycle(); mInPool = true; mPool.Push(this as T); } protected abstract void OnRecycle(); } #endregion #region interfaces /// /// 对象池接口 /// /// internal interface IPool { /// /// 分配对象 /// /// T Allocate(); /// /// 回收对象 /// /// /// bool Recycle(T obj); } /// /// I pool able. /// internal interface IPoolable { void OnRecycled(); bool IsRecycled { get; set; } } /// /// I cache type. /// internal interface IPoolType { void Recycle2Cache(); } /// /// 对象池 /// /// internal abstract class Pool : IPool { #region ICountObserverable /// /// Gets the current count. /// /// The current count. public int CurCount { get { return mCacheStack.Count; } } #endregion protected IObjectFactory mFactory; /// /// 存储相关数据的栈 /// protected readonly Stack mCacheStack = new Stack(); /// /// default is 5 /// protected int mMaxCount = 12; public virtual T Allocate() { return mCacheStack.Count == 0 ? mFactory.Create() : mCacheStack.Pop(); } public abstract bool Recycle(T obj); } #endregion #region DataStructurePool /// /// 字典对象池:用于存储相关对象 /// /// /// internal class DictionaryPool { /// /// 栈对象:存储多个字典 /// static Stack> mListStack = new Stack>(8); /// /// 出栈:从栈中获取某个字典数据 /// /// public static Dictionary Get() { if (mListStack.Count == 0) { return new Dictionary(8); } return mListStack.Pop(); } /// /// 入栈:将字典数据存储到栈中 /// /// public static void Release(Dictionary toRelease) { toRelease.Clear(); mListStack.Push(toRelease); } } /// /// 对象池字典 拓展方法类 /// internal static class DictionaryPoolExtensions { /// /// 对字典拓展 自身入栈 的方法 /// /// /// /// public static void Release2Pool(this Dictionary toRelease) { DictionaryPool.Release(toRelease); } } /// /// 链表对象池:存储相关对象 /// /// internal static class ListPool { /// /// 栈对象:存储多个List /// static Stack> mListStack = new Stack>(8); /// /// 出栈:获取某个List对象 /// /// public static List Get() { if (mListStack.Count == 0) { return new List(8); } return mListStack.Pop(); } /// /// 入栈:将List对象添加到栈中 /// /// public static void Release(List toRelease) { toRelease.Clear(); mListStack.Push(toRelease); } } /// /// 链表对象池 拓展方法类 /// internal static class ListPoolExtensions { /// /// 给List拓展 自身入栈 的方法 /// /// /// public static void Release2Pool(this List toRelease) { ListPool.Release(toRelease); } } #endregion #region Factories /// /// 对象工厂 /// internal class ObjectFactory { /// /// 动态创建类的实例:创建有参的构造函数 /// /// /// /// public static object Create(Type type, params object[] constructorArgs) { return Activator.CreateInstance(type, constructorArgs); } /// /// 动态创建类的实例:泛型扩展 /// /// /// /// public static T Create(params object[] constructorArgs) { return (T) Create(typeof(T), constructorArgs); } /// /// 动态创建类的实例:创建无参/私有的构造函数 /// /// /// public static object CreateNonPublicConstructorObject(Type type) { // 获取私有构造函数 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); } /// /// 动态创建类的实例:创建无参/私有的构造函数 泛型扩展 /// /// /// public static T CreateNonPublicConstructorObject() { return (T) CreateNonPublicConstructorObject(typeof(T)); } /// /// 创建带有初始化回调的 对象 /// /// /// /// /// public static object CreateWithInitialAction(Type type, Action onObjectCreate, params object[] constructorArgs) { var obj = Create(type, constructorArgs); onObjectCreate(obj); return obj; } /// /// 创建带有初始化回调的 对象:泛型扩展 /// /// /// /// /// public static T CreateWithInitialAction(Action onObjectCreate, params object[] constructorArgs) { var obj = Create(constructorArgs); onObjectCreate(obj); return obj; } } /// /// 自定义对象工厂:相关对象是 自己定义 /// /// internal class CustomObjectFactory : IObjectFactory { public CustomObjectFactory(Func factoryMethod) { mFactoryMethod = factoryMethod; } protected Func mFactoryMethod; public T Create() { return mFactoryMethod(); } } /// /// 默认对象工厂:相关对象是通过New 出来的 /// /// internal class DefaultObjectFactory : IObjectFactory where T : new() { public T Create() { return new T(); } } /// /// 对象工厂接口 /// /// internal interface IObjectFactory { /// /// 创建对象 /// /// T Create(); } /// /// 没有公共构造函数的对象工厂:相关对象只能通过反射获得 /// /// internal class NonPublicObjectFactory : IObjectFactory where T : class { public T Create() { var ctors = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic); var ctor = Array.Find(ctors, c => c.GetParameters().Length == 0); if (ctor == null) { throw new Exception("Non-Public Constructor() not found! in " + typeof(T) + "\n 在没有找到非 public 的构造方法"); } return ctor.Invoke(null) as T; } } #endregion #region SingletonKit For Pool /// /// 单例接口 /// internal interface ISingleton { /// /// 单例初始化(继承当前接口的类都需要实现该方法) /// void OnSingletonInit(); } /// /// 普通类的单例 /// /// internal abstract class Singleton : ISingleton where T : Singleton { /// /// 静态实例 /// protected static T mInstance; /// /// 标签锁:确保当一个线程位于代码的临界区时,另一个线程不进入临界区。 /// 如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放 /// static object mLock = new object(); /// /// 静态属性 /// public static T Instance { get { lock (mLock) { if (mInstance == null) { mInstance = SingletonCreator.CreateSingleton(); } } return mInstance; } } /// /// 资源释放 /// public virtual void Dispose() { mInstance = null; } /// /// 单例初始化方法 /// public virtual void OnSingletonInit() { } } /// /// 属性单例类 /// /// internal static class SingletonProperty where T : class, ISingleton { /// /// 静态实例 /// private static T mInstance; /// /// 标签锁 /// private static readonly object mLock = new object(); /// /// 静态属性 /// public static T Instance { get { lock (mLock) { if (mInstance == null) { mInstance = SingletonCreator.CreateSingleton(); } } return mInstance; } } /// /// 资源释放 /// public static void Dispose() { mInstance = null; } } /// /// 普通单例创建类 /// internal static class SingletonCreator { static T CreateNonPublicConstructorObject() 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() where T : class, ISingleton { var type = typeof(T); var monoBehaviourType = typeof(MonoBehaviour); if (monoBehaviourType.IsAssignableFrom(type)) { return CreateMonoSingleton(); } else { var instance = CreateNonPublicConstructorObject(); instance.OnSingletonInit(); return instance; } } /// /// 单元测试模式 标签 /// public static bool IsUnitTestMode { get; set; } /// /// 查找Obj(一个嵌套查找Obj的过程) /// /// 父节点 /// 拆分后的路径节点 /// 下标 /// true /// 不要销毁 标签 /// 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); } /// /// 泛型方法:创建MonoBehaviour单例 /// /// /// public static T CreateMonoSingleton() 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(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; } /// /// 在GameObject上创建T组件(脚本) /// /// /// 路径(应该就是Hierarchy下的树结构路径) /// 不要销毁 标签 /// private static T CreateComponentOnGameObject(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; } /// /// 查找Obj(对于路径 进行拆分) /// /// 路径 /// true /// 不要销毁 标签 /// 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); } } /// /// 静态类:MonoBehaviour类的单例 /// 泛型类:Where约束表示T类型必须继承MonoSingleton /// /// internal abstract class MonoSingleton : MonoBehaviour, ISingleton where T : MonoSingleton { /// /// 静态实例 /// protected static T mInstance; /// /// 静态属性:封装相关实例对象 /// public static T Instance { get { if (mInstance == null && !mOnApplicationQuit) { mInstance = SingletonCreator.CreateMonoSingleton(); } return mInstance; } } /// /// 实现接口的单例初始化 /// public virtual void OnSingletonInit() { } /// /// 资源释放 /// 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); } } /// /// 当前应用程序是否结束 标签 /// protected static bool mOnApplicationQuit = false; /// /// 应用程序退出:释放当前对象并销毁相关GameObject /// protected virtual void OnApplicationQuit() { mOnApplicationQuit = true; if (mInstance == null) return; Destroy(mInstance.gameObject); mInstance = null; } /// /// 释放当前对象 /// protected virtual void OnDestroy() { mInstance = null; } /// /// 判断当前应用程序是否退出 /// public static bool IsApplicationQuit { get { return mOnApplicationQuit; } } } /// /// MonoSingleton路径 /// [AttributeUsage(AttributeTargets.Class)] //这个特性只能标记在Class上 internal class MonoSingletonPath : Attribute { private string mPathInHierarchy; public MonoSingletonPath(string pathInHierarchy) { mPathInHierarchy = pathInHierarchy; } public string PathInHierarchy { get { return mPathInHierarchy; } } } /// /// 继承Mono的属性单例? /// /// internal static class MonoSingletonProperty where T : MonoBehaviour, ISingleton { private static T mInstance; public static T Instance { get { if (null == mInstance) { mInstance = SingletonCreator.CreateMonoSingleton(); } return mInstance; } } public static void Dispose() { if (SingletonCreator.IsUnitTestMode) { UnityEngine.Object.DestroyImmediate(mInstance.gameObject); } else { UnityEngine.Object.Destroy(mInstance.gameObject); } mInstance = null; } } /// /// 如果跳转到新的场景里已经有了实例,则不创建新的单例(或者创建新的单例后会销毁掉新的单例) /// /// internal abstract class PersistentMonoSingleton : MonoBehaviour where T : Component { protected static T mInstance; protected bool mEnabled; /// /// Singleton design pattern /// /// The instance. public static T Instance { get { if (mInstance == null) { mInstance = FindObjectOfType(); if (mInstance == null) { var obj = new GameObject(); mInstance = obj.AddComponent(); } } return mInstance; } } /// /// On awake, we check if there's already a copy of the object in the scene. If there's one, we destroy it. /// 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); } } } } /// /// 如果跳转到新的场景里已经有了实例,则删除已有示例,再创建新的实例 /// /// internal class ReplaceableMonoSingleton : MonoBehaviour where T : Component { protected static T mInstance; public float InitializationTime; /// /// Singleton design pattern /// /// The instance. public static T Instance { get { if (mInstance == null) { mInstance = FindObjectOfType(); if (mInstance == null) { GameObject obj = new GameObject(); obj.hideFlags = HideFlags.HideAndDontSave; mInstance = obj.AddComponent(); } } return mInstance; } } /// /// On awake, we check if there's already a copy of the object in the scene. If there's one, we destroy it. /// 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(); 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>().InitializationTime < InitializationTime) { Destroy(searched.gameObject); } } } if (mInstance == null) { mInstance = this as T; } } } #endregion }