better boom-job juggling

This commit is contained in:
minjaesong
2024-02-16 02:55:36 +09:00
parent 693ad05352
commit cac9e947f7
3 changed files with 49 additions and 13 deletions

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum.modulebasegame
import com.badlogic.gdx.utils.Queue
import net.torvald.terrarum.BlockCodex
import net.torvald.terrarum.ItemCodex
import net.torvald.terrarum.OreCodex
@@ -11,12 +12,23 @@ import net.torvald.terrarum.gameworld.fmod
import net.torvald.terrarum.gameworld.getOffset
import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore
import net.torvald.unsafe.UnsafeHelper
import java.util.concurrent.*
import kotlin.math.*
/**
* Created by minjaesong on 2024-02-13.
*/
object ExplosionManager {
private val executor = Executors.newSingleThreadExecutor()
private val futures = ArrayList<Future<*>>()
private val runners = ArrayList<CallableWithState>()
data class CallableWithState(
val runner: Callable<Unit>,
var executed: Boolean = false
)
fun goBoom(world: GameWorld, tx: Int, ty: Int, power: Float, dropProbNonOre: Float, dropProbOre: Float, callback: () -> Unit) {
val CALC_RADIUS = power.ceilToInt() + 2
val CALC_WIDTH = CALC_RADIUS * 2 + 1
@@ -31,7 +43,29 @@ object ExplosionManager {
memcpyFromWorldBreakage(CALC_WIDTH, world, tx - CALC_RADIUS, ty - CALC_RADIUS, line, breakmap)
}
createExplosionWorker(CALC_RADIUS, CALC_WIDTH, world, breakmap, tilemap, tx, ty, power, dropProbNonOre, dropProbOre, callback).start()
val runner = createExplosionWorker(CALC_RADIUS, CALC_WIDTH, world, breakmap, tilemap, tx, ty, power, dropProbNonOre, dropProbOre, callback)
// futures.add(executor.submit(runner))
runners.removeIf { it.executed }
runners.add(CallableWithState(runner))
}
init {
Thread {
while (true) {
try {
val job = runners.first { !it.executed }
val executor = Executors.newSingleThreadExecutor()
executor.submit(job.runner).get(500L, TimeUnit.MILLISECONDS)
executor.shutdownNow()
job.executed = true
}
catch (_: TimeoutException) { }
catch (_: NoSuchElementException) { }
Thread.sleep(50L)
}
}.start()
}
private fun memcpyFromWorldTiles(CALC_RADIUS: Int, CALC_WIDTH: Int, world: GameWorld, xStart: Int, yStart: Int, yOff: Int, out: BlockLayerI16) {
@@ -125,8 +159,8 @@ object ExplosionManager {
power: Float,
dropProbNonOre: Float,
dropProbOre: Float,
callback: () -> Unit): Thread
{ return Thread {
callback: () -> Unit): Callable<Unit>
{ return Callable {
val mapBoomPow = UnsafeFloatArray(CALC_WIDTH, CALC_WIDTH) // explosion power map
val mapTileStr = UnsafeFloatArray(CALC_WIDTH, CALC_WIDTH) // the tile strengths
val mapTileStr2 = UnsafeFloatArray(CALC_WIDTH, CALC_WIDTH) // the tile strengths

View File

@@ -876,8 +876,9 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
repossessActor()
// process actor addition requests
actorAdditionQueue.forEach { forceAddActor(it.first, it.second) }
actorAdditionQueue.clear()
val addCueCpy = actorAdditionQueue.toList()
addCueCpy.forEach { forceAddActor(it.first, it.second) }
actorAdditionQueue.removeAll(addCueCpy)
// determine whether the inactive actor should be activated
wakeDormantActors()
// update NOW; allow one last update for the actors flagged to despawn
@@ -885,10 +886,11 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
// determine whether the actor should keep being activated or be dormant
killOrKnockdownActors()
// process actor removal requests
actorRemovalQueue.forEach { forceRemoveActor(it.first, it.second) }
actorRemovalQueue.clear()
val remCueCpy = actorRemovalQueue.toList()
remCueCpy.forEach { forceRemoveActor(it.first, it.second) }
actorRemovalQueue.removeAll(remCueCpy)
// update particles
particlesContainer.forEach { if (!it.flagDespawn) particlesActive++; it.update(delta) }
particlesContainer.toList().forEach { if (!it.flagDespawn) particlesActive++; it.update(delta) }
// TODO thread pool(?)
CollisionSolver.process()

View File

@@ -46,10 +46,6 @@ open class ActorPrimedBomb(
if (fuse <= 0f && !explosionCalled) {
explosionCalled = true
physProp.usePhysics = false
this.isVisible = false // or play explosion anim
startAudio(boomSound, 10.0)
ExplosionManager.goBoom(
INGAME.world,
@@ -58,7 +54,11 @@ open class ActorPrimedBomb(
explosionPower,
dropProbNonOre,
dropProbOre
) {}
) {
physProp.usePhysics = false
this.isVisible = false // or play explosion anim
startAudio(boomSound, 10.0)
}
}
}