UnityEqualityComparer.cs 11 KB

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