hypothetical multithreading on terragen

This commit is contained in:
minjaesong
2019-11-27 16:59:24 +09:00
parent 98993f1755
commit cfda47405d
2 changed files with 22 additions and 17 deletions

View File

@@ -29,7 +29,7 @@ class WorldgenLoadScreen(screenToBeLoaded: IngameInstance, private val worldwidt
companion object { companion object {
private const val WIDTH_RATIO = 0.7 private const val WIDTH_RATIO = 0.7
private const val PREVIEW_UPDATE_RATE = 1 / 8f private const val PREVIEW_UPDATE_RATE = 1 / 5f
private val COL_WALL = Color.WHITE private val COL_WALL = Color.WHITE
private val COL_TERR = Color(.5f, .5f, .5f, 1f) private val COL_TERR = Color(.5f, .5f, .5f, 1f)

View File

@@ -6,7 +6,9 @@ import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.AppLoader.printdbg import net.torvald.terrarum.AppLoader.printdbg
import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.concurrent.ThreadExecutor import net.torvald.terrarum.concurrent.ThreadExecutor
import net.torvald.terrarum.concurrent.sliceEvenly
import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.toInt
import java.util.concurrent.Future import java.util.concurrent.Future
import kotlin.math.cos import kotlin.math.cos
import kotlin.math.sin import kotlin.math.sin
@@ -16,10 +18,10 @@ import kotlin.math.sin
*/ */
class Terragen(world: GameWorld, seed: Long, params: Any) : Gen(world, seed, params) { class Terragen(world: GameWorld, seed: Long, params: Any) : Gen(world, seed, params) {
private var genFuture: Future<*>? = null private var genFutures: Array<Future<*>?> = arrayOfNulls(ThreadExecutor.threadCount)
override var generationStarted: Boolean = false override var generationStarted: Boolean = false
override val generationDone: Boolean override val generationDone: Boolean
get() = generationStarted && genFuture?.isDone ?: false get() = generationStarted && genFutures.fold(1) { acc, f -> acc * (f?.isDone ?: true).toInt() } == 1
override fun run() { override fun run() {
val joise = getGenerator(seed, params as TerragenParams) val joise = getGenerator(seed, params as TerragenParams)
@@ -27,23 +29,26 @@ class Terragen(world: GameWorld, seed: Long, params: Any) : Gen(world, seed, par
generationStarted = true generationStarted = true
// single-threaded impl because I couldn't resolve multithread memory corruption issue... // single-threaded impl because I couldn't resolve multithread memory corruption issue...
genFuture = ThreadExecutor.submit { val slices = 1 // ThreadExecutor.threadCount
for (x in 0 until world.width) { (0 until world.width).sliceEvenly(slices).mapIndexed { i, xs ->
genFutures[i] = ThreadExecutor.submit {
for (x in xs) {
if (AppLoader.IS_DEVELOPMENT_BUILD) { if (AppLoader.IS_DEVELOPMENT_BUILD) {
AppLoader.getLoadScreen().addMessage("Tile draw for x=$x") AppLoader.getLoadScreen().addMessage("Tile draw for x=$x")
//println("Tile draw for x=$x") //println("Tile draw for x=$x")
} }
for (y in 0 until world.height) { for (y in 0 until world.height) {
val sampleTheta = (x.toDouble() / world.width) * TWO_PI val sampleTheta = (x.toDouble() / world.width) * TWO_PI
val sampleOffset = world.width / 8.0 val sampleOffset = world.width / 8.0
val sampleX = sin(sampleTheta) * sampleOffset + sampleOffset // plus sampleOffset to make only val sampleX = sin(sampleTheta) * sampleOffset + sampleOffset // plus sampleOffset to make only
val sampleZ = cos(sampleTheta) * sampleOffset + sampleOffset // positive points are to be sampled val sampleZ = cos(sampleTheta) * sampleOffset + sampleOffset // positive points are to be sampled
val sampleY = y.toDouble() val sampleY = y.toDouble()
val noise = joise.map { it.get(sampleX, sampleY, sampleZ) } val noise = joise.map { it.get(sampleX, sampleY, sampleZ) }
draw(x, y, noise, world) draw(x, y, noise, world)
}
} }
} }
} }