From 7e09ee1298052a31c5f05288d017ff837dc727c3 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Mon, 13 Dec 2021 20:57:10 +0100 Subject: [PATCH] fix eros account selection bug, fix world renderer crash, fixes #58 --- .../gui/eros/main/MainErosController.kt | 3 +- .../rendering/particle/ParticleRenderer.kt | 2 +- .../gui/rendering/world/WorldRenderer.kt | 53 +++++++++++++------ 3 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/gui/eros/main/MainErosController.kt b/src/main/java/de/bixilon/minosoft/gui/eros/main/MainErosController.kt index 4dd6ed1ed..48824e5c3 100644 --- a/src/main/java/de/bixilon/minosoft/gui/eros/main/MainErosController.kt +++ b/src/main/java/de/bixilon/minosoft/gui/eros/main/MainErosController.kt @@ -146,11 +146,12 @@ class MainErosController : JavaFXWindowController() { DefaultThreadPool += { try { account.verify(profile.clientToken) + onSuccess(account) } catch (exception: Throwable) { + exception.printStackTrace() Platform.runLater { activity = ErosMainActivities.ACCOUNT } // ToDo: Show account window and do account error handling } - onSuccess(account) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt index 7a6e16591..0846d4070 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt @@ -78,7 +78,7 @@ class ParticleRenderer( } private var maxAmount = RenderConstants.MAXIMUM_PARTICLE_AMOUNT set(value) { - check(value > 1) { "Can not have negative particle mac amount" } + check(value > 1) { "Can not have negative particle max amount" } particlesLock.lock() while (particles.size > value) { particles.removeAt(0) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt index cb7f5a494..802fc5137 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt @@ -69,6 +69,7 @@ import de.bixilon.minosoft.util.KUtil.unsafeCast import de.bixilon.minosoft.util.ReadWriteLock import de.bixilon.minosoft.util.chunk.ChunkUtil import de.bixilon.minosoft.util.chunk.ChunkUtil.isInViewDistance +import de.bixilon.minosoft.util.chunk.ChunkUtil.loaded import de.bixilon.minosoft.util.task.pool.DefaultThreadPool import de.bixilon.minosoft.util.task.pool.ThreadPool.Priorities.HIGH import de.bixilon.minosoft.util.task.pool.ThreadPool.Priorities.LOW @@ -99,6 +100,7 @@ class WorldRenderer( val maxPreparingTasks = maxOf(DefaultThreadPool.threadCount - 1, 1) private val preparingTasks: MutableSet = synchronizedSetOf() // current running section preparing tasks + private val preparingTasksLock = ReadWriteLock() private val queue: MutableList = synchronizedListOf() // queue, that is visible, and should be rendered private val queueLock = ReadWriteLock() @@ -296,11 +298,13 @@ class WorldRenderer( meshesToLoad.removeAll { !isChunkVisible(it.chunkPosition) } + preparingTasksLock.acquire() for (task in preparingTasks.toMutableSet()) { if (!isChunkVisible(task.chunkPosition)) { task.runnable.interrupt() } } + preparingTasksLock.release() loadedMeshesLock.unlock() queueLock.unlock() @@ -349,9 +353,11 @@ class WorldRenderer( clearVisibleNextFrame = true + preparingTasksLock.acquire() for (task in preparingTasks.toMutableSet()) { task.runnable.interrupt() } + preparingTasksLock.release() loadedMeshesLock.unlock() queueLock.unlock() @@ -373,11 +379,13 @@ class WorldRenderer( meshesToLoad.removeAll { it.chunkPosition == chunkPosition } + preparingTasksLock.acquire() for (task in preparingTasks.toMutableSet()) { if (task.chunkPosition == chunkPosition) { task.runnable.interrupt() } } + preparingTasksLock.release() if (meshes != null) { for (mesh in meshes.values) { meshesToUnload += mesh @@ -416,20 +424,20 @@ class WorldRenderer( for (item in items) { val task = SectionPrepareTask(item.chunkPosition, ThreadPoolRunnable(if (item.chunkPosition == cameraChunkPosition) HIGH else LOW)) // Our own chunk is the most important one ToDo: Also make neighbour chunks important task.runnable.runnable = Runnable { - - fun end() { - preparingTasks -= task - workQueue() - } - var locked = false try { - val chunk = item.chunk ?: world[item.chunkPosition] ?: return@Runnable end() - val section = chunk[item.sectionHeight] ?: return@Runnable end() + val chunk = item.chunk ?: world[item.chunkPosition] ?: return@Runnable + val section = chunk[item.sectionHeight] ?: return@Runnable if (section.blocks.isEmpty) { - return@Runnable end() + return@Runnable + } + val neighbourChunks: Array + world.getChunkNeighbours(item.chunkPosition).let { + if (!it.loaded) { + return@Runnable queueSection(item.chunkPosition, item.sectionHeight, chunk, section) + } + neighbourChunks = it.unsafeCast() } - val neighbourChunks: Array = world.getChunkNeighbours(item.chunkPosition).unsafeCast() val neighbours = item.neighbours ?: ChunkUtil.getDirectNeighbours(neighbourChunks, chunk, item.sectionHeight) val mesh = WorldMesh(renderWindow, item.chunkPosition, item.sectionHeight) solidSectionPreparer.prepareSolid(item.chunkPosition, item.sectionHeight, chunk, section, neighbours, neighbourChunks, mesh) @@ -437,7 +445,7 @@ class WorldRenderer( fluidSectionPreparer.prepareFluid(item.chunkPosition, item.sectionHeight, chunk, section, neighbours, neighbourChunks, mesh) } if (mesh.clearEmpty() == 0) { - return@Runnable end() + return@Runnable } item.mesh = mesh meshesToLoadLock.lock() @@ -454,16 +462,20 @@ class WorldRenderer( if (locked) { meshesToLoadLock.unlock() } - if (exception is InterruptedException) { - // task got interrupted (probably because of chunk unload) - preparingTasks -= task - return@Runnable + if (exception !is InterruptedException) { + // otherwise task got interrupted (probably because of chunk unload) + throw exception } - throw exception + } finally { + preparingTasksLock.lock() + preparingTasks -= task + preparingTasksLock.unlock() + workQueue() } - end() } + preparingTasksLock.lock() preparingTasks += task + preparingTasksLock.unlock() DefaultThreadPool += task.runnable } } @@ -472,6 +484,13 @@ class WorldRenderer( if (!chunk.isFullyLoaded || section.blocks.isEmpty) { // ToDo: Unload if empty return false } + /* + // ToDo: The chunk needs to be fully loaded! + val neighbours = world.getChunkNeighbours(chunkPosition) + if(!neighbours.loaded){ + return false + } + */ val visible = ignoreFrustum || isSectionVisible(chunkPosition, sectionHeight, section.blocks.minPosition, section.blocks.maxPosition, true) if (visible) {