// 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;
}
}