GameFrameworkMultiDictionary.cs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. //------------------------------------------------------------
  2. // Game Framework
  3. // Copyright © 2013-2021 loyalsoft. All rights reserved.
  4. // Homepage: http://www.game7000.com/
  5. // Feedback: http://www.game7000.com/
  6. //------------------------------------------------------------
  7. using System.Collections;
  8. using System.Collections.Generic;
  9. using System.Runtime.InteropServices;
  10. namespace GameFramework
  11. {
  12. /// <summary>
  13. /// 游戏框架多值字典类。
  14. /// </summary>
  15. /// <typeparam name="TKey">指定多值字典的主键类型。</typeparam>
  16. /// <typeparam name="TValue">指定多值字典的值类型。</typeparam>
  17. public sealed class GameFrameworkMultiDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, GameFrameworkLinkedListRange<TValue>>>, IEnumerable
  18. {
  19. private readonly GameFrameworkLinkedList<TValue> m_LinkedList;
  20. private readonly Dictionary<TKey, GameFrameworkLinkedListRange<TValue>> m_Dictionary;
  21. /// <summary>
  22. /// 初始化游戏框架多值字典类的新实例。
  23. /// </summary>
  24. public GameFrameworkMultiDictionary()
  25. {
  26. m_LinkedList = new GameFrameworkLinkedList<TValue>();
  27. m_Dictionary = new Dictionary<TKey, GameFrameworkLinkedListRange<TValue>>();
  28. }
  29. /// <summary>
  30. /// 获取多值字典中实际包含的主键数量。
  31. /// </summary>
  32. public int Count
  33. {
  34. get
  35. {
  36. return m_Dictionary.Count;
  37. }
  38. }
  39. /// <summary>
  40. /// 获取多值字典中指定主键的范围。
  41. /// </summary>
  42. /// <param name="key">指定的主键。</param>
  43. /// <returns>指定主键的范围。</returns>
  44. public GameFrameworkLinkedListRange<TValue> this[TKey key]
  45. {
  46. get
  47. {
  48. GameFrameworkLinkedListRange<TValue> range = default(GameFrameworkLinkedListRange<TValue>);
  49. m_Dictionary.TryGetValue(key, out range);
  50. return range;
  51. }
  52. }
  53. /// <summary>
  54. /// 清理多值字典。
  55. /// </summary>
  56. public void Clear()
  57. {
  58. m_Dictionary.Clear();
  59. m_LinkedList.Clear();
  60. }
  61. /// <summary>
  62. /// 检查多值字典中是否包含指定主键。
  63. /// </summary>
  64. /// <param name="key">要检查的主键。</param>
  65. /// <returns>多值字典中是否包含指定主键。</returns>
  66. public bool Contains(TKey key)
  67. {
  68. return m_Dictionary.ContainsKey(key);
  69. }
  70. /// <summary>
  71. /// 检查多值字典中是否包含指定值。
  72. /// </summary>
  73. /// <param name="key">要检查的主键。</param>
  74. /// <param name="value">要检查的值。</param>
  75. /// <returns>多值字典中是否包含指定值。</returns>
  76. public bool Contains(TKey key, TValue value)
  77. {
  78. GameFrameworkLinkedListRange<TValue> range = default(GameFrameworkLinkedListRange<TValue>);
  79. if (m_Dictionary.TryGetValue(key, out range))
  80. {
  81. return range.Contains(value);
  82. }
  83. return false;
  84. }
  85. /// <summary>
  86. /// 尝试获取多值字典中指定主键的范围。
  87. /// </summary>
  88. /// <param name="key">指定的主键。</param>
  89. /// <param name="range">指定主键的范围。</param>
  90. /// <returns>是否获取成功。</returns>
  91. public bool TryGetValue(TKey key, out GameFrameworkLinkedListRange<TValue> range)
  92. {
  93. return m_Dictionary.TryGetValue(key, out range);
  94. }
  95. /// <summary>
  96. /// 向指定的主键增加指定的值。
  97. /// </summary>
  98. /// <param name="key">指定的主键。</param>
  99. /// <param name="value">指定的值。</param>
  100. public void Add(TKey key, TValue value)
  101. {
  102. GameFrameworkLinkedListRange<TValue> range = default(GameFrameworkLinkedListRange<TValue>);
  103. if (m_Dictionary.TryGetValue(key, out range))
  104. {
  105. m_LinkedList.AddBefore(range.Terminal, value);
  106. }
  107. else
  108. {
  109. LinkedListNode<TValue> first = m_LinkedList.AddLast(value);
  110. LinkedListNode<TValue> terminal = m_LinkedList.AddLast(default(TValue));
  111. m_Dictionary.Add(key, new GameFrameworkLinkedListRange<TValue>(first, terminal));
  112. }
  113. }
  114. /// <summary>
  115. /// 从指定的主键中移除指定的值。
  116. /// </summary>
  117. /// <param name="key">指定的主键。</param>
  118. /// <param name="value">指定的值。</param>
  119. /// <returns>是否移除成功。</returns>
  120. public bool Remove(TKey key, TValue value)
  121. {
  122. GameFrameworkLinkedListRange<TValue> range = default(GameFrameworkLinkedListRange<TValue>);
  123. if (m_Dictionary.TryGetValue(key, out range))
  124. {
  125. for (LinkedListNode<TValue> current = range.First; current != null && current != range.Terminal; current = current.Next)
  126. {
  127. if (current.Value.Equals(value))
  128. {
  129. if (current == range.First)
  130. {
  131. LinkedListNode<TValue> next = current.Next;
  132. if (next == range.Terminal)
  133. {
  134. m_LinkedList.Remove(next);
  135. m_Dictionary.Remove(key);
  136. }
  137. else
  138. {
  139. m_Dictionary[key] = new GameFrameworkLinkedListRange<TValue>(next, range.Terminal);
  140. }
  141. }
  142. m_LinkedList.Remove(current);
  143. return true;
  144. }
  145. }
  146. }
  147. return false;
  148. }
  149. /// <summary>
  150. /// 从指定的主键中移除所有的值。
  151. /// </summary>
  152. /// <param name="key">指定的主键。</param>
  153. /// <returns>是否移除成功。</returns>
  154. public bool RemoveAll(TKey key)
  155. {
  156. GameFrameworkLinkedListRange<TValue> range = default(GameFrameworkLinkedListRange<TValue>);
  157. if (m_Dictionary.TryGetValue(key, out range))
  158. {
  159. m_Dictionary.Remove(key);
  160. LinkedListNode<TValue> current = range.First;
  161. while (current != null)
  162. {
  163. LinkedListNode<TValue> next = current != range.Terminal ? current.Next : null;
  164. m_LinkedList.Remove(current);
  165. current = next;
  166. }
  167. return true;
  168. }
  169. return false;
  170. }
  171. /// <summary>
  172. /// 返回循环访问集合的枚举数。
  173. /// </summary>
  174. /// <returns>循环访问集合的枚举数。</returns>
  175. public Enumerator GetEnumerator()
  176. {
  177. return new Enumerator(m_Dictionary);
  178. }
  179. /// <summary>
  180. /// 返回循环访问集合的枚举数。
  181. /// </summary>
  182. /// <returns>循环访问集合的枚举数。</returns>
  183. IEnumerator<KeyValuePair<TKey, GameFrameworkLinkedListRange<TValue>>> IEnumerable<KeyValuePair<TKey, GameFrameworkLinkedListRange<TValue>>>.GetEnumerator()
  184. {
  185. return GetEnumerator();
  186. }
  187. /// <summary>
  188. /// 返回循环访问集合的枚举数。
  189. /// </summary>
  190. /// <returns>循环访问集合的枚举数。</returns>
  191. IEnumerator IEnumerable.GetEnumerator()
  192. {
  193. return GetEnumerator();
  194. }
  195. /// <summary>
  196. /// 循环访问集合的枚举数。
  197. /// </summary>
  198. [StructLayout(LayoutKind.Auto)]
  199. public struct Enumerator : IEnumerator<KeyValuePair<TKey, GameFrameworkLinkedListRange<TValue>>>, IEnumerator
  200. {
  201. private Dictionary<TKey, GameFrameworkLinkedListRange<TValue>>.Enumerator m_Enumerator;
  202. internal Enumerator(Dictionary<TKey, GameFrameworkLinkedListRange<TValue>> dictionary)
  203. {
  204. if (dictionary == null)
  205. {
  206. throw new GameFrameworkException("Dictionary is invalid.");
  207. }
  208. m_Enumerator = dictionary.GetEnumerator();
  209. }
  210. /// <summary>
  211. /// 获取当前结点。
  212. /// </summary>
  213. public KeyValuePair<TKey, GameFrameworkLinkedListRange<TValue>> Current
  214. {
  215. get
  216. {
  217. return m_Enumerator.Current;
  218. }
  219. }
  220. /// <summary>
  221. /// 获取当前的枚举数。
  222. /// </summary>
  223. object IEnumerator.Current
  224. {
  225. get
  226. {
  227. return m_Enumerator.Current;
  228. }
  229. }
  230. /// <summary>
  231. /// 清理枚举数。
  232. /// </summary>
  233. public void Dispose()
  234. {
  235. m_Enumerator.Dispose();
  236. }
  237. /// <summary>
  238. /// 获取下一个结点。
  239. /// </summary>
  240. /// <returns>返回下一个结点。</returns>
  241. public bool MoveNext()
  242. {
  243. return m_Enumerator.MoveNext();
  244. }
  245. /// <summary>
  246. /// 重置枚举数。
  247. /// </summary>
  248. void IEnumerator.Reset()
  249. {
  250. ((IEnumerator<KeyValuePair<TKey, GameFrameworkLinkedListRange<TValue>>>)m_Enumerator).Reset();
  251. }
  252. }
  253. }
  254. }