PoolKit.cs 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Reflection;
  5. using UnityEngine;
  6. namespace QFramework
  7. {
  8. #region API
  9. /// <summary>
  10. /// Unity 游戏框架搭建 (十九) 简易对象池:http://qframework.io/post/24/ 的例子
  11. /// </summary>
  12. /// <typeparam name="T"></typeparam>
  13. public class SimpleObjectPool<T> : Pool<T>
  14. {
  15. readonly Action<T> mResetMethod;
  16. public SimpleObjectPool(Func<T> factoryMethod, Action<T> resetMethod = null,int initCount = 0)
  17. {
  18. mFactory = new CustomObjectFactory<T>(factoryMethod);
  19. mResetMethod = resetMethod;
  20. for (int i = 0; i < initCount; i++)
  21. {
  22. mCacheStack.Push(mFactory.Create());
  23. }
  24. }
  25. public override bool Recycle(T obj)
  26. {
  27. if (mResetMethod != null)
  28. {
  29. mResetMethod.Invoke(obj);
  30. }
  31. mCacheStack.Push(obj);
  32. return true;
  33. }
  34. }
  35. /// <summary>
  36. /// Object pool.
  37. /// </summary>
  38. public class SafeObjectPool<T> : Pool<T>, ISingleton where T : IPoolable, new()
  39. {
  40. #region Singleton
  41. void ISingleton.OnSingletonInit() {}
  42. protected SafeObjectPool()
  43. {
  44. mFactory = new DefaultObjectFactory<T>();
  45. }
  46. public static SafeObjectPool<T> Instance
  47. {
  48. get { return SingletonProperty<SafeObjectPool<T>>.Instance; }
  49. }
  50. public void Dispose()
  51. {
  52. SingletonProperty<SafeObjectPool<T>>.Dispose();
  53. }
  54. #endregion
  55. /// <summary>
  56. /// Init the specified maxCount and initCount.
  57. /// </summary>
  58. /// <param name="maxCount">Max Cache count.</param>
  59. /// <param name="initCount">Init Cache count.</param>
  60. public void Init(int maxCount, int initCount)
  61. {
  62. MaxCacheCount = maxCount;
  63. if (maxCount > 0)
  64. {
  65. initCount = Math.Min(maxCount, initCount);
  66. }
  67. if (CurCount < initCount)
  68. {
  69. for (var i = CurCount; i < initCount; ++i)
  70. {
  71. Recycle(new T());
  72. }
  73. }
  74. }
  75. /// <summary>
  76. /// Gets or sets the max cache count.
  77. /// </summary>
  78. /// <value>The max cache count.</value>
  79. public int MaxCacheCount
  80. {
  81. get { return mMaxCount; }
  82. set
  83. {
  84. mMaxCount = value;
  85. if (mCacheStack != null)
  86. {
  87. if (mMaxCount > 0)
  88. {
  89. if (mMaxCount < mCacheStack.Count)
  90. {
  91. int removeCount = mCacheStack.Count - mMaxCount;
  92. while (removeCount > 0)
  93. {
  94. mCacheStack.Pop();
  95. --removeCount;
  96. }
  97. }
  98. }
  99. }
  100. }
  101. }
  102. /// <summary>
  103. /// Allocate T instance.
  104. /// </summary>
  105. public override T Allocate()
  106. {
  107. var result = base.Allocate();
  108. result.IsRecycled = false;
  109. return result;
  110. }
  111. /// <summary>
  112. /// Recycle the T instance
  113. /// </summary>
  114. /// <param name="t">T.</param>
  115. public override bool Recycle(T t)
  116. {
  117. if (t == null || t.IsRecycled)
  118. {
  119. return false;
  120. }
  121. if (mMaxCount > 0)
  122. {
  123. if (mCacheStack.Count >= mMaxCount)
  124. {
  125. t.OnRecycled();
  126. return false;
  127. }
  128. }
  129. t.IsRecycled = true;
  130. t.OnRecycled();
  131. mCacheStack.Push(t);
  132. return true;
  133. }
  134. }
  135. /// <summary>
  136. /// Object pool 4 class who no public constructor
  137. /// such as SingletonClass.QEventSystem
  138. /// </summary>
  139. public class NonPublicObjectPool<T> :Pool<T>,ISingleton where T : class,IPoolable
  140. {
  141. #region Singleton
  142. public void OnSingletonInit(){}
  143. public static NonPublicObjectPool<T> Instance
  144. {
  145. get { return SingletonProperty<NonPublicObjectPool<T>>.Instance; }
  146. }
  147. protected NonPublicObjectPool()
  148. {
  149. mFactory = new NonPublicObjectFactory<T>();
  150. }
  151. public void Dispose()
  152. {
  153. SingletonProperty<NonPublicObjectPool<T>>.Dispose();
  154. }
  155. #endregion
  156. /// <summary>
  157. /// Init the specified maxCount and initCount.
  158. /// </summary>
  159. /// <param name="maxCount">Max Cache count.</param>
  160. /// <param name="initCount">Init Cache count.</param>
  161. public void Init(int maxCount, int initCount)
  162. {
  163. if (maxCount > 0)
  164. {
  165. initCount = Math.Min(maxCount, initCount);
  166. }
  167. if (CurCount >= initCount) return;
  168. for (var i = CurCount; i < initCount; ++i)
  169. {
  170. Recycle(mFactory.Create());
  171. }
  172. }
  173. /// <summary>
  174. /// Gets or sets the max cache count.
  175. /// </summary>
  176. /// <value>The max cache count.</value>
  177. public int MaxCacheCount
  178. {
  179. get { return mMaxCount; }
  180. set
  181. {
  182. mMaxCount = value;
  183. if (mCacheStack == null) return;
  184. if (mMaxCount <= 0) return;
  185. if (mMaxCount >= mCacheStack.Count) return;
  186. var removeCount = mMaxCount - mCacheStack.Count;
  187. while (removeCount > 0)
  188. {
  189. mCacheStack.Pop();
  190. --removeCount;
  191. }
  192. }
  193. }
  194. /// <summary>
  195. /// Allocate T instance.
  196. /// </summary>
  197. public override T Allocate()
  198. {
  199. var result = base.Allocate();
  200. result.IsRecycled = false;
  201. return result;
  202. }
  203. /// <summary>
  204. /// Recycle the T instance
  205. /// </summary>
  206. /// <param name="t">T.</param>
  207. public override bool Recycle(T t)
  208. {
  209. if (t == null || t.IsRecycled)
  210. {
  211. return false;
  212. }
  213. if (mMaxCount > 0)
  214. {
  215. if (mCacheStack.Count >= mMaxCount)
  216. {
  217. t.OnRecycled();
  218. return false;
  219. }
  220. }
  221. t.IsRecycled = true;
  222. t.OnRecycled();
  223. mCacheStack.Push(t);
  224. return true;
  225. }
  226. }
  227. public abstract class AbstractPool<T> where T : AbstractPool<T>, new()
  228. {
  229. private static Stack<T> mPool = new Stack<T>(10);
  230. protected bool mInPool = false;
  231. public static T Allocate()
  232. {
  233. var node = mPool.Count == 0 ? new T() : mPool.Pop();
  234. node.mInPool = false;
  235. return node;
  236. }
  237. public void Recycle2Cache()
  238. {
  239. OnRecycle();
  240. mInPool = true;
  241. mPool.Push(this as T);
  242. }
  243. protected abstract void OnRecycle();
  244. }
  245. #endregion
  246. #region interfaces
  247. /// <summary>
  248. /// 对象池接口
  249. /// </summary>
  250. /// <typeparam name="T"></typeparam>
  251. public interface IPool<T>
  252. {
  253. /// <summary>
  254. /// 分配对象
  255. /// </summary>
  256. /// <returns></returns>
  257. T Allocate();
  258. /// <summary>
  259. /// 回收对象
  260. /// </summary>
  261. /// <param name="obj"></param>
  262. /// <returns></returns>
  263. bool Recycle(T obj);
  264. }
  265. /// <summary>
  266. /// I pool able.
  267. /// </summary>
  268. public interface IPoolable
  269. {
  270. void OnRecycled();
  271. bool IsRecycled { get; set; }
  272. }
  273. /// <summary>
  274. /// I cache type.
  275. /// </summary>
  276. public interface IPoolType
  277. {
  278. void Recycle2Cache();
  279. }
  280. /// <summary>
  281. /// 对象池
  282. /// </summary>
  283. /// <typeparam name="T"></typeparam>
  284. public abstract class Pool<T> : IPool<T>
  285. {
  286. #region ICountObserverable
  287. /// <summary>
  288. /// Gets the current count.
  289. /// </summary>
  290. /// <value>The current count.</value>
  291. public int CurCount
  292. {
  293. get { return mCacheStack.Count; }
  294. }
  295. #endregion
  296. protected IObjectFactory<T> mFactory;
  297. /// <summary>
  298. /// 存储相关数据的栈
  299. /// </summary>
  300. protected readonly Stack<T> mCacheStack = new Stack<T>();
  301. /// <summary>
  302. /// default is 5
  303. /// </summary>
  304. protected int mMaxCount = 12;
  305. public virtual T Allocate()
  306. {
  307. return mCacheStack.Count == 0
  308. ? mFactory.Create()
  309. : mCacheStack.Pop();
  310. }
  311. public abstract bool Recycle(T obj);
  312. }
  313. #endregion
  314. #region DataStructurePool
  315. /// <summary>
  316. /// 字典对象池:用于存储相关对象
  317. /// </summary>
  318. /// <typeparam name="TKey"></typeparam>
  319. /// <typeparam name="TValue"></typeparam>
  320. public class DictionaryPool<TKey, TValue>
  321. {
  322. /// <summary>
  323. /// 栈对象:存储多个字典
  324. /// </summary>
  325. static Stack<Dictionary<TKey, TValue>> mListStack = new Stack<Dictionary<TKey, TValue>>(8);
  326. /// <summary>
  327. /// 出栈:从栈中获取某个字典数据
  328. /// </summary>
  329. /// <returns></returns>
  330. public static Dictionary<TKey, TValue> Get()
  331. {
  332. if (mListStack.Count == 0)
  333. {
  334. return new Dictionary<TKey, TValue>(8);
  335. }
  336. return mListStack.Pop();
  337. }
  338. /// <summary>
  339. /// 入栈:将字典数据存储到栈中
  340. /// </summary>
  341. /// <param name="toRelease"></param>
  342. public static void Release(Dictionary<TKey, TValue> toRelease)
  343. {
  344. toRelease.Clear();
  345. mListStack.Push(toRelease);
  346. }
  347. }
  348. /// <summary>
  349. /// 对象池字典 拓展方法类
  350. /// </summary>
  351. public static class DictionaryPoolExtensions
  352. {
  353. /// <summary>
  354. /// 对字典拓展 自身入栈 的方法
  355. /// </summary>
  356. /// <typeparam name="TKey"></typeparam>
  357. /// <typeparam name="TValue"></typeparam>
  358. /// <param name="toRelease"></param>
  359. public static void Release2Pool<TKey,TValue>(this Dictionary<TKey, TValue> toRelease)
  360. {
  361. DictionaryPool<TKey,TValue>.Release(toRelease);
  362. }
  363. }
  364. /// <summary>
  365. /// 链表对象池:存储相关对象
  366. /// </summary>
  367. /// <typeparam name="T"></typeparam>
  368. public static class ListPool<T>
  369. {
  370. /// <summary>
  371. /// 栈对象:存储多个List
  372. /// </summary>
  373. static Stack<List<T>> mListStack = new Stack<List<T>>(8);
  374. /// <summary>
  375. /// 出栈:获取某个List对象
  376. /// </summary>
  377. /// <returns></returns>
  378. public static List<T> Get()
  379. {
  380. if (mListStack.Count == 0)
  381. {
  382. return new List<T>(8);
  383. }
  384. return mListStack.Pop();
  385. }
  386. /// <summary>
  387. /// 入栈:将List对象添加到栈中
  388. /// </summary>
  389. /// <param name="toRelease"></param>
  390. public static void Release(List<T> toRelease)
  391. {
  392. toRelease.Clear();
  393. mListStack.Push(toRelease);
  394. }
  395. }
  396. /// <summary>
  397. /// 链表对象池 拓展方法类
  398. /// </summary>
  399. public static class ListPoolExtensions
  400. {
  401. /// <summary>
  402. /// 给List拓展 自身入栈 的方法
  403. /// </summary>
  404. /// <typeparam name="T"></typeparam>
  405. /// <param name="toRelease"></param>
  406. public static void Release2Pool<T>(this List<T> toRelease)
  407. {
  408. ListPool<T>.Release(toRelease);
  409. }
  410. }
  411. #endregion
  412. #region Factories
  413. /// <summary>
  414. /// 对象工厂
  415. /// </summary>
  416. public class ObjectFactory
  417. {
  418. /// <summary>
  419. /// 动态创建类的实例:创建有参的构造函数
  420. /// </summary>
  421. /// <param name="type"></param>
  422. /// <param name="constructorArgs"></param>
  423. /// <returns></returns>
  424. public static object Create(Type type, params object[] constructorArgs)
  425. {
  426. return Activator.CreateInstance(type, constructorArgs);
  427. }
  428. /// <summary>
  429. /// 动态创建类的实例:泛型扩展
  430. /// </summary>
  431. /// <typeparam name="T"></typeparam>
  432. /// <param name="constructorArgs"></param>
  433. /// <returns></returns>
  434. public static T Create<T>(params object[] constructorArgs)
  435. {
  436. return (T) Create(typeof(T), constructorArgs);
  437. }
  438. /// <summary>
  439. /// 动态创建类的实例:创建无参/私有的构造函数
  440. /// </summary>
  441. /// <param name="type"></param>
  442. /// <returns></returns>
  443. public static object CreateNonPublicConstructorObject(Type type)
  444. {
  445. // 获取私有构造函数
  446. var constructorInfos = type.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
  447. // 获取无参构造函数
  448. var ctor = Array.Find(constructorInfos, c => c.GetParameters().Length == 0);
  449. if (ctor == null)
  450. {
  451. throw new Exception("Non-Public Constructor() not found! in " + type);
  452. }
  453. return ctor.Invoke(null);
  454. }
  455. /// <summary>
  456. /// 动态创建类的实例:创建无参/私有的构造函数 泛型扩展
  457. /// </summary>
  458. /// <typeparam name="T"></typeparam>
  459. /// <returns></returns>
  460. public static T CreateNonPublicConstructorObject<T>()
  461. {
  462. return (T) CreateNonPublicConstructorObject(typeof(T));
  463. }
  464. /// <summary>
  465. /// 创建带有初始化回调的 对象
  466. /// </summary>
  467. /// <param name="type"></param>
  468. /// <param name="onObjectCreate"></param>
  469. /// <param name="constructorArgs"></param>
  470. /// <returns></returns>
  471. public static object CreateWithInitialAction(Type type, Action<object> onObjectCreate,
  472. params object[] constructorArgs)
  473. {
  474. var obj = Create(type, constructorArgs);
  475. onObjectCreate(obj);
  476. return obj;
  477. }
  478. /// <summary>
  479. /// 创建带有初始化回调的 对象:泛型扩展
  480. /// </summary>
  481. /// <typeparam name="T"></typeparam>
  482. /// <param name="onObjectCreate"></param>
  483. /// <param name="constructorArgs"></param>
  484. /// <returns></returns>
  485. public static T CreateWithInitialAction<T>(Action<T> onObjectCreate,
  486. params object[] constructorArgs)
  487. {
  488. var obj = Create<T>(constructorArgs);
  489. onObjectCreate(obj);
  490. return obj;
  491. }
  492. }
  493. /// <summary>
  494. /// 自定义对象工厂:相关对象是 自己定义
  495. /// </summary>
  496. /// <typeparam name="T"></typeparam>
  497. public class CustomObjectFactory<T> : IObjectFactory<T>
  498. {
  499. public CustomObjectFactory(Func<T> factoryMethod)
  500. {
  501. mFactoryMethod = factoryMethod;
  502. }
  503. protected Func<T> mFactoryMethod;
  504. public T Create()
  505. {
  506. return mFactoryMethod();
  507. }
  508. }
  509. /// <summary>
  510. /// 默认对象工厂:相关对象是通过New 出来的
  511. /// </summary>
  512. /// <typeparam name="T"></typeparam>
  513. public class DefaultObjectFactory<T> : IObjectFactory<T> where T : new()
  514. {
  515. public T Create()
  516. {
  517. return new T();
  518. }
  519. }
  520. /// <summary>
  521. /// 对象工厂接口
  522. /// </summary>
  523. /// <typeparam name="T"></typeparam>
  524. public interface IObjectFactory<T>
  525. {
  526. /// <summary>
  527. /// 创建对象
  528. /// </summary>
  529. /// <returns></returns>
  530. T Create();
  531. }
  532. /// <summary>
  533. /// 没有公共构造函数的对象工厂:相关对象只能通过反射获得
  534. /// </summary>
  535. /// <typeparam name="T"></typeparam>
  536. public class NonPublicObjectFactory<T> : IObjectFactory<T> where T : class
  537. {
  538. public T Create()
  539. {
  540. var ctors = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
  541. var ctor = Array.Find(ctors, c => c.GetParameters().Length == 0);
  542. if (ctor == null)
  543. {
  544. throw new Exception("Non-Public Constructor() not found! in " + typeof(T) + "\n 在没有找到非 public 的构造方法");
  545. }
  546. return ctor.Invoke(null) as T;
  547. }
  548. }
  549. #endregion
  550. #region SingletonKit For Pool
  551. /// <summary>
  552. /// 单例接口
  553. /// </summary>
  554. internal interface ISingleton
  555. {
  556. /// <summary>
  557. /// 单例初始化(继承当前接口的类都需要实现该方法)
  558. /// </summary>
  559. void OnSingletonInit();
  560. }
  561. /// <summary>
  562. /// 普通类的单例
  563. /// </summary>
  564. /// <typeparam name="T"></typeparam>
  565. internal abstract class Singleton<T> : ISingleton where T : Singleton<T>
  566. {
  567. /// <summary>
  568. /// 静态实例
  569. /// </summary>
  570. protected static T mInstance;
  571. /// <summary>
  572. /// 标签锁:确保当一个线程位于代码的临界区时,另一个线程不进入临界区。
  573. /// 如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放
  574. /// </summary>
  575. static object mLock = new object();
  576. /// <summary>
  577. /// 静态属性
  578. /// </summary>
  579. public static T Instance
  580. {
  581. get
  582. {
  583. lock (mLock)
  584. {
  585. if (mInstance == null)
  586. {
  587. mInstance = SingletonCreator.CreateSingleton<T>();
  588. }
  589. }
  590. return mInstance;
  591. }
  592. }
  593. /// <summary>
  594. /// 资源释放
  595. /// </summary>
  596. public virtual void Dispose()
  597. {
  598. mInstance = null;
  599. }
  600. /// <summary>
  601. /// 单例初始化方法
  602. /// </summary>
  603. public virtual void OnSingletonInit()
  604. {
  605. }
  606. }
  607. /// <summary>
  608. /// 属性单例类
  609. /// </summary>
  610. /// <typeparam name="T"></typeparam>
  611. internal static class SingletonProperty<T> where T : class, ISingleton
  612. {
  613. /// <summary>
  614. /// 静态实例
  615. /// </summary>
  616. private static T mInstance;
  617. /// <summary>
  618. /// 标签锁
  619. /// </summary>
  620. private static readonly object mLock = new object();
  621. /// <summary>
  622. /// 静态属性
  623. /// </summary>
  624. public static T Instance
  625. {
  626. get
  627. {
  628. lock (mLock)
  629. {
  630. if (mInstance == null)
  631. {
  632. mInstance = SingletonCreator.CreateSingleton<T>();
  633. }
  634. }
  635. return mInstance;
  636. }
  637. }
  638. /// <summary>
  639. /// 资源释放
  640. /// </summary>
  641. public static void Dispose()
  642. {
  643. mInstance = null;
  644. }
  645. }
  646. /// <summary>
  647. /// 普通单例创建类
  648. /// </summary>
  649. internal static class SingletonCreator
  650. {
  651. static T CreateNonPublicConstructorObject<T>() where T : class
  652. {
  653. var type = typeof(T);
  654. // 获取私有构造函数
  655. var constructorInfos = type.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
  656. // 获取无参构造函数
  657. var ctor = Array.Find(constructorInfos, c => c.GetParameters().Length == 0);
  658. if (ctor == null)
  659. {
  660. throw new Exception("Non-Public Constructor() not found! in " + type);
  661. }
  662. return ctor.Invoke(null) as T;
  663. }
  664. public static T CreateSingleton<T>() where T : class, ISingleton
  665. {
  666. var type = typeof(T);
  667. var monoBehaviourType = typeof(MonoBehaviour);
  668. if (monoBehaviourType.IsAssignableFrom(type))
  669. {
  670. return CreateMonoSingleton<T>();
  671. }
  672. else
  673. {
  674. var instance = CreateNonPublicConstructorObject<T>();
  675. instance.OnSingletonInit();
  676. return instance;
  677. }
  678. }
  679. /// <summary>
  680. /// 单元测试模式 标签
  681. /// </summary>
  682. public static bool IsUnitTestMode { get; set; }
  683. /// <summary>
  684. /// 查找Obj(一个嵌套查找Obj的过程)
  685. /// </summary>
  686. /// <param name="root">父节点</param>
  687. /// <param name="subPath">拆分后的路径节点</param>
  688. /// <param name="index">下标</param>
  689. /// <param name="build">true</param>
  690. /// <param name="dontDestroy">不要销毁 标签</param>
  691. /// <returns></returns>
  692. private static GameObject FindGameObject(GameObject root, string[] subPath, int index, bool build,
  693. bool dontDestroy)
  694. {
  695. GameObject client = null;
  696. if (root == null)
  697. {
  698. client = GameObject.Find(subPath[index]);
  699. }
  700. else
  701. {
  702. var child = root.transform.Find(subPath[index]);
  703. if (child != null)
  704. {
  705. client = child.gameObject;
  706. }
  707. }
  708. if (client == null)
  709. {
  710. if (build)
  711. {
  712. client = new GameObject(subPath[index]);
  713. if (root != null)
  714. {
  715. client.transform.SetParent(root.transform);
  716. }
  717. if (dontDestroy && index == 0 && !IsUnitTestMode)
  718. {
  719. GameObject.DontDestroyOnLoad(client);
  720. }
  721. }
  722. }
  723. if (client == null)
  724. {
  725. return null;
  726. }
  727. return ++index == subPath.Length ? client : FindGameObject(client, subPath, index, build, dontDestroy);
  728. }
  729. /// <summary>
  730. /// 泛型方法:创建MonoBehaviour单例
  731. /// </summary>
  732. /// <typeparam name="T"></typeparam>
  733. /// <returns></returns>
  734. public static T CreateMonoSingleton<T>() where T : class, ISingleton
  735. {
  736. T instance = null;
  737. var type = typeof(T);
  738. //判断T实例存在的条件是否满足
  739. if (!IsUnitTestMode && !Application.isPlaying)
  740. return instance;
  741. //判断当前场景中是否存在T实例
  742. instance = UnityEngine.Object.FindObjectOfType(type) as T;
  743. if (instance != null)
  744. {
  745. instance.OnSingletonInit();
  746. return instance;
  747. }
  748. //MemberInfo:获取有关成员属性的信息并提供对成员元数据的访问
  749. MemberInfo info = typeof(T);
  750. //获取T类型 自定义属性,并找到相关路径属性,利用该属性创建T实例
  751. var attributes = info.GetCustomAttributes(true);
  752. foreach (var atribute in attributes)
  753. {
  754. var defineAttri = atribute as MonoSingletonPath;
  755. if (defineAttri == null)
  756. {
  757. continue;
  758. }
  759. instance = CreateComponentOnGameObject<T>(defineAttri.PathInHierarchy, true);
  760. break;
  761. }
  762. //如果还是无法找到instance 则主动去创建同名Obj 并挂载相关脚本 组件
  763. if (instance == null)
  764. {
  765. var obj = new GameObject(typeof(T).Name);
  766. if (!IsUnitTestMode)
  767. UnityEngine.Object.DontDestroyOnLoad(obj);
  768. instance = obj.AddComponent(typeof(T)) as T;
  769. }
  770. instance.OnSingletonInit();
  771. return instance;
  772. }
  773. /// <summary>
  774. /// 在GameObject上创建T组件(脚本)
  775. /// </summary>
  776. /// <typeparam name="T"></typeparam>
  777. /// <param name="path">路径(应该就是Hierarchy下的树结构路径)</param>
  778. /// <param name="dontDestroy">不要销毁 标签</param>
  779. /// <returns></returns>
  780. private static T CreateComponentOnGameObject<T>(string path, bool dontDestroy) where T : class
  781. {
  782. var obj = FindGameObject(path, true, dontDestroy);
  783. if (obj == null)
  784. {
  785. obj = new GameObject("Singleton of " + typeof(T).Name);
  786. if (dontDestroy && !IsUnitTestMode)
  787. {
  788. UnityEngine.Object.DontDestroyOnLoad(obj);
  789. }
  790. }
  791. return obj.AddComponent(typeof(T)) as T;
  792. }
  793. /// <summary>
  794. /// 查找Obj(对于路径 进行拆分)
  795. /// </summary>
  796. /// <param name="path">路径</param>
  797. /// <param name="build">true</param>
  798. /// <param name="dontDestroy">不要销毁 标签</param>
  799. /// <returns></returns>
  800. private static GameObject FindGameObject(string path, bool build, bool dontDestroy)
  801. {
  802. if (string.IsNullOrEmpty(path))
  803. {
  804. return null;
  805. }
  806. var subPath = path.Split('/');
  807. if (subPath == null || subPath.Length == 0)
  808. {
  809. return null;
  810. }
  811. return FindGameObject(null, subPath, 0, build, dontDestroy);
  812. }
  813. }
  814. /// <summary>
  815. /// 静态类:MonoBehaviour类的单例
  816. /// 泛型类:Where约束表示T类型必须继承MonoSingleton<T>
  817. /// </summary>
  818. /// <typeparam name="T"></typeparam>
  819. internal abstract class MonoSingleton<T> : MonoBehaviour, ISingleton where T : MonoSingleton<T>
  820. {
  821. /// <summary>
  822. /// 静态实例
  823. /// </summary>
  824. protected static T mInstance;
  825. /// <summary>
  826. /// 静态属性:封装相关实例对象
  827. /// </summary>
  828. public static T Instance
  829. {
  830. get
  831. {
  832. if (mInstance == null && !mOnApplicationQuit)
  833. {
  834. mInstance = SingletonCreator.CreateMonoSingleton<T>();
  835. }
  836. return mInstance;
  837. }
  838. }
  839. /// <summary>
  840. /// 实现接口的单例初始化
  841. /// </summary>
  842. public virtual void OnSingletonInit()
  843. {
  844. }
  845. /// <summary>
  846. /// 资源释放
  847. /// </summary>
  848. public virtual void Dispose()
  849. {
  850. if (SingletonCreator.IsUnitTestMode)
  851. {
  852. var curTrans = transform;
  853. do
  854. {
  855. var parent = curTrans.parent;
  856. DestroyImmediate(curTrans.gameObject);
  857. curTrans = parent;
  858. } while (curTrans != null);
  859. mInstance = null;
  860. }
  861. else
  862. {
  863. Destroy(gameObject);
  864. }
  865. }
  866. /// <summary>
  867. /// 当前应用程序是否结束 标签
  868. /// </summary>
  869. protected static bool mOnApplicationQuit = false;
  870. /// <summary>
  871. /// 应用程序退出:释放当前对象并销毁相关GameObject
  872. /// </summary>
  873. protected virtual void OnApplicationQuit()
  874. {
  875. mOnApplicationQuit = true;
  876. if (mInstance == null) return;
  877. Destroy(mInstance.gameObject);
  878. mInstance = null;
  879. }
  880. /// <summary>
  881. /// 释放当前对象
  882. /// </summary>
  883. protected virtual void OnDestroy()
  884. {
  885. mInstance = null;
  886. }
  887. /// <summary>
  888. /// 判断当前应用程序是否退出
  889. /// </summary>
  890. public static bool IsApplicationQuit
  891. {
  892. get { return mOnApplicationQuit; }
  893. }
  894. }
  895. /// <summary>
  896. /// MonoSingleton路径
  897. /// </summary>
  898. [AttributeUsage(AttributeTargets.Class)] //这个特性只能标记在Class上
  899. internal class MonoSingletonPath : Attribute
  900. {
  901. private string mPathInHierarchy;
  902. public MonoSingletonPath(string pathInHierarchy)
  903. {
  904. mPathInHierarchy = pathInHierarchy;
  905. }
  906. public string PathInHierarchy
  907. {
  908. get { return mPathInHierarchy; }
  909. }
  910. }
  911. /// <summary>
  912. /// 继承Mono的属性单例?
  913. /// </summary>
  914. /// <typeparam name="T"></typeparam>
  915. internal static class MonoSingletonProperty<T> where T : MonoBehaviour, ISingleton
  916. {
  917. private static T mInstance;
  918. public static T Instance
  919. {
  920. get
  921. {
  922. if (null == mInstance)
  923. {
  924. mInstance = SingletonCreator.CreateMonoSingleton<T>();
  925. }
  926. return mInstance;
  927. }
  928. }
  929. public static void Dispose()
  930. {
  931. if (SingletonCreator.IsUnitTestMode)
  932. {
  933. UnityEngine.Object.DestroyImmediate(mInstance.gameObject);
  934. }
  935. else
  936. {
  937. UnityEngine.Object.Destroy(mInstance.gameObject);
  938. }
  939. mInstance = null;
  940. }
  941. }
  942. /// <summary>
  943. /// 如果跳转到新的场景里已经有了实例,则不创建新的单例(或者创建新的单例后会销毁掉新的单例)
  944. /// </summary>
  945. /// <typeparam name="T"></typeparam>
  946. internal abstract class PersistentMonoSingleton<T> : MonoBehaviour where T : Component
  947. {
  948. protected static T mInstance;
  949. protected bool mEnabled;
  950. /// <summary>
  951. /// Singleton design pattern
  952. /// </summary>
  953. /// <value>The instance.</value>
  954. public static T Instance
  955. {
  956. get
  957. {
  958. if (mInstance == null)
  959. {
  960. mInstance = FindObjectOfType<T>();
  961. if (mInstance == null)
  962. {
  963. var obj = new GameObject();
  964. mInstance = obj.AddComponent<T>();
  965. }
  966. }
  967. return mInstance;
  968. }
  969. }
  970. /// <summary>
  971. /// On awake, we check if there's already a copy of the object in the scene. If there's one, we destroy it.
  972. /// </summary>
  973. protected virtual void Awake()
  974. {
  975. if (!Application.isPlaying)
  976. {
  977. return;
  978. }
  979. if (mInstance == null)
  980. {
  981. //If I am the first instance, make me the Singleton
  982. mInstance = this as T;
  983. DontDestroyOnLoad(transform.gameObject);
  984. mEnabled = true;
  985. }
  986. else
  987. {
  988. //If a Singleton already exists and you find
  989. //another reference in scene, destroy it!
  990. if (this != mInstance)
  991. {
  992. Destroy(this.gameObject);
  993. }
  994. }
  995. }
  996. }
  997. /// <summary>
  998. /// 如果跳转到新的场景里已经有了实例,则删除已有示例,再创建新的实例
  999. /// </summary>
  1000. /// <typeparam name="T"></typeparam>
  1001. internal class ReplaceableMonoSingleton<T> : MonoBehaviour where T : Component
  1002. {
  1003. protected static T mInstance;
  1004. public float InitializationTime;
  1005. /// <summary>
  1006. /// Singleton design pattern
  1007. /// </summary>
  1008. /// <value>The instance.</value>
  1009. public static T Instance
  1010. {
  1011. get
  1012. {
  1013. if (mInstance == null)
  1014. {
  1015. mInstance = FindObjectOfType<T>();
  1016. if (mInstance == null)
  1017. {
  1018. GameObject obj = new GameObject();
  1019. obj.hideFlags = HideFlags.HideAndDontSave;
  1020. mInstance = obj.AddComponent<T>();
  1021. }
  1022. }
  1023. return mInstance;
  1024. }
  1025. }
  1026. /// <summary>
  1027. /// On awake, we check if there's already a copy of the object in the scene. If there's one, we destroy it.
  1028. /// </summary>
  1029. protected virtual void Awake()
  1030. {
  1031. if (!Application.isPlaying)
  1032. {
  1033. return;
  1034. }
  1035. InitializationTime = Time.time;
  1036. DontDestroyOnLoad(this.gameObject);
  1037. // we check for existing objects of the same type
  1038. T[] check = FindObjectsOfType<T>();
  1039. foreach (T searched in check)
  1040. {
  1041. if (searched != this)
  1042. {
  1043. // if we find another object of the same type (not this), and if it's older than our current object, we destroy it.
  1044. if (searched.GetComponent<ReplaceableMonoSingleton<T>>().InitializationTime < InitializationTime)
  1045. {
  1046. Destroy(searched.gameObject);
  1047. }
  1048. }
  1049. }
  1050. if (mInstance == null)
  1051. {
  1052. mInstance = this as T;
  1053. }
  1054. }
  1055. }
  1056. #endregion
  1057. }