aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/api/0142-Async-Chunks-API.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/api/0142-Async-Chunks-API.patch')
-rw-r--r--patches/api/0142-Async-Chunks-API.patch530
1 files changed, 530 insertions, 0 deletions
diff --git a/patches/api/0142-Async-Chunks-API.patch b/patches/api/0142-Async-Chunks-API.patch
new file mode 100644
index 0000000000..68867e8a37
--- /dev/null
+++ b/patches/api/0142-Async-Chunks-API.patch
@@ -0,0 +1,530 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aikar <[email protected]>
+Date: Mon, 29 Feb 2016 17:43:33 -0600
+Subject: [PATCH] Async Chunks API
+
+Adds API's to load or generate chunks asynchronously.
+
+Also adds utility methods to Entity to teleport asynchronously.
+
+diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
+index b3098ce9134acf24f49d23fc1babe79c6bf502f1..5efe33cef4d9c153d760fc71606721ff8abafbfc 100644
+--- a/src/main/java/org/bukkit/World.java
++++ b/src/main/java/org/bukkit/World.java
+@@ -950,6 +950,472 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
+ }
+ // Paper end - additional getNearbyEntities API
+
++ // Paper start - async chunks API
++ /**
++ * This is the Legacy API before Java 8 was supported. Java 8 Consumer is provided,
++ * as well as future support
++ *
++ * Used by {@link World#getChunkAtAsync(Location,ChunkLoadCallback)} methods
++ * to request a {@link Chunk} to be loaded, with this callback receiving
++ * the chunk when it is finished.
++ *
++ * This callback will be executed on synchronously on the main thread.
++ *
++ * Timing and order this callback is fired is intentionally not defined and
++ * and subject to change.
++ *
++ * @deprecated Use either the Future or the Consumer based methods
++ */
++ @Deprecated
++ public static interface ChunkLoadCallback extends java.util.function.Consumer<Chunk> {
++ public void onLoad(@NotNull Chunk chunk);
++
++ // backwards compat to old api
++ @Override
++ default void accept(@NotNull Chunk chunk) {
++ onLoad(chunk);
++ }
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given coordinates
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The {@link ChunkLoadCallback} will always be executed synchronously
++ * on the main Server Thread.
++ *
++ * @deprecated Use either the Future or the Consumer based methods
++ * @param x Chunk X-coordinate of the chunk - floor(world coordinate / 16)
++ * @param z Chunk Z-coordinate of the chunk - floor(world coordinate / 16)
++ * @param cb Callback to receive the chunk when it is loaded.
++ * will be executed synchronously
++ */
++ @Deprecated
++ public default void getChunkAtAsync(int x, int z, @NotNull ChunkLoadCallback cb) {
++ getChunkAtAsync(x, z, true).thenAccept(cb::onLoad).exceptionally((ex) -> {
++ Bukkit.getLogger().log(java.util.logging.Level.WARNING, "Exception in chunk load callback", ex);
++ return null;
++ });
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given {@link Location}
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The {@link ChunkLoadCallback} will always be executed synchronously
++ * on the main Server Thread.
++ *
++ * @deprecated Use either the Future or the Consumer based methods
++ * @param loc Location of the chunk
++ * @param cb Callback to receive the chunk when it is loaded.
++ * will be executed synchronously
++ */
++ @Deprecated
++ public default void getChunkAtAsync(@NotNull Location loc, @NotNull ChunkLoadCallback cb) {
++ getChunkAtAsync(loc, true).thenAccept(cb::onLoad).exceptionally((ex) -> {
++ Bukkit.getLogger().log(java.util.logging.Level.WARNING, "Exception in chunk load callback", ex);
++ return null;
++ });
++ }
++
++ /**
++ * Requests {@link Chunk} to be loaded that contains the given {@link Block}
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The {@link ChunkLoadCallback} will always be executed synchronously
++ * on the main Server Thread.
++ *
++ * @deprecated Use either the Future or the Consumer based methods
++ * @param block Block to get the containing chunk from
++ * @param cb Callback to receive the chunk when it is loaded.
++ * will be executed synchronously
++ */
++ @Deprecated
++ public default void getChunkAtAsync(@NotNull Block block, @NotNull ChunkLoadCallback cb) {
++ getChunkAtAsync(block, true).thenAccept(cb::onLoad).exceptionally((ex) -> {
++ Bukkit.getLogger().log(java.util.logging.Level.WARNING, "Exception in chunk load callback", ex);
++ return null;
++ });
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given coordinates
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The {@link java.util.function.Consumer} will always be executed synchronously
++ * on the main Server Thread.
++ *
++ * @param x Chunk X-coordinate of the chunk - floor(world coordinate / 16)
++ * @param z Chunk Z-coordinate of the chunk - floor(world coordinate / 16)
++ * @param cb Callback to receive the chunk when it is loaded.
++ * will be executed synchronously
++ */
++ default void getChunkAtAsync(final int x, final int z, final @NotNull Consumer<? super Chunk> cb) {
++ this.getChunkAtAsync(x, z, true).thenAccept(cb).exceptionally((ex) -> {
++ Bukkit.getLogger().log(java.util.logging.Level.WARNING, "Exception in chunk load callback", ex);
++ return null;
++ });
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given coordinates
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The {@link java.util.function.Consumer} will always be executed synchronously
++ * on the main Server Thread.
++ *
++ * @param x Chunk X-coordinate of the chunk - floor(world coordinate / 16)
++ * @param z Chunk Z-coordinate of the chunk - floor(world coordinate / 16)
++ * @param gen Should we generate a chunk if it doesn't exist or not
++ * @param cb Callback to receive the chunk when it is loaded.
++ * will be executed synchronously
++ */
++ default void getChunkAtAsync(final int x, final int z, final boolean gen, final @NotNull Consumer<? super Chunk> cb) {
++ this.getChunkAtAsync(x, z, gen).thenAccept(cb).exceptionally((ex) -> {
++ Bukkit.getLogger().log(java.util.logging.Level.WARNING, "Exception in chunk load callback", ex);
++ return null;
++ });
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given {@link Location}
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The {@link java.util.function.Consumer} will always be executed synchronously
++ * on the main Server Thread.
++ *
++ * @param loc Location of the chunk
++ * @param cb Callback to receive the chunk when it is loaded.
++ * will be executed synchronously
++ */
++ default void getChunkAtAsync(final @NotNull Location loc, final @NotNull Consumer<? super Chunk> cb) {
++ this.getChunkAtAsync((int) Math.floor(loc.getX()) >> 4, (int) Math.floor(loc.getZ()) >> 4, true, cb);
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given {@link Location}
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The {@link java.util.function.Consumer} will always be executed synchronously
++ * on the main Server Thread.
++ *
++ * @param loc Location of the chunk
++ * @param gen Should the chunk generate if it doesn't exist
++ * @param cb Callback to receive the chunk when it is loaded.
++ * will be executed synchronously
++ */
++ default void getChunkAtAsync(final @NotNull Location loc, final boolean gen, final @NotNull Consumer<? super Chunk> cb) {
++ this.getChunkAtAsync((int) Math.floor(loc.getX()) >> 4, (int) Math.floor(loc.getZ()) >> 4, gen, cb);
++ }
++
++ /**
++ * Requests {@link Chunk} to be loaded that contains the given {@link Block}
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The {@link java.util.function.Consumer} will always be executed synchronously
++ * on the main Server Thread.
++ *
++ * @param block Block to get the containing chunk from
++ * @param cb Callback to receive the chunk when it is loaded.
++ * will be executed synchronously
++ */
++ default void getChunkAtAsync(final @NotNull Block block, final @NotNull Consumer<? super Chunk> cb) {
++ this.getChunkAtAsync(block.getX() >> 4, block.getZ() >> 4, true, cb);
++ }
++
++ /**
++ * Requests {@link Chunk} to be loaded that contains the given {@link Block}
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The {@link java.util.function.Consumer} will always be executed synchronously
++ * on the main Server Thread.
++ *
++ * @param block Block to get the containing chunk from
++ * @param gen Should the chunk generate if it doesn't exist
++ * @param cb Callback to receive the chunk when it is loaded.
++ * will be executed synchronously
++ */
++ default void getChunkAtAsync(final @NotNull Block block, final boolean gen, final @NotNull Consumer<? super Chunk> cb) {
++ this.getChunkAtAsync(block.getX() >> 4, block.getZ() >> 4, gen, cb);
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given coordinates
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The future will always be executed synchronously
++ * on the main Server Thread.
++ * @param loc Location to load the corresponding chunk from
++ * @return Future that will resolve when the chunk is loaded
++ */
++ default @NotNull java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsync(final @NotNull Location loc) {
++ return this.getChunkAtAsync((int) Math.floor(loc.getX()) >> 4, (int) Math.floor(loc.getZ()) >> 4, true);
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given coordinates
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The future will always be executed synchronously
++ * on the main Server Thread.
++ * @param loc Location to load the corresponding chunk from
++ * @param gen Should the chunk generate if it doesn't exist
++ * @return Future that will resolve when the chunk is loaded
++ */
++ default @NotNull java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsync(final @NotNull Location loc, final boolean gen) {
++ return this.getChunkAtAsync((int) Math.floor(loc.getX()) >> 4, (int) Math.floor(loc.getZ()) >> 4, gen);
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given coordinates
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The future will always be executed synchronously
++ * on the main Server Thread.
++ * @param block Block to load the corresponding chunk from
++ * @return Future that will resolve when the chunk is loaded
++ */
++ default @NotNull java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsync(final @NotNull Block block) {
++ return this.getChunkAtAsync(block.getX() >> 4, block.getZ() >> 4, true);
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given coordinates
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The future will always be executed synchronously
++ * on the main Server Thread.
++ * @param block Block to load the corresponding chunk from
++ * @param gen Should the chunk generate if it doesn't exist
++ * @return Future that will resolve when the chunk is loaded
++ */
++ default @NotNull java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsync(final @NotNull Block block, final boolean gen) {
++ return this.getChunkAtAsync(block.getX() >> 4, block.getZ() >> 4, gen);
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given coordinates
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The future will always be executed synchronously
++ * on the main Server Thread.
++ *
++ * @param x Chunk X-coordinate of the chunk - floor(world coordinate / 16)
++ * @param z Chunk Z-coordinate of the chunk - floor(world coordinate / 16)
++ * @return Future that will resolve when the chunk is loaded
++ */
++ default @NotNull java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsync(final int x, final int z) {
++ return this.getChunkAtAsync(x, z, true);
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given coordinates
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The future will always be executed synchronously
++ * on the main Server Thread.
++ *
++ * @param x Chunk X-coordinate of the chunk - floor(world coordinate / 16)
++ * @param z Chunk Z-coordinate of the chunk - floor(world coordinate / 16)
++ * @param gen Should we generate a chunk if it doesn't exist or not
++ * @return Future that will resolve when the chunk is loaded
++ */
++ default @NotNull java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsync(final int x, final int z, final boolean gen) {
++ return this.getChunkAtAsync(x, z, gen, false);
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given coordinates
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The future will always be executed synchronously
++ * on the main Server Thread.
++ * @param loc Location to load the corresponding chunk from
++ * @return Future that will resolve when the chunk is loaded
++ */
++ default @NotNull java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsyncUrgently(final @NotNull Location loc) {
++ return this.getChunkAtAsync((int) Math.floor(loc.getX()) >> 4, (int) Math.floor(loc.getZ()) >> 4, true, true);
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given coordinates
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The future will always be executed synchronously
++ * on the main Server Thread.
++ * @param loc Location to load the corresponding chunk from
++ * @param gen Should the chunk generate if it doesn't exist
++ * @return Future that will resolve when the chunk is loaded
++ */
++ default @NotNull java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsyncUrgently(final @NotNull Location loc, final boolean gen) {
++ return this.getChunkAtAsync((int) Math.floor(loc.getX()) >> 4, (int) Math.floor(loc.getZ()) >> 4, gen, true);
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given coordinates
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The future will always be executed synchronously
++ * on the main Server Thread.
++ * @param block Block to load the corresponding chunk from
++ * @return Future that will resolve when the chunk is loaded
++ */
++ default @NotNull java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsyncUrgently(final @NotNull Block block) {
++ return this.getChunkAtAsync(block.getX() >> 4, block.getZ() >> 4, true, true);
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given coordinates
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The future will always be executed synchronously
++ * on the main Server Thread.
++ * @param block Block to load the corresponding chunk from
++ * @param gen Should the chunk generate if it doesn't exist
++ * @return Future that will resolve when the chunk is loaded
++ */
++ default @NotNull java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsyncUrgently(final @NotNull Block block, final boolean gen) {
++ return this.getChunkAtAsync(block.getX() >> 4, block.getZ() >> 4, gen, true);
++ }
++
++ /**
++ * Requests a {@link Chunk} to be loaded at the given coordinates
++ *
++ * This method makes no guarantee on how fast the chunk will load,
++ * and will return the chunk to the callback at a later time.
++ *
++ * You should use this method if you need a chunk but do not need it
++ * immediately, and you wish to let the server control the speed
++ * of chunk loads, keeping performance in mind.
++ *
++ * The future will always be executed synchronously
++ * on the main Server Thread.
++ *
++ * @param x X Coord
++ * @param z Z Coord
++ * @return Future that will resolve when the chunk is loaded
++ */
++ default @NotNull java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsyncUrgently(final int x, final int z) {
++ return this.getChunkAtAsync(x, z, true, true);
++ }
++
++ java.util.concurrent.@NotNull CompletableFuture<Chunk> getChunkAtAsync(int x, int z, boolean gen, boolean urgent);
++ // Paper end - async chunks API
++
+ /**
+ * Get a list of all players in this World
+ *
+diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
+index 1e43deadce5a1a0e97521b1f69fee3106f5a0b9e..f1fc42ad24648ee481b9a5d4c4cc58ae8c0a93c1 100644
+--- a/src/main/java/org/bukkit/entity/Entity.java
++++ b/src/main/java/org/bukkit/entity/Entity.java
+@@ -168,6 +168,39 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
+ */
+ public boolean teleport(@NotNull Entity destination, @NotNull TeleportCause cause);
+
++ // Paper start
++ /**
++ * Loads/Generates(in 1.13+) the Chunk asynchronously, and then teleports the entity when the chunk is ready.
++ * @param loc Location to teleport to
++ * @return A future that will be completed with the result of the teleport
++ */
++ default java.util.concurrent.@NotNull CompletableFuture<Boolean> teleportAsync(final @NotNull Location loc) {
++ return this.teleportAsync(loc, TeleportCause.PLUGIN);
++ }
++
++ /**
++ * Loads/Generates(in 1.13+) the Chunk asynchronously, and then teleports the entity when the chunk is ready.
++ * @param loc Location to teleport to
++ * @param cause Reason for teleport
++ * @return A future that will be completed with the result of the teleport
++ */
++ default java.util.concurrent.@NotNull CompletableFuture<Boolean> teleportAsync(final @NotNull Location loc, final @NotNull TeleportCause cause) {
++ final class Holder {
++ static final io.papermc.paper.entity.TeleportFlag[] EMPTY_FLAGS = new io.papermc.paper.entity.TeleportFlag[0];
++ }
++ return this.teleportAsync(loc, cause, Holder.EMPTY_FLAGS);
++ }
++
++ /**
++ * Loads/Generates(in 1.13+) the Chunk asynchronously, and then teleports the entity when the chunk is ready.
++ * @param loc Location to teleport to
++ * @param cause Reason for teleport
++ * @param teleportFlags Flags to be used in this teleportation
++ * @return A future that will be completed with the result of the teleport
++ */
++ java.util.concurrent.@NotNull CompletableFuture<Boolean> teleportAsync(@NotNull Location loc, @NotNull TeleportCause cause, @NotNull io.papermc.paper.entity.TeleportFlag @NotNull... teleportFlags);
++ // Paper end
++
+ /**
+ * Returns a list of entities within a bounding box centered around this
+ * entity