diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index 74756cc33..fdda74238 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -318,35 +318,6 @@ public class ClientApi - //============// - // clint tick // - //============// - - @Deprecated - public void clientTickEvent() - { - IProfilerWrapper profiler = MC_CLIENT.getProfiler(); - profiler.push("DH-ClientTick"); - - try - { - IDhClientWorld clientWorld = SharedApi.tryGetDhClientWorld(); - if (clientWorld != null) - { - clientWorld.clientTick(); - } - } - catch (Exception e) - { - // handle errors here to prevent blowing up a mixin or API up stream - LOGGER.error("Unexpected error in ClientApi.clientTickEvent(), error: "+e.getMessage(), e); - } - - profiler.pop(); - } - - - //============// // networking // //============// diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/EventLoop.java b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/EventLoop.java deleted file mode 100644 index 97054c975..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/EventLoop.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL v3 License. - * - * Copyright (C) 2020 James Seibel - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.seibel.distanthorizons.core.util.objects; - -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.coreapi.ModInfo; -import com.seibel.distanthorizons.core.logging.DhLogger; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.ExecutorService; - -public class EventLoop implements AutoCloseable -{ - private static final DhLogger LOGGER = new DhLoggerBuilder().build(); - - private final boolean PAUSE_ON_ERROR = ModInfo.IS_DEV_BUILD; - private final ExecutorService executorService; - - private final Runnable runnable; - /** the future related to the given runnable */ - private CompletableFuture runnableFuture; - - private boolean isRunning = true; - - - - public EventLoop(ExecutorService executorService, Runnable runnable) - { - this.executorService = executorService; - this.runnable = runnable; - } - - - - public void tick() - { - if (runnableFuture != null && runnableFuture.isDone()) - { - try - { - runnableFuture.join(); - } - catch (CompletionException ce) - { - LOGGER.error("Uncaught exception in event loop", ce.getCause()); - if (PAUSE_ON_ERROR) - { - isRunning = false; - } - } - catch (Exception e) - { - LOGGER.error("Exception in event loop", e); - if (PAUSE_ON_ERROR) - { - isRunning = false; - } - } - finally - { - runnableFuture = null; - } - } - - if (runnableFuture == null && isRunning) - { - runnableFuture = CompletableFuture.runAsync(runnable, executorService); - } - } - - public void close() - { - if (runnableFuture != null) - { - runnableFuture.cancel(true); - } - - runnableFuture = null; - executorService.shutdown(); - } - - public boolean isRunning() { return runnableFuture != null && !runnableFuture.isDone(); } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/world/DhClientServerWorld.java b/core/src/main/java/com/seibel/distanthorizons/core/world/DhClientServerWorld.java index fc9725406..af19c94f5 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/world/DhClientServerWorld.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/world/DhClientServerWorld.java @@ -21,27 +21,21 @@ package com.seibel.distanthorizons.core.world; import com.seibel.distanthorizons.core.api.internal.ClientApi; import com.seibel.distanthorizons.core.level.DhClientServerLevel; -import com.seibel.distanthorizons.core.util.ThreadUtil; -import com.seibel.distanthorizons.core.util.objects.EventLoop; +import com.seibel.distanthorizons.core.util.TimerUtil; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; +import java.util.*; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; public class DhClientServerWorld extends AbstractDhServerWorld implements IDhClientWorld { private final Set dhLevels = Collections.synchronizedSet(new HashSet<>()); - public ExecutorService dhTickerThread = ThreadUtil.makeSingleThreadPool("Client Server World Ticker", 2); - public EventLoop eventLoop = new EventLoop(this.dhTickerThread, this::_clientTick); //TODO: Rate-limit the loop + private final Timer clientTickTimer = TimerUtil.CreateTimer("ClientTickTimer"); @@ -53,6 +47,15 @@ public class DhClientServerWorld extends AbstractDhServerWorld(); LOGGER.info("Started DhWorld of type " + this.environment); + + this.clientTickTimer.scheduleAtFixedRate(new TimerTask() + { + @Override + public void run() + { + DhClientWorld.this.levels.values().forEach(DhClientLevel::clientTick); + } + }, 0, IDhClientWorld.TICK_RATE_IN_MS); } @@ -127,11 +135,6 @@ public class DhClientWorld extends AbstractDhWorld implements IDhClientWorld } } - private void _clientTick() { this.levels.values().forEach(DhClientLevel::clientTick); } - - @Override - public void clientTick() { this.eventLoop.tick(); } - @Override public void addDebugMenuStringsToList(List messageList) { @@ -143,7 +146,6 @@ public class DhClientWorld extends AbstractDhWorld implements IDhClientWorld public void close() { this.networkState.close(); - this.dhTickerThread.shutdownNow(); ArrayList> closeFutures = new ArrayList<>(); for (DhClientLevel dhClientLevel : this.levels.values()) @@ -175,7 +177,7 @@ public class DhClientWorld extends AbstractDhWorld implements IDhClientWorld } this.levels.clear(); - this.eventLoop.close(); + this.clientTickTimer.cancel(); LOGGER.info("Closed DhWorld of type [" + this.environment + "]."); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/world/IDhClientWorld.java b/core/src/main/java/com/seibel/distanthorizons/core/world/IDhClientWorld.java index cc20e2963..14e9b649e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/world/IDhClientWorld.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/world/IDhClientWorld.java @@ -24,7 +24,8 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; public interface IDhClientWorld extends IDhWorld { - void clientTick(); + /** how long in between client ticks in milliseconds */ + long TICK_RATE_IN_MS = 100L; default IDhClientLevel getOrLoadClientLevel(ILevelWrapper levelWrapper) { return (IDhClientLevel) this.getOrLoadLevel(levelWrapper); } default IDhClientLevel getClientLevel(ILevelWrapper levelWrapper) { return (IDhClientLevel) this.getLevel(levelWrapper); }