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.

135 lines
4.3KB

  1. using System;
  2. using System.Runtime.CompilerServices;
  3. using System.Runtime.InteropServices;
  4. using Svelto.DataStructures;
  5. namespace Svelto.ECS
  6. {
  7. [StructLayout(LayoutKind.Explicit, Size = 4)]
  8. //the type doesn't implement IEqualityComparer, what implements it is a custom comparer
  9. public struct ExclusiveGroupStruct : IEquatable<ExclusiveGroupStruct>, IComparable<ExclusiveGroupStruct>
  10. {
  11. public static readonly ExclusiveGroupStruct Invalid = default; //must stay here because of Burst
  12. public ExclusiveGroupStruct(byte[] data, uint pos):this()
  13. {
  14. _id = (uint)(
  15. data[pos]
  16. | data[++pos] << 8
  17. | data[++pos] << 16
  18. );
  19. _bytemask = (byte) (data[++pos] << 24);
  20. DBC.ECS.Check.Ensure(_id < _globalId, "Invalid group ID deserialiased");
  21. }
  22. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  23. public override bool Equals(object obj)
  24. {
  25. return obj is ExclusiveGroupStruct other && Equals(other);
  26. }
  27. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  28. public override int GetHashCode()
  29. {
  30. return (int) _id;
  31. }
  32. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  33. public static bool operator ==(ExclusiveGroupStruct c1, ExclusiveGroupStruct c2)
  34. {
  35. return c1.Equals(c2);
  36. }
  37. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  38. public static bool operator !=(ExclusiveGroupStruct c1, ExclusiveGroupStruct c2)
  39. {
  40. return c1.Equals(c2) == false;
  41. }
  42. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  43. public bool Equals(ExclusiveGroupStruct other)
  44. {
  45. return other._id == _id;
  46. }
  47. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  48. public int CompareTo(ExclusiveGroupStruct other)
  49. {
  50. return other._id.CompareTo(_id);
  51. }
  52. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  53. public readonly bool IsEnabled()
  54. {
  55. return (_bytemask & (byte)ExclusiveGroupBitmask.DISABLED_BIT) == 0;
  56. }
  57. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  58. internal void Disable()
  59. {
  60. _bytemask |= (byte)ExclusiveGroupBitmask.DISABLED_BIT;
  61. }
  62. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  63. internal void Enable()
  64. {
  65. _bytemask &= (byte)(~ExclusiveGroupBitmask.DISABLED_BIT);
  66. }
  67. public override string ToString()
  68. {
  69. return this.ToName();
  70. }
  71. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  72. public static explicit operator uint(ExclusiveGroupStruct groupStruct)
  73. {
  74. return groupStruct._id;
  75. }
  76. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  77. public static ExclusiveGroupStruct operator+(ExclusiveGroupStruct a, uint b)
  78. {
  79. var group = new ExclusiveGroupStruct {_id = a._id + b};
  80. return @group;
  81. }
  82. internal static ExclusiveGroupStruct Generate(byte bitmask = 0)
  83. {
  84. ExclusiveGroupStruct groupStruct;
  85. groupStruct._id = _globalId;
  86. groupStruct._bytemask = bitmask;
  87. DBC.ECS.Check.Require(_globalId + 1 < ExclusiveGroup.MaxNumberOfExclusiveGroups, "too many exclusive groups created");
  88. _globalId++;
  89. return groupStruct;
  90. }
  91. internal ExclusiveGroupStruct(ExclusiveGroupStruct @group):this() { this = group; }
  92. /// <summary>
  93. /// Use this constructor to reserve N groups
  94. /// </summary>
  95. internal ExclusiveGroupStruct(ushort range):this()
  96. {
  97. _id = _globalId;
  98. DBC.ECS.Check.Require(_globalId + range < ExclusiveGroup.MaxNumberOfExclusiveGroups, "too many exclusive groups created");
  99. _globalId += range;
  100. }
  101. internal ExclusiveGroupStruct(uint groupID):this()
  102. {
  103. DBC.ECS.Check.Require(groupID < 0xFFFFFF);
  104. _id = groupID;
  105. }
  106. [FieldOffset(0)] uint _id;
  107. [FieldOffset(3)] byte _bytemask;
  108. static uint _globalId = 1; //it starts from 1 because default EGID is considered not initialized value
  109. }
  110. }