From d9f3b31cc56dc463283a68ab89139562f4c851e9 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Wed, 22 Apr 2026 18:48:21 -0500 Subject: [PATCH] Add timeout to CSV block culling configs --- .../AbstractDelayedConfigEventHandler.java | 84 +++++++++++++++++++ .../ReloadLodsConfigEventHandler.java | 55 +++--------- .../RenderBlockCacheCsvHandler.java | 14 +++- 3 files changed, 106 insertions(+), 47 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/AbstractDelayedConfigEventHandler.java diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/AbstractDelayedConfigEventHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/AbstractDelayedConfigEventHandler.java new file mode 100644 index 000000000..58a8c59ee --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/AbstractDelayedConfigEventHandler.java @@ -0,0 +1,84 @@ +package com.seibel.distanthorizons.core.config.eventHandlers; + +import com.seibel.distanthorizons.core.config.listeners.IConfigListener; +import com.seibel.distanthorizons.core.util.TimerUtil; + +import java.util.Timer; +import java.util.TimerTask; + +public abstract class AbstractDelayedConfigEventHandler implements IConfigListener +{ + public static final long DEFAULT_TIMEOUT_IN_MS = 2_000L; + + /** how long to wait in milliseconds before applying the config changes */ + private final long timeoutInMs; + private Timer timer; + + + + //=============// + // constructor // + //=============// + //region + + public AbstractDelayedConfigEventHandler(long timeoutInMs) { this.timeoutInMs = timeoutInMs; } + + //endregion + + + + //==================// + // abstract methods // + //==================// + //region + + public abstract void onConfigTimeout(); + + //endregion + + + + //========// + // events // + //========// + //region + + @Override + public void onConfigValueSet() + { + if (this.timeoutInMs > 0) + { + this.refreshRenderDataAfterTimeout(); + } + else + { + this.onConfigTimeout(); + } + } + + /** Calling this method multiple times will reset the timer */ + private synchronized void refreshRenderDataAfterTimeout() // synchronized to prevent potential threading issues when adding/removing the timer + { + // stop the previous timer if one exists + if (this.timer != null) + { + this.timer.cancel(); + } + + // create a new timer task + TimerTask timerTask = new TimerTask() + { + public void run() + { + AbstractDelayedConfigEventHandler.this.onConfigTimeout(); + } + }; + this.timer = TimerUtil.CreateTimer("AbstractDelayedConfigTimer"); + this.timer.schedule(timerTask, this.timeoutInMs); + } + + //endregion + + + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/ReloadLodsConfigEventHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/ReloadLodsConfigEventHandler.java index 66653c25a..52a404223 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/ReloadLodsConfigEventHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/ReloadLodsConfigEventHandler.java @@ -27,72 +27,36 @@ import com.seibel.distanthorizons.core.util.TimerUtil; import java.util.Timer; import java.util.TimerTask; -public class ReloadLodsConfigEventHandler implements IConfigListener +public class ReloadLodsConfigEventHandler extends AbstractDelayedConfigEventHandler { /** * should be used for user facing UI options * this allows the user a second to click through options before they're applied */ - public static ReloadLodsConfigEventHandler DELAYED_INSTANCE = new ReloadLodsConfigEventHandler(2_000L); + public static ReloadLodsConfigEventHandler DELAYED_INSTANCE = new ReloadLodsConfigEventHandler(AbstractDelayedConfigEventHandler.DEFAULT_TIMEOUT_IN_MS); /** should be used for debug options so their change can be seen instantly */ public static ReloadLodsConfigEventHandler INSTANT_INSTANCE = new ReloadLodsConfigEventHandler(0); - /** how long to wait in milliseconds before applying the config changes */ - private final long timeoutInMs; - private Timer cacheClearingTimer; - //=============// // constructor // //=============// + //region - public ReloadLodsConfigEventHandler(long timeoutInMs) - { - this.timeoutInMs = timeoutInMs; - } + public ReloadLodsConfigEventHandler(long timeoutInMs) { super(timeoutInMs); } + + //endregion //========// // events // //========// + //region @Override - public void onConfigValueSet() - { - if (this.timeoutInMs > 0) - { - this.refreshRenderDataAfterTimeout(); - } - else - { - clearRenderDataCache(); - } - } - - /** Calling this method multiple times will reset the timer */ - private synchronized void refreshRenderDataAfterTimeout() // synchronized to prevent potential threading issues when adding/removing the timer - { - // stop the previous timer if one exists - if (this.cacheClearingTimer != null) - { - this.cacheClearingTimer.cancel(); - } - - // create a new timer task - TimerTask timerTask = new TimerTask() - { - public void run() - { - clearRenderDataCache(); - } - }; - this.cacheClearingTimer = TimerUtil.CreateTimer("RenderCacheClearConfigTimer"); - this.cacheClearingTimer.schedule(timerTask, this.timeoutInMs); - } - - private static void clearRenderDataCache() + public void onConfigTimeout() { IDhApiRenderProxy renderProxy = DhApi.Delayed.renderProxy; if (renderProxy != null) @@ -101,5 +65,8 @@ public class ReloadLodsConfigEventHandler implements IConfigListener } } + //endregion + + } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/RenderBlockCacheCsvHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/RenderBlockCacheCsvHandler.java index 51a0940be..d2711dda1 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/RenderBlockCacheCsvHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/RenderBlockCacheCsvHandler.java @@ -32,7 +32,9 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; import com.seibel.distanthorizons.coreapi.util.StringUtil; -public class RenderBlockCacheCsvHandler implements IConfigListener +import java.util.Timer; + +public class RenderBlockCacheCsvHandler extends AbstractDelayedConfigEventHandler { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); @@ -43,18 +45,22 @@ public class RenderBlockCacheCsvHandler implements IConfigListener //=============// // constructor // //=============// + //region /** private since we only ever need one handler at a time */ - private RenderBlockCacheCsvHandler() { } + private RenderBlockCacheCsvHandler() { super(AbstractDelayedConfigEventHandler.DEFAULT_TIMEOUT_IN_MS); } + + //endregion //=================// // config handling // //=================// + //region @Override - public void onConfigValueSet() + public void onConfigTimeout() { IWrapperFactory wrapperFactory = SingletonInjector.INSTANCE.get(IWrapperFactory.class); if (wrapperFactory != null) @@ -64,6 +70,8 @@ public class RenderBlockCacheCsvHandler implements IConfigListener } } + //endregion + }