ParticleIterator.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Copyright (c) Craftwork Games. All rights reserved.
  2. // Licensed under the MIT license.
  3. // See LICENSE file in the project root for full license information.
  4. using System;
  5. using MonoGame.Extended.Particles.Data;
  6. namespace MonoGame.Extended.Particles;
  7. /// <summary>
  8. /// Provides functionality for iterating through particles in a circular buffer.
  9. /// </summary>
  10. /// <remarks>
  11. /// The <see cref="ParticleIterator"/> class enables safe traversal of active particles in a
  12. /// <see cref="ParticleBuffer"/>, automatically handling the circular nature of the buffer and wrapping around
  13. /// boundaries as needed.
  14. /// </remarks>
  15. public sealed class ParticleIterator
  16. {
  17. private readonly ParticleBuffer _buffer;
  18. private unsafe Particle* _current;
  19. /// <summary>
  20. /// Gets the total number of particles that can be iterated over.
  21. /// </summary>
  22. public int Total { get; private set; }
  23. /// <summary>
  24. /// Gets a value indicating whether there are more particles to iterate over.
  25. /// </summary>
  26. /// <value>
  27. /// <see langword="true"/> if there are more particles available; otherwise, <see langword="false"/>.
  28. /// </value>
  29. public unsafe bool HasNext => _current != _buffer.Tail;
  30. /// <summary>
  31. /// Initializes a new instance of the <see cref="ParticleIterator"/> class.
  32. /// </summary>
  33. /// <param name="buffer">The <see cref="ParticleBuffer"/> to iterate over.</param>
  34. /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <see langword="null"/>.</exception>
  35. /// <exception cref="ObjectDisposedException"><paramref name="buffer"/> has previously been disposed.</exception>
  36. public ParticleIterator(ParticleBuffer buffer)
  37. {
  38. ArgumentNullException.ThrowIfNull(buffer);
  39. ObjectDisposedException.ThrowIf(buffer.IsDisposed, buffer);
  40. _buffer = buffer;
  41. }
  42. /// <summary>
  43. /// Resets the iterator to the beginning of the active particles in the buffer.
  44. /// </summary>
  45. /// <returns>This <see cref="ParticleIterator"/> instance.</returns>
  46. public unsafe ParticleIterator Reset()
  47. {
  48. _current = _buffer.Head;
  49. Total = _buffer.Count;
  50. return this;
  51. }
  52. /// <summary>
  53. /// Resets the iterator to a specific offset position within the active particles.
  54. /// </summary>
  55. /// <param name="offset">The number of particles to offset from the head position.</param>
  56. /// <returns>This <see cref="ParticleIterator"/> instance.</returns>
  57. internal unsafe ParticleIterator Reset(int offset)
  58. {
  59. Total = _buffer.Count;
  60. _current = _buffer.Head + offset;
  61. if (_current >= _buffer.BufferEnd)
  62. {
  63. _current -= _buffer.Size + 1;
  64. }
  65. return this;
  66. }
  67. /// <summary>
  68. /// Advances the iterator to the next particle and returns a pointer to the current particle.
  69. /// </summary>
  70. /// <returns>A pointer to the current particle before advancing the iterator.</returns>
  71. public unsafe Particle* Next()
  72. {
  73. Particle* particle = _current;
  74. _current++;
  75. if (_current == _buffer.BufferEnd)
  76. {
  77. _current = (Particle*)_buffer.NativePointer;
  78. }
  79. return particle;
  80. }
  81. }