UnityEqualityComparer.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace Cysharp.Threading.Tasks.Internal
  5. {
  6. internal static class UnityEqualityComparer
  7. {
  8. public static readonly IEqualityComparer<Vector2> Vector2 = new Vector2EqualityComparer();
  9. public static readonly IEqualityComparer<Vector3> Vector3 = new Vector3EqualityComparer();
  10. public static readonly IEqualityComparer<Vector4> Vector4 = new Vector4EqualityComparer();
  11. public static readonly IEqualityComparer<Color> Color = new ColorEqualityComparer();
  12. public static readonly IEqualityComparer<Color32> Color32 = new Color32EqualityComparer();
  13. public static readonly IEqualityComparer<Rect> Rect = new RectEqualityComparer();
  14. public static readonly IEqualityComparer<Bounds> Bounds = new BoundsEqualityComparer();
  15. public static readonly IEqualityComparer<Quaternion> Quaternion = new QuaternionEqualityComparer();
  16. static readonly RuntimeTypeHandle vector2Type = typeof(Vector2).TypeHandle;
  17. static readonly RuntimeTypeHandle vector3Type = typeof(Vector3).TypeHandle;
  18. static readonly RuntimeTypeHandle vector4Type = typeof(Vector4).TypeHandle;
  19. static readonly RuntimeTypeHandle colorType = typeof(Color).TypeHandle;
  20. static readonly RuntimeTypeHandle color32Type = typeof(Color32).TypeHandle;
  21. static readonly RuntimeTypeHandle rectType = typeof(Rect).TypeHandle;
  22. static readonly RuntimeTypeHandle boundsType = typeof(Bounds).TypeHandle;
  23. static readonly RuntimeTypeHandle quaternionType = typeof(Quaternion).TypeHandle;
  24. #if UNITY_2017_2_OR_NEWER
  25. public static readonly IEqualityComparer<Vector2Int> Vector2Int = new Vector2IntEqualityComparer();
  26. public static readonly IEqualityComparer<Vector3Int> Vector3Int = new Vector3IntEqualityComparer();
  27. public static readonly IEqualityComparer<RangeInt> RangeInt = new RangeIntEqualityComparer();
  28. public static readonly IEqualityComparer<RectInt> RectInt = new RectIntEqualityComparer();
  29. public static readonly IEqualityComparer<BoundsInt> BoundsInt = new BoundsIntEqualityComparer();
  30. static readonly RuntimeTypeHandle vector2IntType = typeof(Vector2Int).TypeHandle;
  31. static readonly RuntimeTypeHandle vector3IntType = typeof(Vector3Int).TypeHandle;
  32. static readonly RuntimeTypeHandle rangeIntType = typeof(RangeInt).TypeHandle;
  33. static readonly RuntimeTypeHandle rectIntType = typeof(RectInt).TypeHandle;
  34. static readonly RuntimeTypeHandle boundsIntType = typeof(BoundsInt).TypeHandle;
  35. #endif
  36. static class Cache<T>
  37. {
  38. public static readonly IEqualityComparer<T> Comparer;
  39. static Cache()
  40. {
  41. var comparer = GetDefaultHelper(typeof(T));
  42. if (comparer == null)
  43. {
  44. Comparer = EqualityComparer<T>.Default;
  45. }
  46. else
  47. {
  48. Comparer = (IEqualityComparer<T>)comparer;
  49. }
  50. }
  51. }
  52. public static IEqualityComparer<T> GetDefault<T>()
  53. {
  54. return Cache<T>.Comparer;
  55. }
  56. static object GetDefaultHelper(Type type)
  57. {
  58. var t = type.TypeHandle;
  59. if (t.Equals(vector2Type)) return (object)UnityEqualityComparer.Vector2;
  60. if (t.Equals(vector3Type)) return (object)UnityEqualityComparer.Vector3;
  61. if (t.Equals(vector4Type)) return (object)UnityEqualityComparer.Vector4;
  62. if (t.Equals(colorType)) return (object)UnityEqualityComparer.Color;
  63. if (t.Equals(color32Type)) return (object)UnityEqualityComparer.Color32;
  64. if (t.Equals(rectType)) return (object)UnityEqualityComparer.Rect;
  65. if (t.Equals(boundsType)) return (object)UnityEqualityComparer.Bounds;
  66. if (t.Equals(quaternionType)) return (object)UnityEqualityComparer.Quaternion;
  67. #if UNITY_2017_2_OR_NEWER
  68. if (t.Equals(vector2IntType)) return (object)UnityEqualityComparer.Vector2Int;
  69. if (t.Equals(vector3IntType)) return (object)UnityEqualityComparer.Vector3Int;
  70. if (t.Equals(rangeIntType)) return (object)UnityEqualityComparer.RangeInt;
  71. if (t.Equals(rectIntType)) return (object)UnityEqualityComparer.RectInt;
  72. if (t.Equals(boundsIntType)) return (object)UnityEqualityComparer.BoundsInt;
  73. #endif
  74. return null;
  75. }
  76. sealed class Vector2EqualityComparer : IEqualityComparer<Vector2>
  77. {
  78. public bool Equals(Vector2 self, Vector2 vector)
  79. {
  80. return self.x.Equals(vector.x) && self.y.Equals(vector.y);
  81. }
  82. public int GetHashCode(Vector2 obj)
  83. {
  84. return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2;
  85. }
  86. }
  87. sealed class Vector3EqualityComparer : IEqualityComparer<Vector3>
  88. {
  89. public bool Equals(Vector3 self, Vector3 vector)
  90. {
  91. return self.x.Equals(vector.x) && self.y.Equals(vector.y) && self.z.Equals(vector.z);
  92. }
  93. public int GetHashCode(Vector3 obj)
  94. {
  95. return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2 ^ obj.z.GetHashCode() >> 2;
  96. }
  97. }
  98. sealed class Vector4EqualityComparer : IEqualityComparer<Vector4>
  99. {
  100. public bool Equals(Vector4 self, Vector4 vector)
  101. {
  102. return self.x.Equals(vector.x) && self.y.Equals(vector.y) && self.z.Equals(vector.z) && self.w.Equals(vector.w);
  103. }
  104. public int GetHashCode(Vector4 obj)
  105. {
  106. return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2 ^ obj.z.GetHashCode() >> 2 ^ obj.w.GetHashCode() >> 1;
  107. }
  108. }
  109. sealed class ColorEqualityComparer : IEqualityComparer<Color>
  110. {
  111. public bool Equals(Color self, Color other)
  112. {
  113. return self.r.Equals(other.r) && self.g.Equals(other.g) && self.b.Equals(other.b) && self.a.Equals(other.a);
  114. }
  115. public int GetHashCode(Color obj)
  116. {
  117. return obj.r.GetHashCode() ^ obj.g.GetHashCode() << 2 ^ obj.b.GetHashCode() >> 2 ^ obj.a.GetHashCode() >> 1;
  118. }
  119. }
  120. sealed class RectEqualityComparer : IEqualityComparer<Rect>
  121. {
  122. public bool Equals(Rect self, Rect other)
  123. {
  124. return self.x.Equals(other.x) && self.width.Equals(other.width) && self.y.Equals(other.y) && self.height.Equals(other.height);
  125. }
  126. public int GetHashCode(Rect obj)
  127. {
  128. return obj.x.GetHashCode() ^ obj.width.GetHashCode() << 2 ^ obj.y.GetHashCode() >> 2 ^ obj.height.GetHashCode() >> 1;
  129. }
  130. }
  131. sealed class BoundsEqualityComparer : IEqualityComparer<Bounds>
  132. {
  133. public bool Equals(Bounds self, Bounds vector)
  134. {
  135. return self.center.Equals(vector.center) && self.extents.Equals(vector.extents);
  136. }
  137. public int GetHashCode(Bounds obj)
  138. {
  139. return obj.center.GetHashCode() ^ obj.extents.GetHashCode() << 2;
  140. }
  141. }
  142. sealed class QuaternionEqualityComparer : IEqualityComparer<Quaternion>
  143. {
  144. public bool Equals(Quaternion self, Quaternion vector)
  145. {
  146. return self.x.Equals(vector.x) && self.y.Equals(vector.y) && self.z.Equals(vector.z) && self.w.Equals(vector.w);
  147. }
  148. public int GetHashCode(Quaternion obj)
  149. {
  150. return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2 ^ obj.z.GetHashCode() >> 2 ^ obj.w.GetHashCode() >> 1;
  151. }
  152. }
  153. sealed class Color32EqualityComparer : IEqualityComparer<Color32>
  154. {
  155. public bool Equals(Color32 self, Color32 vector)
  156. {
  157. return self.a.Equals(vector.a) && self.r.Equals(vector.r) && self.g.Equals(vector.g) && self.b.Equals(vector.b);
  158. }
  159. public int GetHashCode(Color32 obj)
  160. {
  161. return obj.a.GetHashCode() ^ obj.r.GetHashCode() << 2 ^ obj.g.GetHashCode() >> 2 ^ obj.b.GetHashCode() >> 1;
  162. }
  163. }
  164. #if UNITY_2017_2_OR_NEWER
  165. sealed class Vector2IntEqualityComparer : IEqualityComparer<Vector2Int>
  166. {
  167. public bool Equals(Vector2Int self, Vector2Int vector)
  168. {
  169. return self.x.Equals(vector.x) && self.y.Equals(vector.y);
  170. }
  171. public int GetHashCode(Vector2Int obj)
  172. {
  173. return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2;
  174. }
  175. }
  176. sealed class Vector3IntEqualityComparer : IEqualityComparer<Vector3Int>
  177. {
  178. public static readonly Vector3IntEqualityComparer Default = new Vector3IntEqualityComparer();
  179. public bool Equals(Vector3Int self, Vector3Int vector)
  180. {
  181. return self.x.Equals(vector.x) && self.y.Equals(vector.y) && self.z.Equals(vector.z);
  182. }
  183. public int GetHashCode(Vector3Int obj)
  184. {
  185. return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2 ^ obj.z.GetHashCode() >> 2;
  186. }
  187. }
  188. sealed class RangeIntEqualityComparer : IEqualityComparer<RangeInt>
  189. {
  190. public bool Equals(RangeInt self, RangeInt vector)
  191. {
  192. return self.start.Equals(vector.start) && self.length.Equals(vector.length);
  193. }
  194. public int GetHashCode(RangeInt obj)
  195. {
  196. return obj.start.GetHashCode() ^ obj.length.GetHashCode() << 2;
  197. }
  198. }
  199. sealed class RectIntEqualityComparer : IEqualityComparer<RectInt>
  200. {
  201. public bool Equals(RectInt self, RectInt other)
  202. {
  203. return self.x.Equals(other.x) && self.width.Equals(other.width) && self.y.Equals(other.y) && self.height.Equals(other.height);
  204. }
  205. public int GetHashCode(RectInt obj)
  206. {
  207. return obj.x.GetHashCode() ^ obj.width.GetHashCode() << 2 ^ obj.y.GetHashCode() >> 2 ^ obj.height.GetHashCode() >> 1;
  208. }
  209. }
  210. sealed class BoundsIntEqualityComparer : IEqualityComparer<BoundsInt>
  211. {
  212. public bool Equals(BoundsInt self, BoundsInt vector)
  213. {
  214. return Vector3IntEqualityComparer.Default.Equals(self.position, vector.position)
  215. && Vector3IntEqualityComparer.Default.Equals(self.size, vector.size);
  216. }
  217. public int GetHashCode(BoundsInt obj)
  218. {
  219. return Vector3IntEqualityComparer.Default.GetHashCode(obj.position) ^ Vector3IntEqualityComparer.Default.GetHashCode(obj.size) << 2;
  220. }
  221. }
  222. #endif
  223. }
  224. }