BetterList.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  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. }
  154. public BetterList(List<T> allVe)
  155. {
  156. buffer = allVe.ToArray();
  157. size = buffer.Length;
  158. }
  159. /// <summary>
  160. /// Convenience function. I recommend using .buffer instead.
  161. /// </summary>
  162. [DebuggerHidden]
  163. public T this[int i]
  164. {
  165. get { return buffer[i]; }
  166. set { buffer[i] = value; }
  167. }
  168. /// <summary>
  169. /// Helper function that expands the size of the array, maintaining the content.
  170. /// </summary>
  171. void AllocateMore()
  172. {
  173. T[] newList = (buffer != null) ? new T[System.Math.Max(buffer.Length << 1, buffSize)] : new T[buffSize];
  174. if (buffer != null && size > 0) buffer.CopyTo(newList, 0);
  175. buffer = newList;
  176. }
  177. /// <summary>
  178. /// Trim the unnecessary memory, resizing the buffer to be of 'Length' size.
  179. /// Call this function only if you are sure that the buffer won't need to resize anytime soon.
  180. /// </summary>
  181. void Trim()
  182. {
  183. if (size > 0)
  184. {
  185. if (size < buffer.Length)
  186. {
  187. T[] newList = new T[size];
  188. for (int i = 0; i < size; ++i) newList[i] = buffer[i];
  189. buffer = newList;
  190. }
  191. }
  192. else buffer = null;
  193. }
  194. /// <summary>
  195. /// Clear the array by resetting its size to zero. Note that the memory is not actually released.
  196. /// </summary>
  197. public void Clear()
  198. {
  199. size = 0;
  200. }
  201. /// <summary>
  202. /// Clear the array and release the used memory.
  203. /// </summary>
  204. public void Release()
  205. {
  206. size = 0;
  207. buffer = null;
  208. }
  209. /// <summary>
  210. /// Add the specified item to the end of the list.
  211. /// </summary>
  212. public void Add(T item)
  213. {
  214. if (buffer == null || size == buffer.Length) AllocateMore();
  215. buffer[size++] = item;
  216. }
  217. /// <summary>
  218. /// Insert an item at the specified index, pushing the entries back.
  219. /// </summary>
  220. public void Insert(int index, T item)
  221. {
  222. if (buffer == null || size == buffer.Length) AllocateMore();
  223. if (index > -1 && index < size)
  224. {
  225. for (int i = size; i > index; --i) buffer[i] = buffer[i - 1];
  226. buffer[index] = item;
  227. ++size;
  228. }
  229. else Add(item);
  230. }
  231. /// <summary>
  232. /// Returns 'true' if the specified item is within the list.
  233. /// </summary>
  234. public bool Contains(T item)
  235. {
  236. if (buffer == null) return false;
  237. for (int i = 0; i < size; ++i)
  238. if (buffer[i].Equals(item))
  239. return true;
  240. return false;
  241. }
  242. /// <summary>
  243. /// Return the index of the specified item.
  244. /// </summary>
  245. public int IndexOf(T item)
  246. {
  247. if (buffer == null) return -1;
  248. for (int i = 0; i < size; ++i)
  249. if (buffer[i].Equals(item))
  250. return i;
  251. return -1;
  252. }
  253. /// <summary>
  254. /// Remove the specified item from the list. Note that RemoveAt() is faster and is advisable if you already know the index.
  255. /// </summary>
  256. public bool Remove(T item)
  257. {
  258. if (buffer != null)
  259. {
  260. EqualityComparer<T> comp = EqualityComparer<T>.Default;
  261. for (int i = 0; i < size; ++i)
  262. {
  263. if (comp.Equals(buffer[i], item))
  264. {
  265. --size;
  266. buffer[i] = default(T);
  267. for (int b = i; b < size; ++b) buffer[b] = buffer[b + 1];
  268. buffer[size] = default(T);
  269. return true;
  270. }
  271. }
  272. }
  273. return false;
  274. }
  275. /// <summary>
  276. /// Remove an item at the specified index.
  277. /// </summary>
  278. public void RemoveAt(int index)
  279. {
  280. if (buffer != null && index > -1 && index < size)
  281. {
  282. --size;
  283. buffer[index] = default(T);
  284. for (int b = index; b < size; ++b) buffer[b] = buffer[b + 1];
  285. buffer[size] = default(T);
  286. }
  287. }
  288. /// <summary>
  289. /// Remove an item from the end.
  290. /// </summary>
  291. public T Pop()
  292. {
  293. if (buffer != null && size != 0)
  294. {
  295. T val = buffer[--size];
  296. buffer[size] = default(T);
  297. return val;
  298. }
  299. return default(T);
  300. }
  301. public void AddRange(List<T> target)
  302. {
  303. for (int i = 0; i < target.Count; i++)
  304. {
  305. Add(target[i]);
  306. }
  307. }
  308. public void AddRange(T[] target)
  309. {
  310. if (target == null)
  311. {
  312. return;
  313. }
  314. for (int i = 0; i < target.Length; i++)
  315. {
  316. Add(target[i]);
  317. }
  318. }
  319. public void AddRange<K>(BetterList<K> target)
  320. {
  321. for (int i = 0; i < target.Count; i++)
  322. {
  323. Add(target[i]);
  324. }
  325. }
  326. private void Add(object item)
  327. {
  328. if (buffer == null || size == buffer.Length) AllocateMore();
  329. buffer[size++] = (T)item;
  330. }
  331. public void AddRange(BetterList<T> target)
  332. {
  333. // for (int i = 0; i < target.size; i++)
  334. // {
  335. // Add(target[i]);
  336. // }
  337. if (target == null || target.buffer == null)
  338. {
  339. return;
  340. }
  341. if (buffer == null)
  342. {
  343. buffer = new T[0];
  344. }
  345. if (size + target.size > buffer.Length)
  346. {
  347. System.Array.Resize(ref buffer, size + target.size);
  348. }
  349. System.Array.Copy(target.buffer, 0, buffer, size, target.size);
  350. size += target.size;
  351. }
  352. /// <summary>
  353. /// Mimic List's ToArray() functionality, except that in this case the list is resized to match the current size.
  354. /// </summary>
  355. public T[] ToArray()
  356. {
  357. Trim();
  358. return buffer;
  359. }
  360. //class Comparer : System.Collections.IComparer
  361. //{
  362. // public System.Comparison<T> func;
  363. // public int Compare (object x, object y) { return func((T)x, (T)y); }
  364. //}
  365. //Comparer mComp = new Comparer();
  366. /// <summary>
  367. /// List.Sort equivalent. Doing Array.Sort causes GC allocations.
  368. /// </summary>
  369. //public void Sort (System.Comparison<T> comparer)
  370. //{
  371. // if (size > 0)
  372. // {
  373. // mComp.func = comparer;
  374. // System.Array.Sort(buffer, 0, size, mComp);
  375. // }
  376. //}
  377. /// <summary>
  378. /// List.Sort equivalent. Manual sorting causes no GC allocations.
  379. /// </summary>
  380. [DebuggerHidden]
  381. [DebuggerStepThrough]
  382. public void Sort(CompareFunc comparer)
  383. {
  384. int start = 0;
  385. int max = size - 1;
  386. bool changed = true;
  387. while (changed)
  388. {
  389. changed = false;
  390. for (int i = start; i < max; ++i)
  391. {
  392. // Compare the two values
  393. if (comparer(buffer[i], buffer[i + 1]) > 0)
  394. {
  395. // Swap the values
  396. T temp = buffer[i];
  397. buffer[i] = buffer[i + 1];
  398. buffer[i + 1] = temp;
  399. changed = true;
  400. }
  401. else if (!changed)
  402. {
  403. // Nothing has changed -- we can start here next time
  404. start = (i == 0) ? 0 : i - 1;
  405. }
  406. }
  407. }
  408. }
  409. /// <summary>
  410. /// Comparison function should return -1 if left is less than right, 1 if left is greater than right, and 0 if they match.
  411. /// </summary>
  412. public delegate int CompareFunc(T left, T right);
  413. #endif
  414. public void Dispose()
  415. {
  416. if (isNotPool)
  417. {
  418. return;
  419. }
  420. CombatListPool<T>.Instance.Recycle(this);
  421. }
  422. }