mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
multithreaded tile renumbering
This commit is contained in:
@@ -240,7 +240,6 @@ class BTeXDocument : Disposable {
|
|||||||
printPageNumber(pixmap, pageNum, 0, 0)
|
printPageNumber(pixmap, pageNum, 0, 0)
|
||||||
pagePixmaps[pageNum] = pixmap
|
pagePixmaps[pageNum] = pixmap
|
||||||
progressIndicator.getAndAdd(1)
|
progressIndicator.getAndAdd(1)
|
||||||
Unit
|
|
||||||
} } }
|
} } }
|
||||||
|
|
||||||
ThreadExecutor(THREAD_COUNT).also {
|
ThreadExecutor(THREAD_COUNT).also {
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ class ThreadExecutor(
|
|||||||
var allFinished = true
|
var allFinished = true
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
private var init = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
App.disposables.add(Disposable { this.killAll() })
|
App.disposables.add(Disposable { this.killAll() })
|
||||||
}
|
}
|
||||||
@@ -35,6 +37,12 @@ class ThreadExecutor(
|
|||||||
catch (e: UninitializedPropertyAccessException) {}
|
catch (e: UninitializedPropertyAccessException) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkInit() {
|
||||||
|
if (!init) {
|
||||||
|
throw IllegalStateException("ThreadExecuter not initialised; run renew() first!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun renew() {
|
fun renew() {
|
||||||
try {
|
try {
|
||||||
if (!executor.isTerminated && !executor.isShutdown) throw IllegalStateException("Pool is still running")
|
if (!executor.isTerminated && !executor.isShutdown) throw IllegalStateException("Pool is still running")
|
||||||
@@ -45,6 +53,7 @@ class ThreadExecutor(
|
|||||||
futures.clear()
|
futures.clear()
|
||||||
isOpen = true
|
isOpen = true
|
||||||
allFinished = false
|
allFinished = false
|
||||||
|
init = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/*fun invokeAll(ts: List<Callable<Unit>>) {
|
/*fun invokeAll(ts: List<Callable<Unit>>) {
|
||||||
@@ -52,17 +61,30 @@ class ThreadExecutor(
|
|||||||
executor.invokeAll(ts)
|
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>) {
|
fun submit(t: Callable<Unit>) {
|
||||||
|
checkInit()
|
||||||
checkShutdown()
|
checkShutdown()
|
||||||
futures.add(executor.submit(t))
|
futures.add(executor.submit(t))
|
||||||
}
|
}
|
||||||
fun submitAll(ts: List<Callable<Unit>>) {
|
fun submitAll(ts: List<Callable<Unit>>) {
|
||||||
|
checkInit()
|
||||||
checkShutdown()
|
checkShutdown()
|
||||||
ts.forEach { futures.add(executor.submit(it)) }
|
ts.forEach { futures.add(executor.submit(it)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/28818494/threads-stopping-prematurely-for-certain-values
|
// https://stackoverflow.com/questions/28818494/threads-stopping-prematurely-for-certain-values
|
||||||
fun join() {
|
fun join() {
|
||||||
|
checkInit()
|
||||||
//println("ThreadExecutor.join")
|
//println("ThreadExecutor.join")
|
||||||
isOpen = false
|
isOpen = false
|
||||||
futures.forEach {
|
futures.forEach {
|
||||||
@@ -70,7 +92,8 @@ class ThreadExecutor(
|
|||||||
it.get()
|
it.get()
|
||||||
}
|
}
|
||||||
catch (e: ExecutionException) {
|
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...
|
executor.shutdown() // thread status of completed ones will be WAIT instead of TERMINATED without this line...
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import net.torvald.terrarum.*
|
|||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
import net.torvald.terrarum.blockproperties.Fluid
|
import net.torvald.terrarum.blockproperties.Fluid
|
||||||
|
import net.torvald.terrarum.concurrent.ThreadExecutor
|
||||||
import net.torvald.terrarum.gameactors.ActorID
|
import net.torvald.terrarum.gameactors.ActorID
|
||||||
import net.torvald.terrarum.gameitems.ItemID
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
import net.torvald.terrarum.gameitems.isFluid
|
import net.torvald.terrarum.gameitems.isFluid
|
||||||
@@ -23,6 +24,7 @@ import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
|||||||
import net.torvald.util.SortedArrayList
|
import net.torvald.util.SortedArrayList
|
||||||
import org.dyn4j.geometry.Vector2
|
import org.dyn4j.geometry.Vector2
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import java.util.concurrent.Executors.callable
|
||||||
|
|
||||||
typealias BlockAddress = Long
|
typealias BlockAddress = Long
|
||||||
|
|
||||||
@@ -301,8 +303,11 @@ open class GameWorld(
|
|||||||
// fluidNumberToNameMap[65535] = Fluid.NULL
|
// fluidNumberToNameMap[65535] = Fluid.NULL
|
||||||
// fluidNameToNumberMap[Fluid.NULL] = 0
|
// fluidNameToNumberMap[Fluid.NULL] = 0
|
||||||
|
|
||||||
|
|
||||||
|
BlocksDrawer.rebuildInternalPrecalculations()
|
||||||
|
|
||||||
// perform renaming of tile layers
|
// 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) {
|
for (x in 0 until layerTerrain.width) {
|
||||||
// renumber terrain and wall
|
// renumber terrain and wall
|
||||||
layerTerrain.unsafeSetTile(x, y, tileNameToNumberMap[oldTileNumberToNameMap[layerTerrain.unsafeGetTile(x, y).toLong()]]!!)
|
layerTerrain.unsafeSetTile(x, y, tileNameToNumberMap[oldTileNumberToNameMap[layerTerrain.unsafeGetTile(x, y).toLong()]]!!)
|
||||||
@@ -318,9 +323,61 @@ open class GameWorld(
|
|||||||
val oldFluidName = oldTileNumberToNameMap[oldFluidNum.toLong()]
|
val oldFluidName = oldTileNumberToNameMap[oldFluidNum.toLong()]
|
||||||
layerFluids.unsafeSetTile(x, y, oldFluidName.let { tileNameToNumberMap[it] ?: throw NullPointerException("Unknown tile name: $oldFluidName (<- $oldFluidNum)") }, oldFluidFill)
|
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!")
|
printdbg(this, "renumberTilesAfterLoad done!")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user