AudioKitDependency.cs 33 KB

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