mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-12 11:34:05 +09:00
wip fixing multithreaded noisy image bug
decided to remove my own thread pool impl to reduce the scope of attack
This commit is contained in:
@@ -1,14 +1,32 @@
|
|||||||
package net.torvald.terrarum.concurrent
|
package net.torvald.terrarum.concurrent
|
||||||
|
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
|
|
||||||
typealias RunnableFun = () -> Unit
|
typealias RunnableFun = () -> Unit
|
||||||
/** Int: index of the processing core */
|
/** Int: index of the processing core */
|
||||||
typealias ThreadableFun = (Int) -> Unit
|
typealias ThreadableFun = (Int) -> Unit
|
||||||
|
|
||||||
|
|
||||||
|
object ThreadExecutor {
|
||||||
|
val threadCount = Runtime.getRuntime().availableProcessors() // not using (logicalCores + 1) method; it's often better idea to reserve one extra thread for other jobs in the app
|
||||||
|
private val executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())
|
||||||
|
|
||||||
|
fun submit(t: Runnable) = executor.submit(t)
|
||||||
|
fun submit(f: RunnableFun) = executor.submit { f() }
|
||||||
|
|
||||||
|
fun join() {
|
||||||
|
executor.awaitTermination(24L, TimeUnit.HOURS)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-05-25.
|
* Created by minjaesong on 2016-05-25.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Hooey implementation", ReplaceWith("ThreadExecutor", "net.torvald.terrarum.concurrent.ThreadExecutor"))
|
||||||
object ThreadParallel {
|
object ThreadParallel {
|
||||||
val threadCount = Runtime.getRuntime().availableProcessors() // not using (logicalCores + 1) method; it's often better idea to reserve one extra thread for other jobs in the app
|
val threadCount = Runtime.getRuntime().availableProcessors() // not using (logicalCores + 1) method; it's often better idea to reserve one extra thread for other jobs in the app
|
||||||
|
|
||||||
|
|||||||
@@ -15,13 +15,13 @@ import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
|||||||
import com.sudoplay.joise.Joise
|
import com.sudoplay.joise.Joise
|
||||||
import com.sudoplay.joise.module.*
|
import com.sudoplay.joise.module.*
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
import net.torvald.terrarum.concurrent.ThreadParallel
|
import net.torvald.terrarum.concurrent.*
|
||||||
import net.torvald.terrarum.concurrent.mapToThreadPoolDirectly
|
|
||||||
import net.torvald.terrarum.gameworld.fmod
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
import net.torvald.terrarum.inUse
|
import net.torvald.terrarum.inUse
|
||||||
import net.torvald.terrarum.modulebasegame.worldgenerator.BiomegenParams
|
import net.torvald.terrarum.modulebasegame.worldgenerator.BiomegenParams
|
||||||
import net.torvald.terrarum.modulebasegame.worldgenerator.TerragenParams
|
import net.torvald.terrarum.modulebasegame.worldgenerator.TerragenParams
|
||||||
import net.torvald.terrarum.modulebasegame.worldgenerator.shake
|
import net.torvald.terrarum.modulebasegame.worldgenerator.shake
|
||||||
|
import java.util.concurrent.Future
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
|
|
||||||
@@ -93,12 +93,12 @@ class WorldgenNoiseSandbox : ApplicationAdapter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if generation is done
|
// check if generation is done
|
||||||
if (ThreadParallel.allFinished()) {
|
if (threadExecFinished) {
|
||||||
generateKeyLatched = false
|
generateKeyLatched = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// finish time measurement
|
// finish time measurement
|
||||||
if (ThreadParallel.allFinished() && generationTimeInMeasure) {
|
if (threadExecFinished && generationTimeInMeasure) {
|
||||||
generationTimeInMeasure = false
|
generationTimeInMeasure = false
|
||||||
val time = System.nanoTime() - generationStartTime
|
val time = System.nanoTime() - generationStartTime
|
||||||
generationTime = time / 1000000000f
|
generationTime = time / 1000000000f
|
||||||
@@ -123,6 +123,12 @@ class WorldgenNoiseSandbox : ApplicationAdapter() {
|
|||||||
|
|
||||||
val colourNull = Color(0x1b3281ff)
|
val colourNull = Color(0x1b3281ff)
|
||||||
|
|
||||||
|
private val sampleOffset = WIDTH / 8.0
|
||||||
|
|
||||||
|
private val threadExecFuture = Array<Future<*>?>(ThreadExecutor.threadCount) { null }
|
||||||
|
private val threadExecFinished: Boolean
|
||||||
|
get() = threadExecFuture.fold(true) { acc, future -> acc && (future?.isDone ?: true) }
|
||||||
|
|
||||||
private fun renderNoise() {
|
private fun renderNoise() {
|
||||||
generationStartTime = System.nanoTime()
|
generationStartTime = System.nanoTime()
|
||||||
generationTimeInMeasure = true
|
generationTimeInMeasure = true
|
||||||
@@ -132,22 +138,26 @@ class WorldgenNoiseSandbox : ApplicationAdapter() {
|
|||||||
testTex.fill()
|
testTex.fill()
|
||||||
|
|
||||||
// render noisemap to pixmap
|
// render noisemap to pixmap
|
||||||
(0 until WIDTH).mapToThreadPoolDirectly("NoiseGen") { range ->
|
val runnables: List<RunnableFun> = (0 until WIDTH).sliceEvenly(ThreadExecutor.threadCount).map { range ->
|
||||||
for (y in 0 until HEIGHT) {
|
{
|
||||||
for (x in range) {
|
for (y in 0 until HEIGHT) {
|
||||||
val sampleTheta = (x.toDouble() / WIDTH) * TWO_PI
|
for (x in range) {
|
||||||
val sampleOffset = WIDTH / 8.0
|
val sampleTheta = (x.toDouble() / WIDTH) * TWO_PI
|
||||||
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) }
|
|
||||||
|
|
||||||
NOISE_MAKER.draw(x, y, noise, testTex)
|
//synchronized(testTex) {
|
||||||
|
NOISE_MAKER.draw(x, y, joise.map { it.get(sampleX, sampleY, sampleZ) }, testTex)
|
||||||
|
//}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadParallel.startAll()
|
runnables.forEachIndexed { index, function ->
|
||||||
|
threadExecFuture[index] = ThreadExecutor.submit(function)
|
||||||
|
}
|
||||||
|
|
||||||
generationDone = true
|
generationDone = true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user