From 488b598d97deac5e043c44e23f03da8e3706d98d Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 28 Oct 2023 12:18:55 -0500 Subject: [PATCH] Close #447 Add the ability to limit LOD chunk update rate --- .../core/api/internal/SharedApi.java | 28 +++++++++++++------ .../distanthorizons/core/config/Config.java | 16 +++++++++++ .../assets/distanthorizons/lang/en_us.json | 11 +++++++- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java index 22872a2a6..ce4a231ca 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java @@ -43,6 +43,8 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ThreadPoolExecutor; @@ -62,6 +64,8 @@ public class SharedApi private static ThreadPoolExecutor lightPopulatorThreadPool; private static ConfigChangeListener threadConfigListener; + private static final Timer CHUNK_UPDATE_TIMER = new Timer(); + //=============// @@ -236,13 +240,6 @@ public class SharedApi } private static void bakeChunkLightingAndSendToLevelAsync(IChunkWrapper chunkWrapper, @Nullable ArrayList neighbourChunkList, IDhLevel dhLevel) { - if (UPDATING_CHUNK_SET.size() > lightPopulatorThreadPool.getPoolSize() * 100) - { - // limit how many tasks can be queued at a time - // attempt to limit memory leaking - return; - } - // prevent duplicate update requests if (UPDATING_CHUNK_SET.contains(chunkWrapper.getChunkPos())) { @@ -299,7 +296,22 @@ public class SharedApi } finally { - UPDATING_CHUNK_SET.remove(chunkWrapper.getChunkPos()); + // the LOD chunk has finished being updated + int updateTimeoutInSec = Config.Client.Advanced.LodBuilding.minTimeBetweenChunkUpdatesInSeconds.get(); + if (updateTimeoutInSec != 0) + { + // prevent updating this chunk again until the timeout finishes + CHUNK_UPDATE_TIMER.schedule(new TimerTask() + { + @Override + public void run() { UPDATING_CHUNK_SET.remove(chunkWrapper.getChunkPos()); } + }, updateTimeoutInSec * 1000L); + } + else + { + // instantly allow this chunk to be updated again + UPDATING_CHUNK_SET.remove(chunkWrapper.getChunkPos()); + } } }); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java index 72b2c6e3c..ef96111a9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java @@ -117,6 +117,7 @@ public class Config public static ConfigCategory graphics = new ConfigCategory.Builder().set(Graphics.class).build(); public static ConfigCategory worldGenerator = new ConfigCategory.Builder().set(WorldGenerator.class).build(); public static ConfigCategory multiplayer = new ConfigCategory.Builder().set(Multiplayer.class).build(); + public static ConfigCategory lodBuilding = new ConfigCategory.Builder().set(LodBuilding.class).build(); public static ConfigCategory multiThreading = new ConfigCategory.Builder().set(MultiThreading.class).build(); public static ConfigCategory buffers = new ConfigCategory.Builder().set(GpuBuffers.class).build(); public static ConfigCategory autoUpdater = new ConfigCategory.Builder().set(AutoUpdater.class).build(); @@ -750,6 +751,21 @@ public class Config } + public static class LodBuilding + { + public static ConfigEntry minTimeBetweenChunkUpdatesInSeconds = new ConfigEntry.Builder() + .setMinDefaultMax(0, 1, 60) + .comment("" + + "Determines how long must pass between LOD chunk updates before another. \n" + + "update can occur\n" + + "\n" + + "Increasing this value will reduce CPU load but may may cause \n" + + "LODs to become outdated more frequently or for longer. \n" + + "") + .build(); + + } + public static class Multiplayer { public static ConfigEntry serverFolderNameMode = new ConfigEntry.Builder() diff --git a/core/src/main/resources/assets/distanthorizons/lang/en_us.json b/core/src/main/resources/assets/distanthorizons/lang/en_us.json index 9dda658c3..f5ad40972 100644 --- a/core/src/main/resources/assets/distanthorizons/lang/en_us.json +++ b/core/src/main/resources/assets/distanthorizons/lang/en_us.json @@ -326,8 +326,17 @@ "Generation Priority", "distanthorizons.config.client.advanced.worldGenerator.generationPriority.@tooltip": "The priority for chunks being generated around the player.", + + + "distanthorizons.config.client.advanced.lodBuilding": + "Lod Building", + + "distanthorizons.config.client.advanced.lodBuilding.minTimeBetweenChunkUpdatesInSeconds": + "Minimum Time Between Chunk Updates In Seconds", + "distanthorizons.config.client.advanced.lodBuilding.minTimeBetweenChunkUpdatesInSeconds.@tooltip": + "Determines how long must pass between LOD chunk updates before another. \nupdate can occur\n\nIncreasing this value will reduce CPU load but may may cause \nLODs to become outdated more frequently or for longer.", - + "distanthorizons.config.client.advanced.multiplayer": "Multiplayer",