diff options
author | iamblackornot <nkzshinnik@gmail.com> | 2023-10-12 14:38:45 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-12 13:38:45 +0200 |
commit | 820ebd76016b69a0346588bcdc90a53f251e5b4c (patch) | |
tree | 00c83d3b750119ef63909204941bcec883f08019 /src/main/java/gregtech/api/util | |
parent | 0f1df8bb1de3ab5567e6b38e2d8c59edf6be12d8 (diff) | |
download | GT5-Unofficial-820ebd76016b69a0346588bcdc90a53f251e5b4c.tar.gz GT5-Unofficial-820ebd76016b69a0346588bcdc90a53f251e5b4c.tar.bz2 GT5-Unofficial-820ebd76016b69a0346588bcdc90a53f251e5b4c.zip |
average per tick counter for cable voltage and amperage (#2321)
* - a workaround fix to https://github.com/GTNewHorizons/GT-New-Horizons-Modpack/issues/14431
- code clean-up of unused variables related to the issue
- portable scanner infodata is cleaned too since some of the data is related to mentioned before "ghost" variables
* - PR review changes
* "Current Amperage" -> "Amperage"
* - updated gradle build script
* - sync fork
* added AveragePerTickCounter class, which helps getting [current tick] value and [average] value for Amperage and Voltage of energy cable blocks
updated cable scanner info to show these values
* - lowercase the first letter of new methods to follow the guidelines
- added one comment to explain code segment's logic
---------
Co-authored-by: iamblackornot <nkzshinnnik@gmail.com>
Diffstat (limited to 'src/main/java/gregtech/api/util')
-rw-r--r-- | src/main/java/gregtech/api/util/AveragePerTickCounter.java | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/src/main/java/gregtech/api/util/AveragePerTickCounter.java b/src/main/java/gregtech/api/util/AveragePerTickCounter.java new file mode 100644 index 0000000000..c9b1275deb --- /dev/null +++ b/src/main/java/gregtech/api/util/AveragePerTickCounter.java @@ -0,0 +1,139 @@ +package gregtech.api.util; + +import java.security.InvalidParameterException; +import java.util.ArrayDeque; + +import net.minecraft.server.MinecraftServer; + +public class AveragePerTickCounter { + + /** + * Averages a value over a certain amount of ticks + * + * @param period amount of ticks to average (20 for 1 second) + * + */ + public AveragePerTickCounter(int period) throws InvalidParameterException { + + if (period <= 0) throw new InvalidParameterException("period should be a positive non-zero number"); + + this.period = period; + values = new ArrayDeque<>(period); + } + + public void addValue(long value) { + + if (value == 0) return; + + final int currTick = getWorldTimeInTicks(); + + if (values.isEmpty()) { + values.addLast(new Measurement(currTick, value)); + isCachedAverageValid = false; + return; + } + + Measurement lastMeasurement = values.peekLast(); + final int lastMeasurementTick = lastMeasurement.TimestampInWorldTicks; + + /// sums up values added in the same tick + /// for example a cable had an amp running through it multiple times in the same tick + if (currTick == lastMeasurementTick) { + lastMeasurement.Value = lastMeasurement.Value + value; + isCachedAverageValid = false; + return; + } + + if (currTick > lastMeasurementTick) { + trimIrrelevantData(currTick); + + values.addLast(new Measurement(currTick, value)); + isCachedAverageValid = false; + return; + } + } + + public double getAverage() { + + if (values.isEmpty()) return 0; + + final int currTick = getWorldTimeInTicks(); + + Measurement lastMeasurement = values.peekLast(); + final int lastMeasurementTick = lastMeasurement.TimestampInWorldTicks; + + if (currTick < lastMeasurementTick) return 0; + + if (currTick > lastMeasurementTick) { + trimIrrelevantData(currTick); + } + + if (isCachedAverageValid) return cachedAverage; + + return calculateAverage(); + } + + public long getLast() { + + if (values.isEmpty()) return 0; + + final int currTick = getWorldTimeInTicks(); + + Measurement lastMeasurement = values.peekLast(); + final int lastMeasurementTick = lastMeasurement.TimestampInWorldTicks; + + if (currTick == lastMeasurementTick) return values.getLast().Value; + + return 0; + } + + private double calculateAverage() { + + isCachedAverageValid = true; + long sum = 0; + + for (Measurement measurement : values) { + sum += measurement.Value; + } + + return sum / (double) period; + } + + private void trimIrrelevantData(int currWorldTimeInTicks) { + + if (values.isEmpty()) return; + + int firstMeasurementTick = values.peekFirst().TimestampInWorldTicks; + + while (currWorldTimeInTicks - firstMeasurementTick >= period) { + values.removeFirst(); + isCachedAverageValid = false; + + if (values.isEmpty()) return; + + firstMeasurementTick = values.peekFirst().TimestampInWorldTicks; + } + } + + private int getWorldTimeInTicks() { + return MinecraftServer.getServer() + .getTickCounter(); + } + + private ArrayDeque<Measurement> values; + private int period; + + private double cachedAverage = 0; + private boolean isCachedAverageValid = true; + + private class Measurement { + + public int TimestampInWorldTicks; + public long Value; + + public Measurement(int timestampInWorldTicks, long value) { + this.TimestampInWorldTicks = timestampInWorldTicks; + this.Value = value; + } + } +} |