// Copyright (c) Craftwork Games. All rights reserved. // Licensed under the MIT license. // See LICENSE file in the project root for full license information. using System; using MonoGame.Extended.Particles.Data; namespace MonoGame.Extended.Particles; /// /// Provides functionality for iterating through particles in a circular buffer. /// /// /// The class enables safe traversal of active particles in a /// , automatically handling the circular nature of the buffer and wrapping around /// boundaries as needed. /// public sealed class ParticleIterator { private readonly ParticleBuffer _buffer; private unsafe Particle* _current; /// /// Gets the total number of particles that can be iterated over. /// public int Total { get; private set; } /// /// Gets a value indicating whether there are more particles to iterate over. /// /// /// if there are more particles available; otherwise, . /// public unsafe bool HasNext => _current != _buffer.Tail; /// /// Initializes a new instance of the class. /// /// The to iterate over. /// is . /// has previously been disposed. public ParticleIterator(ParticleBuffer buffer) { ArgumentNullException.ThrowIfNull(buffer); ObjectDisposedException.ThrowIf(buffer.IsDisposed, buffer); _buffer = buffer; } /// /// Resets the iterator to the beginning of the active particles in the buffer. /// /// This instance. public unsafe ParticleIterator Reset() { _current = _buffer.Head; Total = _buffer.Count; return this; } /// /// Resets the iterator to a specific offset position within the active particles. /// /// The number of particles to offset from the head position. /// This instance. internal unsafe ParticleIterator Reset(int offset) { Total = _buffer.Count; _current = _buffer.Head + offset; if (_current >= _buffer.BufferEnd) { _current -= _buffer.Size + 1; } return this; } /// /// Advances the iterator to the next particle and returns a pointer to the current particle. /// /// A pointer to the current particle before advancing the iterator. public unsafe Particle* Next() { Particle* particle = _current; _current++; if (_current == _buffer.BufferEnd) { _current = (Particle*)_buffer.NativePointer; } return particle; } }