aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/api/0389-Add-Tick-TemporalUnit.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/api/0389-Add-Tick-TemporalUnit.patch')
-rw-r--r--patches/api/0389-Add-Tick-TemporalUnit.patch156
1 files changed, 156 insertions, 0 deletions
diff --git a/patches/api/0389-Add-Tick-TemporalUnit.patch b/patches/api/0389-Add-Tick-TemporalUnit.patch
new file mode 100644
index 0000000000..562eb00082
--- /dev/null
+++ b/patches/api/0389-Add-Tick-TemporalUnit.patch
@@ -0,0 +1,156 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Kieran Wallbanks <[email protected]>
+Date: Fri, 2 Apr 2021 17:28:58 +0100
+Subject: [PATCH] Add Tick TemporalUnit
+
+
+diff --git a/src/main/java/io/papermc/paper/util/Tick.java b/src/main/java/io/papermc/paper/util/Tick.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..10430f02e1d1e654383154c04473f07469bc7fee
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/util/Tick.java
+@@ -0,0 +1,95 @@
++package io.papermc.paper.util;
++
++import net.kyori.adventure.util.Ticks;
++import org.jetbrains.annotations.NotNull;
++
++import java.time.Duration;
++import java.time.temporal.ChronoUnit;
++import java.time.temporal.Temporal;
++import java.time.temporal.TemporalUnit;
++import java.util.Objects;
++
++/**
++ * A TemporalUnit that represents the target length of one server tick. This is defined
++ * as 50 milliseconds. Note that this class is not for measuring the length that a tick
++ * took, rather it is used for simple conversion between times and ticks.
++ * @see #tick()
++ */
++public final class Tick implements TemporalUnit {
++ private static final Tick INSTANCE = new Tick(Ticks.SINGLE_TICK_DURATION_MS);
++
++ private final long milliseconds;
++
++ /**
++ * Gets the instance of the tick temporal unit.
++ * @return the tick instance
++ */
++ public static @NotNull Tick tick() {
++ return INSTANCE;
++ }
++
++ /**
++ * Creates a new tick.
++ * @param length the length of the tick in milliseconds
++ * @see #tick()
++ */
++ private Tick(long length) {
++ this.milliseconds = length;
++ }
++
++ /**
++ * Creates a duration from an amount of ticks. This is shorthand for
++ * {@link Duration#of(long, TemporalUnit)} called with the amount of ticks and
++ * {@link #tick()}.
++ * @param ticks the amount of ticks
++ * @return the duration
++ */
++ public static @NotNull Duration of(long ticks) {
++ return Duration.of(ticks, INSTANCE);
++ }
++
++ /**
++ * Gets the number of whole ticks that occur in the provided duration. Note that this
++ * method returns an {@code int} as this is the unit that Minecraft stores ticks in.
++ * @param duration the duration
++ * @return the number of whole ticks in this duration
++ * @throws ArithmeticException if the duration is zero or an overflow occurs
++ */
++ public int fromDuration(@NotNull Duration duration) {
++ Objects.requireNonNull(duration, "duration cannot be null");
++ return Math.toIntExact(Math.floorDiv(duration.toMillis(), this.milliseconds));
++ }
++
++ @Override
++ public @NotNull Duration getDuration() {
++ return Duration.ofMillis(this.milliseconds);
++ }
++
++ // Note: This is a workaround in order to allow calculations with this duration.
++ // See: Duration#add
++ @Override
++ public boolean isDurationEstimated() {
++ return false;
++ }
++
++ @Override
++ public boolean isDateBased() {
++ return false;
++ }
++
++ @Override
++ public boolean isTimeBased() {
++ return true;
++ }
++
++ @SuppressWarnings("unchecked") // following ChronoUnit#addTo
++ @Override
++ public <R extends Temporal> @NotNull R addTo(@NotNull R temporal, long amount) {
++ return (R) temporal.plus(getDuration().multipliedBy(amount));
++ }
++
++ @Override
++ public long between(@NotNull Temporal start, @NotNull Temporal end) {
++ return start.until(end, ChronoUnit.MILLIS) / this.milliseconds;
++ }
++}
+diff --git a/src/test/java/io/papermc/paper/util/TickTest.java b/src/test/java/io/papermc/paper/util/TickTest.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..f147d909f2fc710c1d12bac3c7b66c2883139026
+--- /dev/null
++++ b/src/test/java/io/papermc/paper/util/TickTest.java
+@@ -0,0 +1,43 @@
++package io.papermc.paper.util;
++
++import java.time.Duration;
++import java.time.Instant;
++import java.time.temporal.ChronoUnit;
++import org.junit.jupiter.api.Test;
++
++import static org.junit.jupiter.api.Assertions.assertEquals;
++
++public class TickTest {
++
++ @Test
++ public void testTickLength() {
++ assertEquals(50, Duration.of(1, Tick.tick()).toMillis());
++ assertEquals(100, Duration.of(2, Tick.tick()).toMillis());
++ }
++
++ @Test
++ public void testTickFromDuration() {
++ assertEquals(0, Tick.tick().fromDuration(Duration.ofMillis(0)));
++ assertEquals(0, Tick.tick().fromDuration(Duration.ofMillis(10)));
++ assertEquals(1, Tick.tick().fromDuration(Duration.ofMillis(60)));
++ assertEquals(2, Tick.tick().fromDuration(Duration.ofMillis(100)));
++ }
++
++ @Test
++ public void testAddTickToInstant() {
++ Instant now = Instant.now();
++ assertEquals(now, now.plus(0, Tick.tick()));
++ assertEquals(now.plus(50, ChronoUnit.MILLIS), now.plus(1, Tick.tick()));
++ assertEquals(now.plus(100, ChronoUnit.MILLIS), now.plus(2, Tick.tick()));
++ assertEquals(now.plus(150, ChronoUnit.MILLIS), now.plus(3, Tick.tick()));
++ }
++
++ @Test
++ public void testTicksBetweenInstants() {
++ Instant now = Instant.now();
++ assertEquals(0, now.until(now.plus(20, ChronoUnit.MILLIS), Tick.tick()));
++ assertEquals(1, now.until(now.plus(50, ChronoUnit.MILLIS), Tick.tick()));
++ assertEquals(1, now.until(now.plus(60, ChronoUnit.MILLIS), Tick.tick()));
++ assertEquals(2, now.until(now.plus(100, ChronoUnit.MILLIS), Tick.tick()));
++ }
++}