mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
better boom-job juggling
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user