using FishNet.Documenting;
using System;
using UnityEngine;
namespace FishNet.Managing.Timing
{
[APIExclude]
public class MovingAverage
{
#region Public.
///
/// Average from samples favoring the most recent sample.
///
public float Average { get; private set; }
#endregion
///
/// Next index to write a sample to.
///
private int _writeIndex;
///
/// Collected samples.
///
private float[] _samples;
///
/// Number of samples written. Will be at most samples size.
///
private int _writtenSamples;
///
/// Samples accumulated over queue.
///
private float _sampleAccumulator;
public MovingAverage(int sampleSize)
{
if (sampleSize < 0)
sampleSize = 0;
else if (sampleSize < 2)
NetworkManager.StaticLogWarning("Using a sampleSize of less than 2 will always return the most recent value as Average.");
_samples = new float[sampleSize];
}
///
/// Computes a new windowed average each time a new sample arrives
///
///
public void ComputeAverage(float newSample)
{
if (_samples.Length <= 1)
{
Average = newSample;
return;
}
_sampleAccumulator += newSample;
_samples[_writeIndex] = newSample;
//Increase writeIndex.
_writeIndex++;
_writtenSamples = Math.Max(_writtenSamples, _writeIndex);
if (_writeIndex >= _samples.Length)
_writeIndex = 0;
Average = _sampleAccumulator / _writtenSamples;
/* If samples are full then drop off
* the oldest sample. This will always be
* the one just after written. The entry isn't
* actually removed from the array but will
* be overwritten next sample. */
if (_writtenSamples >= _samples.Length)
_sampleAccumulator -= _samples[_writeIndex];
}
}
}