| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- // 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;
- /// <summary>
- /// Provides functionality for iterating through particles in a circular buffer.
- /// </summary>
- /// <remarks>
- /// The <see cref="ParticleIterator"/> class enables safe traversal of active particles in a
- /// <see cref="ParticleBuffer"/>, automatically handling the circular nature of the buffer and wrapping around
- /// boundaries as needed.
- /// </remarks>
- public sealed class ParticleIterator
- {
- private readonly ParticleBuffer _buffer;
- private unsafe Particle* _current;
- /// <summary>
- /// Gets the total number of particles that can be iterated over.
- /// </summary>
- public int Total { get; private set; }
- /// <summary>
- /// Gets a value indicating whether there are more particles to iterate over.
- /// </summary>
- /// <value>
- /// <see langword="true"/> if there are more particles available; otherwise, <see langword="false"/>.
- /// </value>
- public unsafe bool HasNext => _current != _buffer.Tail;
- /// <summary>
- /// Initializes a new instance of the <see cref="ParticleIterator"/> class.
- /// </summary>
- /// <param name="buffer">The <see cref="ParticleBuffer"/> to iterate over.</param>
- /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <see langword="null"/>.</exception>
- /// <exception cref="ObjectDisposedException"><paramref name="buffer"/> has previously been disposed.</exception>
- public ParticleIterator(ParticleBuffer buffer)
- {
- ArgumentNullException.ThrowIfNull(buffer);
- ObjectDisposedException.ThrowIf(buffer.IsDisposed, buffer);
- _buffer = buffer;
- }
- /// <summary>
- /// Resets the iterator to the beginning of the active particles in the buffer.
- /// </summary>
- /// <returns>This <see cref="ParticleIterator"/> instance.</returns>
- public unsafe ParticleIterator Reset()
- {
- _current = _buffer.Head;
- Total = _buffer.Count;
- return this;
- }
- /// <summary>
- /// Resets the iterator to a specific offset position within the active particles.
- /// </summary>
- /// <param name="offset">The number of particles to offset from the head position.</param>
- /// <returns>This <see cref="ParticleIterator"/> instance.</returns>
- internal unsafe ParticleIterator Reset(int offset)
- {
- Total = _buffer.Count;
- _current = _buffer.Head + offset;
- if (_current >= _buffer.BufferEnd)
- {
- _current -= _buffer.Size + 1;
- }
- return this;
- }
- /// <summary>
- /// Advances the iterator to the next particle and returns a pointer to the current particle.
- /// </summary>
- /// <returns>A pointer to the current particle before advancing the iterator.</returns>
- public unsafe Particle* Next()
- {
- Particle* particle = _current;
- _current++;
- if (_current == _buffer.BufferEnd)
- {
- _current = (Particle*)_buffer.NativePointer;
- }
- return particle;
- }
- }
|