Skip to content

Commit

Permalink
Add better feedback to users about biome changing process.
Browse files Browse the repository at this point in the history
  • Loading branch information
BONNe committed Jan 23, 2022
1 parent 85d1017 commit 29691b9
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ private void changeBiome()
/**
* This variable stores update range
*/
private int range;
private int range = 1;

/**
* This variable stores update mode
Expand Down
11 changes: 6 additions & 5 deletions src/main/java/world/bentobox/biomes/tasks/BiomeUpdateHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.bukkit.Bukkit;
Expand Down Expand Up @@ -421,12 +425,9 @@ public void updateIslandBiome()
{
// Calculate minimal and maximal coordinate based on update mode.

CompletableFuture<UpdateQueue.Result> completableFuture = new CompletableFuture<>();

BiomeUpdateTask task = new BiomeUpdateTask(this.addon,
this.callerUser,
this.biome,
completableFuture);
this.biome);

// Select world depending on environment.

Expand Down Expand Up @@ -465,7 +466,7 @@ else if (World.Environment.THE_END.equals(this.biome.getEnvironment()))
{
task.updateChunkQueue();

this.addon.getUpdateQueue().addUpdateTask(task).thenAccept(result ->
this.addon.getUpdateQueue().addUpdateTask(task).thenAccept((result) ->
{
switch (result)
{
Expand Down
31 changes: 24 additions & 7 deletions src/main/java/world/bentobox/biomes/tasks/BiomeUpdateTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import java.util.Queue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;

Expand Down Expand Up @@ -31,12 +32,10 @@ public class BiomeUpdateTask
* @param addon BiomeAddon object.
* @param user Player who calls biome update.
* @param biome BiomeObject that will changed.
* @param result Result exposer.
*/
public BiomeUpdateTask(BiomesAddon addon,
User user,
BiomesObject biome,
CompletableFuture<UpdateQueue.Result> result)
BiomesObject biome)
{
this.addon = addon;
this.user = user;
Expand All @@ -45,7 +44,7 @@ public BiomeUpdateTask(BiomesAddon addon,
this.biomesObject = biome;

this.chunksToUpdate = new ConcurrentLinkedQueue<>();
this.result = result;
this.result = new CompletableFuture<>();

this.processCounter = new AtomicInteger(0);
}
Expand Down Expand Up @@ -88,8 +87,10 @@ public void processBiomeChange(UpdateQueue updateQueue)
this.addon.logError("scanChunk not on Primary Thread!");
}

long runTime = System.currentTimeMillis() - updateQueue.getProcessStartMap().get(this);

// Timeout check
if (System.currentTimeMillis() - updateQueue.getProcessStartMap().get(this) > this.addon.getSettings().getChangeTimeout() * 60000)
if (runTime > this.addon.getSettings().getChangeTimeout() * 60000)
{
// Done
updateQueue.getProcessStartMap().remove(this);
Expand All @@ -106,6 +107,9 @@ public void processBiomeChange(UpdateQueue updateQueue)
if (this.chunksToUpdate.isEmpty())
{
// Done there are no more things to process
updateQueue.updateTimer(runTime, this.getNumberOfChunks());
updateQueue.getProcessStartMap().remove(this);

this.result.complete(UpdateQueue.Result.FINISHED);
}
else
Expand Down Expand Up @@ -337,14 +341,27 @@ public int getNumberOfChunks()


/**
* Notify biome change process starting to the user.
* Notify that biome is added in processing queue.
*/
public void notifyStarting()
{
Utils.sendMessage(this.user, this.user.getTranslation(
Constants.MESSAGES + "update-start",
"[biome]", this.biomesObject.getFriendlyName(),
"[number]", String.valueOf(this.numberOfChunks)));
"[number]", String.valueOf(this.getNumberOfChunks()),
"[time]", String.valueOf((int)
Math.max(1, this.getNumberOfChunks() * this.addon.getUpdateQueue().getChunkTime()))));
}


/**
* Notify that biome is added in waiting queue.
*/
public void notifyWaiting()
{
Utils.sendMessage(this.user,
this.user.getTranslation(Constants.MESSAGES + "waiting",
"[time]", String.valueOf(this.addon.getUpdateQueue().getQueueTime())));
}


