BetterList.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. //-------------------------------------------------
  2. // NGUI: Next-Gen UI kit
  3. // Copyright © 2011-2017 Tasharen Entertainment Inc
  4. //-------------------------------------------------
  5. #if !COMBAT_SERVER
  6. using UnityEngine;
  7. #endif
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Diagnostics;
  11. using CombatLibrary.CombatLibrary.CombatCore;
  12. #if !COMBAT_SERVER
  13. using Debug = UnityEngine.Debug;
  14. #endif
  15. /// <summary>
  16. /// This improved version of the System.Collections.Generic.List that doesn't release the buffer on Clear(),
  17. /// resulting in better performance and less garbage collection.
  18. /// PRO: BetterList performs faster than List when you Add and Remove items (although slower if you remove from the beginning).
  19. /// CON: BetterList performs worse when sorting the list. If your operations involve sorting, use the standard List instead.
  20. /// </summary>
  21. public class BetterList<T> : IDisposable
  22. {
  23. public int tranId;
  24. #if UNITY_FLASH
  25. List<T> mList = new List<T>();
  26. /// <summary>
  27. /// Direct access to the buffer. Note that you should not use its 'Length' parameter, but instead use BetterList.size.
  28. /// </summary>
  29. public T this[int i]
  30. {
  31. get { return mList[i]; }
  32. set { mList[i] = value; }
  33. }
  34. /// <summary>
  35. /// Compatibility with the non-flash syntax.
  36. /// </summary>
  37. public List<T> buffer { get { return mList; } }
  38. /// <summary>
  39. /// Direct access to the buffer's size. Note that it's only public for speed and efficiency. You shouldn't modify it.
  40. /// </summary>
  41. public int size { get { return mList.Count; } }
  42. /// <summary>
  43. /// For 'foreach' functionality.
  44. /// </summary>
  45. public IEnumerator<T> GetEnumerator () { return mList.GetEnumerator(); }
  46. /// <summary>
  47. /// Clear the array by resetting its size to zero. Note that the memory is not actually released.
  48. /// </summary>
  49. public void Clear () { mList.Clear(); }
  50. /// <summary>
  51. /// Clear the array and release the used memory.
  52. /// </summary>
  53. public void Release () { mList.Clear(); }
  54. /// <summary>
  55. /// Add the specified item to the end of the list.
  56. /// </summary>
  57. public void Add (T item) { mList.Add(item); }
  58. /// <summary>
  59. /// Insert an item at the specified index, pushing the entries back.
  60. /// </summary>
  61. public void Insert (int index, T item)
  62. {
  63. if (index > -1 && index < mList.Count) mList.Insert(index, item);
  64. else mList.Add(item);
  65. }
  66. /// <summary>
  67. /// Returns 'true' if the specified item is within the list.
  68. /// </summary>
  69. public bool Contains (T item) { return mList.Contains(item); }
  70. /// <summary>
  71. /// Return the index of the specified item.
  72. /// </summary>
  73. public int IndexOf (T item) { return mList.IndexOf(item); }
  74. /// <summary>
  75. /// Remove the specified item from the list. Note that RemoveAt() is faster and is advisable if you already know the index.
  76. /// </summary>
  77. public bool Remove (T item) { return mList.Remove(item); }
  78. /// <summary>
  79. /// Remove an item at the specified index.
  80. /// </summary>
  81. public void RemoveAt (int index) { mList.RemoveAt(index); }
  82. /// <summary>
  83. /// Remove an item from the end.
  84. /// </summary>
  85. public T Pop ()
  86. {
  87. if (buffer != null && size != 0)
  88. {
  89. T val = buffer[mList.Count - 1];
  90. mList.RemoveAt(mList.Count - 1);
  91. return val;
  92. }
  93. return default(T);
  94. }
  95. /// <summary>
  96. /// Mimic List's ToArray() functionality, except that in this case the list is resized to match the current size.
  97. /// </summary>
  98. public T[] ToArray () { return mList.ToArray(); }
  99. /// <summary>
  100. /// List.Sort equivalent.
  101. /// </summary>
  102. public void Sort (System.Comparison<T> comparer) { mList.Sort(comparer); }
  103. #else
  104. /// <summary>
  105. /// Direct access to the buffer. Note that you should not use its 'Length' parameter, but instead use BetterList.size.
  106. /// </summary>
  107. public T[] buffer;
  108. private int buffSize = 8;
  109. public int Count
  110. {
  111. get { return size; }
  112. }
  113. public bool isNotPool = true;
  114. /// <summary>
  115. /// Direct access to the buffer's size. Note that it's only public for speed and efficiency. You shouldn't modify it.
  116. /// </summary>
  117. public int size = 0;
  118. // /// <summary>
  119. // /// For 'foreach' functionality.
  120. // /// </summary>
  121. // [DebuggerHidden]
  122. // [DebuggerStepThrough]
  123. // public IEnumerator<T> GetEnumerator()
  124. // {
  125. // if (buffer != null)
  126. // {
  127. // for (int i = 0; i < size; ++i)
  128. // {
  129. // yield return buffer[i];
  130. // }
  131. // }
  132. // }
  133. public BetterList()
  134. {
  135. isNotPool = true;
  136. }
  137. // ~BetterList()
  138. // {
  139. // CombatListPool<T>.Instance.Recycle(this);
  140. // }
  141. public BetterList(bool isNotPool)
  142. {
  143. this.isNotPool = isNotPool;
  144. }
  145. public BetterList(bool isNotPool, int size)
  146. {
  147. this.isNotPool = isNotPool;
  148. buffSize = size;
  149. }
  150. public BetterList(int size)
  151. {
  152. buffSize = size;
  153. buffer = new T[size];
  154. }
  155. public BetterList(List<T> allVe)
  156. {
  157. buffer = allVe.ToArray();
  158. size = buffer.Length;
  159. }
  160. /// <summary>
  161. /// Convenience function. I recommend using .buffer instead.
  162. /// </summary>
  163. [DebuggerHidden]
  164. public T this[int i]
  165. {
  166. get { return buffer[i]; }
  167. set { buffer[i] = value; }
  168. }
  169. /// <summary>
  170. /// Helper function that expands the size of the array, maintaining the content.
  171. /// </summary>
  172. void AllocateMore()
  173. {
  174. T[] newList = (buffer != null) ? new T[System.Math.Max(buffer.Length << 1, buffSize)] : new T[buffSize];
  175. if (buffer != null && size > 0) buffer.CopyTo(newList, 0);
  176. buffer = newList;
  177. }
  178. /// <summary>
  179. /// Trim the unnecessary memory, resizing the buffer to be of 'Length' size.
  180. /// Call this function only if you are sure that the buffer won't need to resize anytime soon.
  181. /// </summary>
  182. void Trim()
  183. {
  184. if (size > 0)
  185. {
  186. if (size < buffer.Length)
  187. {
  188. T[] newList = new T[size];
  189. for (int i = 0; i < size; ++i) newList[i] = buffer[i];
  190. buffer = newList;
  191. }
  192. }
  193. else buffer = null;
  194. }
  195. /// <summary>
  196. /// Clear the array by resetting its size to zero. Note that the memory is not actually released.
  197. /// </summary>
  198. public void Clear()
  199. {
  200. size = 0;
  201. }
  202. /// <summary>
  203. /// Clear the array and release the used memory.
  204. /// </summary>
  205. public void Release()
  206. {
  207. size = 0;
  208. buffer = null;
  209. }
  210. /// <summary>
  211. /// Add the specified item to the end of the list.
  212. /// </summary>
  213. public void Add(T item)
  214. {
  215. if (buffer == null || size == buffer.Length) AllocateMore();
  216. buffer[size++] = item;
  217. }
  218. /// <summary>
  219. /// Insert an item at the specified index, pushing the entries back.
  220. /// </summary>
  221. public void Insert(int index, T item)
  222. {
  223. if (buffer == null || size == buffer.Length) AllocateMore();
  224. if (index > -1 && index < size)
  225. {
  226. for (int i = size; i > index; --i) buffer[i] = buffer[i - 1];
  227. buffer[index] = item;
  228. ++size;
  229. }
  230. else Add(item);
  231. }
  232. /// <summary>
  233. /// Returns 'true' if the specified item is within the list.
  234. /// </summary>
  235. public bool Contains(T item)
  236. {
  237. if (buffer == null) return false;
  238. for (int i = 0; i < size; ++i)
  239. if (buffer[i].Equals(item))
  240. return true;
  241. return false;
  242. }
  243. /// <summary>
  244. /// Return the index of the specified item.
  245. /// </summary>
  246. public int IndexOf(T item)
  247. {
  248. if (buffer == null) return -1;
  249. for (int i = 0; i < size; ++i)
  250. if (buffer[i].Equals(item))
  251. return i;
  252. return -1;
  253. }
  254. /// <summary>
  255. /// Remove the specified item from the list. Note that RemoveAt() is faster and is advisable if you already know the index.
  256. /// </summary>
  257. public bool Remove(T item)
  258. {
  259. if (buffer != null)
  260. {
  261. EqualityComparer<T> comp = EqualityComparer<T>.Default;
  262. for (int i = 0; i < size; ++i)
  263. {
  264. if (comp.Equals(buffer[i], item))
  265. {
  266. --size;
  267. buffer[i] = default(T);
  268. for (int b = i; b < size; ++b) buffer[b] = buffer[b + 1];
  269. buffer[size] = default(T);
  270. return true;
  271. }
  272. }
  273. }
  274. return false;
  275. }
  276. /// <summary>
  277. /// Remove an item at the specified index.
  278. /// </summary>
  279. public void RemoveAt(int index)
  280. {
  281. if (buffer != null && index > -1 && index < size)
  282. {
  283. --size;
  284. buffer[index] = default(T);
  285. for (int b = index; b < size; ++b) buffer[b] = buffer[b + 1];
  286. buffer[size] = default(T);
  287. }
  288. }
  289. /// <summary>
  290. /// Remove an item from the end.
  291. /// </summary>
  292. public T Pop()
  293. {
  294. if (buffer != null && size != 0)
  295. {
  296. T val = buffer[--size];
  297. buffer[size] = default(T);
  298. return val;
  299. }
  300. return default(T);
  301. }
  302. public void AddRange(List<T> target)
  303. {
  304. for (int i = 0; i < target.Count; i++)
  305. {
  306. Add(target[i]);
  307. }
  308. }
  309. public void AddRange(T[] target)
  310. {
  311. if (target == null)
  312. {
  313. return;
  314. }
  315. for (int i = 0; i < target.Length; i++)
  316. {
  317. Add(target[i]);
  318. }
  319. }
  320. public void AddRange<K>(BetterList<K> target)
  321. {
  322. for (int i = 0; i < target.Count; i++)
  323. {
  324. Add(target[i]);
  325. }
  326. }
  327. private void Add(object item)
  328. {
  329. if (buffer == null || size == buffer.Length) AllocateMore();
  330. buffer[size++] = (T)item;
  331. }
  332. public void AddRange(BetterList<T> target)
  333. {
  334. // for (int i = 0; i < target.size; i++)
  335. // {
  336. // Add(target[i]);
  337. // }
  338. if (target == null || target.buffer == null)
  339. {
  340. return;
  341. }
  342. if (buffer == null)
  343. {
  344. buffer = new T[0];
  345. }
  346. if (size + target.size > buffer.Length)
  347. {
  348. System.Array.Resize(ref buffer, size + target.size);
  349. }
  350. System.Array.Copy(target.buffer, 0, buffer, size, target.size);
  351. size += target.size;
  352. }
  353. /// <summary>
  354. /// Mimic List's ToArray() functionality, except that in this case the list is resized to match the current size.
  355. /// </summary>
  356. public T[] ToArray(bool isNoTrim=false)
  357. {
  358. if (!isNoTrim)
  359. {
  360. Trim();
  361. }
  362. return buffer;
  363. }
  364. //class Comparer : System.Collections.IComparer
  365. //{
  366. // public System.Comparison<T> func;
  367. // public int Compare (object x, object y) { return func((T)x, (T)y); }
  368. //}
  369. //Comparer mComp = new Comparer();
  370. /// <summary>
  371. /// List.Sort equivalent. Doing Array.Sort causes GC allocations.
  372. /// </summary>
  373. //public void Sort (System.Comparison<T> comparer)
  374. //{
  375. // if (size > 0)
  376. // {
  377. // mComp.func = comparer;
  378. // System.Array.Sort(buffer, 0, size, mComp);
  379. // }
  380. //}
  381. /// <summary>
  382. /// List.Sort equivalent. Manual sorting causes no GC allocations.
  383. /// </summary>
  384. [DebuggerHidden]
  385. [DebuggerStepThrough]
  386. public void Sort(CompareFunc comparer)
  387. {
  388. int start = 0;
  389. int max = size - 1;
  390. bool changed = true;
  391. while (changed)
  392. {
  393. changed = false;
  394. for (int i = start; i < max; ++i)
  395. {
  396. // Compare the two values
  397. if (comparer(buffer[i], buffer[i + 1]) > 0)
  398. {
  399. // Swap the values
  400. T temp = buffer[i];
  401. buffer[i] = buffer[i + 1];
  402. buffer[i + 1] = temp;
  403. changed = true;
  404. }
  405. else if (!changed)
  406. {
  407. // Nothing has changed -- we can start here next time
  408. start = (i == 0) ? 0 : i - 1;
  409. }
  410. }
  411. }
  412. }
  413. /// <summary>
  414. /// Comparison function should return -1 if left is less than right, 1 if left is greater than right, and 0 if they match.
  415. /// </summary>
  416. public delegate int CompareFunc(T left, T right);
  417. #endif
  418. public void Dispose()
  419. {
  420. if (isNotPool)
  421. {
  422. return;
  423. }
  424. CombatListPool<T>.Instance.Recycle(this);
  425. }
  426. }