diff --git a/src/net/torvald/btex/BTeXDocument.kt b/src/net/torvald/btex/BTeXDocument.kt index 1caa7a0ca..d7c21f1b4 100644 --- a/src/net/torvald/btex/BTeXDocument.kt +++ b/src/net/torvald/btex/BTeXDocument.kt @@ -240,7 +240,6 @@ class BTeXDocument : Disposable { printPageNumber(pixmap, pageNum, 0, 0) pagePixmaps[pageNum] = pixmap progressIndicator.getAndAdd(1) - Unit } } } ThreadExecutor(THREAD_COUNT).also { diff --git a/src/net/torvald/terrarum/concurrent/ThreadExecutor.kt b/src/net/torvald/terrarum/concurrent/ThreadExecutor.kt index 8b2d1da76..a960103de 100644 --- a/src/net/torvald/terrarum/concurrent/ThreadExecutor.kt +++ b/src/net/torvald/terrarum/concurrent/ThreadExecutor.kt @@ -21,6 +21,8 @@ class ThreadExecutor( var allFinished = true private set + private var init = false + init { App.disposables.add(Disposable { this.killAll() }) } @@ -35,6 +37,12 @@ class ThreadExecutor( catch (e: UninitializedPropertyAccessException) {} } + private fun checkInit() { + if (!init) { + throw IllegalStateException("ThreadExecuter not initialised; run renew() first!") + } + } + fun renew() { try { if (!executor.isTerminated && !executor.isShutdown) throw IllegalStateException("Pool is still running") @@ -45,6 +53,7 @@ class ThreadExecutor( futures.clear() isOpen = true allFinished = false + init = true } /*fun invokeAll(ts: List>) { @@ -52,17 +61,30 @@ class ThreadExecutor( executor.invokeAll(ts) }*/ + fun submit1(t: Callable) { // is JetBrain's fault, not mine + checkInit() + checkShutdown() + futures.add(executor.submit(t)) + } + fun submitAll1(ts: List>) { // is JetBrain's fault, not mine + checkInit() + checkShutdown() + ts.forEach { futures.add(executor.submit(it)) } + } fun submit(t: Callable) { + checkInit() checkShutdown() futures.add(executor.submit(t)) } fun submitAll(ts: List>) { + checkInit() checkShutdown() ts.forEach { futures.add(executor.submit(it)) } } // https://stackoverflow.com/questions/28818494/threads-stopping-prematurely-for-certain-values fun join() { + checkInit() //println("ThreadExecutor.join") isOpen = false futures.forEach { @@ -70,7 +92,8 @@ class ThreadExecutor( it.get() } catch (e: ExecutionException) { - throw e + e.cause!!.printStackTrace() + throw e.cause!! } } executor.shutdown() // thread status of completed ones will be WAIT instead of TERMINATED without this line... diff --git a/src/net/torvald/terrarum/gameworld/GameWorld.kt b/src/net/torvald/terrarum/gameworld/GameWorld.kt index 1b44f2161..863c19987 100644 --- a/src/net/torvald/terrarum/gameworld/GameWorld.kt +++ b/src/net/torvald/terrarum/gameworld/GameWorld.kt @@ -7,6 +7,7 @@ import net.torvald.terrarum.* import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.blockproperties.Fluid +import net.torvald.terrarum.concurrent.ThreadExecutor import net.torvald.terrarum.gameactors.ActorID import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameitems.isFluid @@ -23,6 +24,7 @@ import net.torvald.terrarum.worlddrawer.BlocksDrawer import net.torvald.util.SortedArrayList import org.dyn4j.geometry.Vector2 import java.util.* +import java.util.concurrent.Executors.callable typealias BlockAddress = Long @@ -301,8 +303,11 @@ open class GameWorld( // fluidNumberToNameMap[65535] = Fluid.NULL // fluidNameToNumberMap[Fluid.NULL] = 0 + + BlocksDrawer.rebuildInternalPrecalculations() + // perform renaming of tile layers - for (y in 0 until layerTerrain.height) { + /*for (y in 0 until layerTerrain.height) { for (x in 0 until layerTerrain.width) { // renumber terrain and wall layerTerrain.unsafeSetTile(x, y, tileNameToNumberMap[oldTileNumberToNameMap[layerTerrain.unsafeGetTile(x, y).toLong()]]!!) @@ -318,9 +323,61 @@ open class GameWorld( val oldFluidName = oldTileNumberToNameMap[oldFluidNum.toLong()] layerFluids.unsafeSetTile(x, y, oldFluidName.let { tileNameToNumberMap[it] ?: throw NullPointerException("Unknown tile name: $oldFluidName (<- $oldFluidNum)") }, oldFluidFill) } - } + }*/ + // will use as much threads you have on the system + printdbg(this, "starting renumbering thread") + try { + val te = ThreadExecutor() + te.renew() + te.submitAll1( + (0 until layerTerrain.width step CHUNK_W).map { xorigin -> + callable { + for (y in 0 until layerTerrain.height) { + for (x in xorigin until (xorigin + CHUNK_W).coerceAtMost(layerTerrain.width)) { + // renumber terrain and wall + layerTerrain.unsafeSetTile( + x, y, + tileNameToNumberMap[oldTileNumberToNameMap[layerTerrain.unsafeGetTile(x, y) + .toLong()]]!! + ) + layerWall.unsafeSetTile( + x, y, + tileNameToNumberMap[oldTileNumberToNameMap[layerWall.unsafeGetTile(x, y) + .toLong()]]!! + ) - BlocksDrawer.rebuildInternalPrecalculations() + // renumber ores + val oldOreNum = layerOres.unsafeGetTile(x, y).toLong() + val oldOreName = oldTileNumberToNameMap[oldOreNum] + layerOres.unsafeSetTileKeepPlacement(x, y, + oldOreName.let { + tileNameToNumberMap[it] + ?: throw NullPointerException("Unknown tile name: $oldOreName (<- $oldOreNum)") + }) + + // renumber fluids + val (oldFluidNum, oldFluidFill) = layerFluids.unsafeGetTile1(x, y) + val oldFluidName = oldTileNumberToNameMap[oldFluidNum.toLong()] + layerFluids.unsafeSetTile( + x, y, + oldFluidName.let { + tileNameToNumberMap[it] + ?: throw NullPointerException("Unknown tile name: $oldFluidName (<- $oldFluidNum)") + }, + oldFluidFill + ) + } + } + } + } + ) + te.join() + } + catch (e: Throwable) { + e.printStackTrace() + throw e + } + printdbg(this, "renumbering thread finished") printdbg(this, "renumberTilesAfterLoad done!") }