Mirror of Svelto.ECS because we're a fan of it
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

114 строки
3.2KB

  1. using System;
  2. using Svelto.Common;
  3. using Svelto.DataStructures;
  4. using Svelto.ECS.Internal;
  5. namespace Svelto.ECS
  6. {
  7. public struct Consumer<T> : IDisposable where T : unmanaged, _IInternalEntityComponent
  8. {
  9. internal Consumer(string name, uint capacity) : this()
  10. {
  11. unsafe
  12. {
  13. #if DEBUG && !PROFILE_SVELTO
  14. _name = name;
  15. #endif
  16. _ringBuffer = new RingBuffer<ValueTuple<T, EGID>>((int) capacity,
  17. #if DEBUG && !PROFILE_SVELTO
  18. _name
  19. #else
  20. string.Empty
  21. #endif
  22. );
  23. mustBeDisposed = MemoryUtilities.NativeAlloc<bool>(1, Allocator.Persistent);
  24. *(bool*) mustBeDisposed = false;
  25. isActive = MemoryUtilities.NativeAlloc<bool>(1, Allocator.Persistent);
  26. *(bool*) isActive = true;
  27. }
  28. }
  29. internal Consumer(ExclusiveGroupStruct group, string name, uint capacity) : this(name, capacity)
  30. {
  31. this.group = group;
  32. hasGroup = true;
  33. }
  34. internal void Enqueue(in T entity, in EGID egid)
  35. {
  36. unsafe
  37. {
  38. if (*(bool*)isActive)
  39. _ringBuffer.Enqueue((entity, egid));
  40. }
  41. }
  42. public bool TryDequeue(out T entity)
  43. {
  44. var tryDequeue = _ringBuffer.TryDequeue(out var values);
  45. entity = values.Item1;
  46. return tryDequeue;
  47. }
  48. //Note: it is correct to publish the EGID at the moment of the publishing, as the responsibility of
  49. //the publisher consumer is not tracking the real state of the entity in the database at the
  50. //moment of the consumption, but it's instead to store a copy of the entity at the moment of the publishing
  51. public bool TryDequeue(out T entity, out EGID id)
  52. {
  53. var tryDequeue = _ringBuffer.TryDequeue(out var values);
  54. entity = values.Item1;
  55. id = values.Item2;
  56. return tryDequeue;
  57. }
  58. public void Flush() { _ringBuffer.Reset(); }
  59. public void Dispose()
  60. {
  61. unsafe
  62. {
  63. *(bool*) mustBeDisposed = true;
  64. }
  65. }
  66. public uint Count() { return (uint) _ringBuffer.Count; }
  67. public void Free()
  68. {
  69. MemoryUtilities.NativeFree(mustBeDisposed, Allocator.Persistent);
  70. MemoryUtilities.NativeFree(isActive, Allocator.Persistent);
  71. }
  72. public void Pause()
  73. {
  74. unsafe
  75. {
  76. *(bool*) isActive = false;
  77. }
  78. }
  79. public void Resume()
  80. {
  81. unsafe
  82. {
  83. *(bool*) isActive = true;
  84. }
  85. }
  86. readonly RingBuffer<ValueTuple<T, EGID>> _ringBuffer;
  87. internal readonly ExclusiveGroupStruct group;
  88. internal readonly bool hasGroup;
  89. internal IntPtr isActive;
  90. internal IntPtr mustBeDisposed;
  91. #if DEBUG && !PROFILE_SVELTO
  92. readonly string _name;
  93. #endif
  94. }
  95. }