Expand Down
69 changes: 66 additions & 3 deletions src/main/java/world/bentobox/biomes/tasks/UpdateQueue.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@

import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitTask;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.*;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicLong;

import world.bentobox.bentobox.BentoBox;
import world.bentobox.biomes.BiomesAddon;
Expand All @@ -34,6 +33,9 @@ public UpdateQueue(BiomesAddon addon)
this.processQueue = new ConcurrentLinkedQueue<>();
this.processStartMap = new HashMap<>();

this.timer = new AtomicLong(0);
this.counter = new AtomicLong(0);

this.task = Bukkit.getScheduler().runTaskTimer(BentoBox.getInstance(), () -> {
if (!BentoBox.getInstance().isEnabled() || !this.addon.isEnabled())
{
Expand All @@ -50,6 +52,7 @@ public UpdateQueue(BiomesAddon addon)
for (int i = 0; i < this.addon.getSettings().getConcurrentBiomeUpdates() && !this.processQueue.isEmpty(); i++)
{
BiomeUpdateTask updateTask = this.processQueue.poll();
// Notify starting
updateTask.notifyStarting();
this.processStartMap.put(updateTask, System.currentTimeMillis());
// Start the scanning of an area chunks
Expand Down Expand Up @@ -114,11 +117,61 @@ public BukkitTask getTask()
*/
public CompletionStage<Result> addUpdateTask(BiomeUpdateTask task)
{
if (this.processStartMap.size() >= this.addon.getSettings().getConcurrentBiomeUpdates())
{
task.notifyWaiting();
}

this.processQueue.add(task);
return task.getResult();
}


/**
* Updates timer for changing biome.
*
* @param timer the timer
* @param chunks the number of chunks
*/
public void updateTimer(long timer, long chunks)
{
this.counter.addAndGet(chunks);
this.timer.addAndGet(timer);
}


/**
* Get the average time it takes to run a level check
* @return the average time in seconds
*/
public int getQueueTime()
{
double average = this.getChunkTime();

int time = 0;

List<BiomeUpdateTask> updateTaskList = new ArrayList<>(this.processQueue);
updateTaskList.addAll(this.processStartMap.keySet());

for (BiomeUpdateTask biomeUpdateTask : updateTaskList)
{
time += biomeUpdateTask.getNumberOfChunks() * average;
}

return time == 0 ? 1 : time;
}


/**
* Gets average time per processing a chunk.
* @return the chunk time
*/
public double getChunkTime()
{
return this.counter.get() == 0 ? 0.05 : 1.0 * this.timer.get() / this.counter.get() / 1000;
}


// ---------------------------------------------------------------------
// Section: Emums
// ---------------------------------------------------------------------
Expand Down Expand Up @@ -168,4 +221,14 @@ public enum Result
* Main bukkit task that process queue.
*/
private final BukkitTask task;

/**
* Stores how long on average biome change took per each chunk.
*/
private final AtomicLong timer;

/**
* Stores how many chunks were updated.
*/
private final AtomicLong counter;
}
9 changes: 5 additions & 4 deletions src/main/resources/locales/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -781,11 +781,12 @@ biomes:
import-count: "&e Imported [biomes] biomes and [bundles] bundles."
# Message that appears after clicking on download button in web library.
start-downloading: "&e Start downloading library."
# This message is sent to use when biome changing is started.
update-start: "&a Starting biome changing to [biome] in [number] chunks."
# This message is sent to use when biome changing is finished.
# This message is sent to user when biome changing is started.
update-start: "&a Starting biome changing to [biome] in [number] chunks. &e Estimated time: [time] sec."
# This message is sent to user when biome changing is finished.
update-done: "&a Finished changing biome to [biome]."

# This message is sent to user when his change is placed in queue.
waiting: "&a Added biome change in queue. &e Estimated waiting time: [time] sec."
skipping: "&a Skipping loading &r [biome] &r&a."
overwriting: "&a Overwriting &r [biome] &r&a in cache."
imported: "&a Imported &r [biome] &r&a in cache."
Expand Down

0 comments on commit 29691b9

Please sign in to comment.