multithreaded tile renumbering

This commit is contained in:
minjaesong
2024-08-31 05:29:59 +09:00
parent 85c1e3ba96
commit 84f0353f09
3 changed files with 84 additions and 5 deletions

View File

@@ -240,7 +240,6 @@ class BTeXDocument : Disposable {
printPageNumber(pixmap, pageNum, 0, 0)
pagePixmaps[pageNum] = pixmap
progressIndicator.getAndAdd(1)
Unit
} } }
ThreadExecutor(THREAD_COUNT).also {

View File

@@ -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<Callable<Unit>>) {
@@ -52,17 +61,30 @@ class ThreadExecutor(
executor.invokeAll(ts)
}*/
fun submit1(t: Callable<Any?>) { // is JetBrain's fault, not mine
checkInit()
checkShutdown()
futures.add(executor.submit(t))
}
fun submitAll1(ts: List<Callable<Any?>>) { // is JetBrain's fault, not mine
checkInit()
checkShutdown()
ts.forEach { futures.add(executor.submit(it)) }
}
fun submit(t: Callable<Unit>) {
checkInit()
checkShutdown()
futures.add(executor.submit(t))
}
fun submitAll(ts: List<Callable<Unit>>) {
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...

View File

@@ -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!")
}