Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
6.0KB

  1. #if !REAL_ID
  2. using System;
  3. using System.Collections.Generic;
  4. #pragma warning disable 660,661
  5. namespace Svelto.ECS
  6. {
  7. public struct EGID:IEquatable<EGID>,IEqualityComparer<EGID>,IComparable<EGID>
  8. {
  9. readonly ulong _GID;
  10. public uint entityID => (uint) (_GID & 0xFFFFFFFF);
  11. public ExclusiveGroup.ExclusiveGroupStruct groupID => new ExclusiveGroup.ExclusiveGroupStruct((uint) (_GID >> 32));
  12. public static bool operator ==(EGID obj1, EGID obj2)
  13. {
  14. return obj1._GID == obj2._GID;
  15. }
  16. public static bool operator !=(EGID obj1, EGID obj2)
  17. {
  18. return obj1._GID != obj2._GID;
  19. }
  20. public EGID(uint entityID, ExclusiveGroup.ExclusiveGroupStruct groupID) : this()
  21. {
  22. _GID = MAKE_GLOBAL_ID(entityID, groupID);
  23. }
  24. static ulong MAKE_GLOBAL_ID(uint entityId, uint groupId)
  25. {
  26. return (ulong)groupId << 32 | ((ulong)entityId & 0xFFFFFFFF);
  27. }
  28. public static explicit operator uint(EGID id)
  29. {
  30. return id.entityID;
  31. }
  32. //in the way it's used, ulong must be always the same for each id/group
  33. public static explicit operator ulong(EGID id) { return id._GID; }
  34. public bool Equals(EGID other)
  35. {
  36. return _GID == other._GID;
  37. }
  38. public bool Equals(EGID x, EGID y)
  39. {
  40. return x == y;
  41. }
  42. public int GetHashCode(EGID obj)
  43. {
  44. return _GID.GetHashCode();
  45. }
  46. public int CompareTo(EGID other)
  47. {
  48. return _GID.CompareTo(other._GID);
  49. }
  50. internal EGID(uint entityID, uint groupID) : this()
  51. {
  52. _GID = MAKE_GLOBAL_ID(entityID, groupID);
  53. }
  54. }
  55. }
  56. #else
  57. using System;
  58. using System.Collections.Generic;
  59. using System.Runtime.CompilerServices;
  60. #pragma warning disable 660,661
  61. namespace Svelto.ECS
  62. {
  63. public struct EGID:IEquatable<EGID>,IEqualityComparer<EGID>,IComparable<EGID>
  64. {
  65. readonly ulong _GID;
  66. const int idbits = 22; //one bit is reserved
  67. const int groupbits = 20;
  68. const int realidbits = 21;
  69. public EGID(uint entityID, ExclusiveGroup.ExclusiveGroupStruct groupID) : this()
  70. {
  71. DBC.ECS.Check.Require(entityID < bit21, "the entityID value is outside the range, max value: (2^22)-1");
  72. DBC.ECS.Check.Require(groupID < bit20, "the groupID value is outside the range");
  73. _GID = MAKE_GLOBAL_ID(entityID, groupID, 0, 1);
  74. }
  75. const uint bit21 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001_1111_1111_1111_1111_1111;
  76. const uint bit22 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0011_1111_1111_1111_1111_1111;
  77. const uint bit20 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1111_1111_1111_1111_1111;
  78. public uint entityID
  79. {
  80. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  81. get { return (uint) (_GID & bit22); }
  82. }
  83. public ExclusiveGroup.ExclusiveGroupStruct groupID =>
  84. new ExclusiveGroup.ExclusiveGroupStruct((uint) ((_GID >> idbits) & bit20));
  85. // 1 21 20 1 21
  86. // | | realid | groupid |R| entityID |
  87. static ulong MAKE_GLOBAL_ID(uint entityId, uint groupId, uint realId, byte hasID)
  88. {
  89. var makeGlobalId = (((ulong)realId & bit21) << (idbits+groupbits)) | (((ulong)groupId & bit20) << idbits) | ((ulong)entityId & bit22);
  90. return makeGlobalId | (ulong) (hasID << idbits + groupbits + realidbits);
  91. }
  92. public static explicit operator uint(EGID id)
  93. {
  94. return id.entityID;
  95. }
  96. public static bool operator ==(EGID obj1, EGID obj2)
  97. {
  98. throw new NotSupportedException();
  99. }
  100. public static bool operator !=(EGID obj1, EGID obj2)
  101. {
  102. throw new NotSupportedException();
  103. }
  104. public bool Equals(EGID other)
  105. {
  106. throw new NotSupportedException();
  107. }
  108. public bool Equals(EGID x, EGID y)
  109. {
  110. throw new NotSupportedException();
  111. }
  112. public int CompareTo(EGID other)
  113. {
  114. throw new NotSupportedException();
  115. }
  116. //in the way it's used, ulong must be always the same for each id/group
  117. public static explicit operator ulong(EGID id)
  118. {
  119. throw new NotSupportedException();
  120. }
  121. public int GetHashCode(EGID egid)
  122. {
  123. throw new NotSupportedException();
  124. }
  125. internal EGID(ulong GID) : this()
  126. {
  127. _GID = GID;
  128. }
  129. internal EGID(uint entityID, uint groupID) : this()
  130. {
  131. _GID = MAKE_GLOBAL_ID(entityID, groupID, 0, 1);
  132. }
  133. internal static EGID UPDATE_REAL_ID_AND_GROUP(EGID egid, uint toGroupID, uint realID)
  134. {
  135. if (egid.hasID == 0)
  136. return new EGID(MAKE_GLOBAL_ID(SAFE_ID(realID), toGroupID, realID, 0));
  137. return new EGID(MAKE_GLOBAL_ID(egid.entityID, toGroupID, realID, 1));
  138. }
  139. internal static EGID UPDATE_REAL_ID(EGID egid, uint realID)
  140. {
  141. if (egid.hasID == 0)
  142. return new EGID(MAKE_GLOBAL_ID(SAFE_ID(realID), egid.groupID, realID, 0));
  143. return new EGID(MAKE_GLOBAL_ID(egid.entityID, egid.groupID, realID, 1));
  144. }
  145. internal static EGID CREATE_WITHOUT_ID(uint toGroupID, uint realID)
  146. {
  147. var _GID = MAKE_GLOBAL_ID(SAFE_ID(realID), toGroupID, realID, 0);
  148. return new EGID(_GID);
  149. }
  150. public byte hasID { get { return (byte) (_GID >> idbits + groupbits + realidbits); } }
  151. internal uint realID
  152. {
  153. get { return ((uint)(_GID >> idbits + groupbits)) & bit21; }
  154. }
  155. static uint SAFE_ID(uint u) { return u | (bit21 + 1); }
  156. }
  157. }
  158. #endif