PoolKit4UIKit.cs 32 KB

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