Mirror of Svelto.ECS because we're a fan of it
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

174 lignes
6.3KB

  1. using System;
  2. using System.Diagnostics;
  3. using System.Runtime.CompilerServices;
  4. using System.Runtime.InteropServices;
  5. using System.Threading;
  6. namespace Svelto.ECS
  7. {
  8. [DebuggerDisplay("{ToString()}")]
  9. [StructLayout(LayoutKind.Explicit, Size = 4)]
  10. //the type doesn't implement IEqualityComparer, what implements it is a custom comparer
  11. public readonly struct ExclusiveGroupStruct : IEquatable<ExclusiveGroupStruct>, IComparable<ExclusiveGroupStruct>
  12. {
  13. public static readonly ExclusiveGroupStruct Invalid = default; //must stay here because of Burst
  14. public ExclusiveGroupStruct(byte[] data, uint pos):this()
  15. {
  16. _idInternal = (uint)(
  17. data[pos]
  18. | data[++pos] << 8
  19. | data[++pos] << 16
  20. );
  21. _bytemask = (byte) (data[++pos] << 24);
  22. DBC.ECS.Check.Ensure(id < _globalId, "Invalid group ID deserialiased");
  23. }
  24. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  25. public override bool Equals(object obj)
  26. {
  27. return obj is ExclusiveGroupStruct other && Equals(other);
  28. }
  29. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  30. public override int GetHashCode()
  31. {
  32. return (int) id;
  33. }
  34. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  35. public static bool operator ==(ExclusiveGroupStruct c1, ExclusiveGroupStruct c2)
  36. {
  37. return c1.Equals(c2);
  38. }
  39. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  40. public static bool operator !=(ExclusiveGroupStruct c1, ExclusiveGroupStruct c2)
  41. {
  42. return c1.Equals(c2) == false;
  43. }
  44. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  45. public bool Equals(ExclusiveGroupStruct other)
  46. {
  47. #if DEBUG && !PROFILE_SVELTO
  48. if ((other.id != this.id || other._bytemask == this._bytemask) == false)
  49. throw new ECSException(
  50. "if the groups are correctly initialised, two groups with the same ID and different bitmask cannot exist");
  51. #endif
  52. return other.id == this.id;
  53. }
  54. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  55. public int CompareTo(ExclusiveGroupStruct other)
  56. {
  57. return other.id.CompareTo(id);
  58. }
  59. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  60. public bool IsEnabled()
  61. {
  62. return (_bytemask & (byte)ExclusiveGroupBitmask.DISABLED_BIT) == 0;
  63. }
  64. public override string ToString()
  65. {
  66. return this.ToName();
  67. }
  68. public bool isInvalid => this == Invalid;
  69. public uint id => _idInternal & 0xFFFFFF;
  70. public uint ToIDAndBitmask() => _idInternal;
  71. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  72. public static ExclusiveGroupStruct operator+(ExclusiveGroupStruct a, uint b)
  73. {
  74. var aID = a.id + b;
  75. #if DEBUG && !PROFILE_SVELTO
  76. if (aID >= 0xFFFFFF)
  77. throw new IndexOutOfRangeException();
  78. #endif
  79. var group = new ExclusiveGroupStruct(aID);
  80. return @group;
  81. }
  82. internal static ExclusiveGroupStruct Generate()
  83. {
  84. var newValue = Interlocked.Increment(ref _staticGlobalID);
  85. ExclusiveGroupStruct groupStruct = new ExclusiveGroupStruct((uint) newValue - (uint) 1);
  86. DBC.ECS.Check.Require(_globalId < ExclusiveGroup.MaxNumberOfExclusiveGroups, "too many exclusive groups created");
  87. return groupStruct;
  88. }
  89. internal static ExclusiveGroupStruct Generate(byte bitmask)
  90. {
  91. var newValue = Interlocked.Increment(ref _staticGlobalID);
  92. ExclusiveGroupStruct groupStruct = new ExclusiveGroupStruct((uint) newValue - (uint) 1, bitmask);
  93. DBC.ECS.Check.Require(_globalId < ExclusiveGroup.MaxNumberOfExclusiveGroups, "too many exclusive groups created");
  94. return groupStruct;
  95. }
  96. /// <summary>
  97. /// Use this to reserve N groups. We of course assign the current ID and then increment the index
  98. /// by range so that the next reserved index will take the range in consideration. This method is used
  99. /// internally by ExclusiveGroup.
  100. /// </summary>
  101. internal static ExclusiveGroupStruct GenerateWithRange(ushort range)
  102. {
  103. var newValue = Interlocked.Add(ref _staticGlobalID, (int)range);
  104. ExclusiveGroupStruct groupStruct = new ExclusiveGroupStruct((uint) newValue - (uint)range);
  105. DBC.ECS.Check.Require(_globalId < ExclusiveGroup.MaxNumberOfExclusiveGroups, "too many exclusive groups created");
  106. return groupStruct;
  107. }
  108. /// <summary>
  109. /// used internally only by the framework to convert uint in to groups. ID must be generated by the framework
  110. /// so only the framework can assure that this method is not being abused
  111. /// </summary>
  112. internal ExclusiveGroupStruct(uint groupID):this()
  113. {
  114. #if DEBUG && !PROFILE_SVELTO
  115. if (groupID >= 0xFFFFFF)
  116. throw new IndexOutOfRangeException();
  117. #endif
  118. _idInternal = groupID;
  119. }
  120. ExclusiveGroupStruct(uint groupID, byte bytemask):this()
  121. {
  122. #if DEBUG && !PROFILE_SVELTO
  123. if (groupID >= 0xFFFFFF)
  124. throw new IndexOutOfRangeException();
  125. #endif
  126. _idInternal = groupID;
  127. _bytemask = bytemask;
  128. }
  129. static ExclusiveGroupStruct()
  130. {
  131. _staticGlobalID = 1;
  132. }
  133. [FieldOffset(0)] readonly uint _idInternal;
  134. //byte mask can be used to add special flags to specific groups that can be checked for example when swapping groups
  135. //however at the moment we are not letting the user access it, because if we do so we should give access only to
  136. //4 bits are the other 4 bits will stay reserved for Svelto use (at the moment of writing using only the disable
  137. //bit)
  138. [FieldOffset(3)] readonly byte _bytemask;
  139. static int _staticGlobalID;
  140. static uint _globalId => (uint) _staticGlobalID;
  141. }
  142. }