Add task states

Add states to differentiate between generating and validating tasks
as well as a field in the database to store this information.
A task will first generate a world until the required radius or the
worldborder is reached. Then it validates that each chunk has been generated.
pull/81/head
trivernis 4 years ago
parent b0a9deaa6d
commit 47650d4795

@ -19,7 +19,8 @@ class SqliteManager(private val chunkmaster: Chunkmaster) {
Pair("last_z", "integer NOT NULL DEFAULT 0"),
Pair("world", "text UNIQUE NOT NULL DEFAULT 'world'"),
Pair("radius", "integer DEFAULT -1"),
Pair("shape", "text NOT NULL DEFAULT 'square'")
Pair("shape", "text NOT NULL DEFAULT 'square'"),
Pair("state", "text NOT NULL DEFAULT 'GENERATING'")
)
),
Pair(

@ -359,7 +359,6 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
genTask.lastChunkCoords.x,
genTask.lastChunkCoords.z))
saveProgressToDatabase(genTask, task.id)
genTask.updateLastChunkMarker()
} catch (error: Exception) {
chunkmaster.logger.warning(chunkmaster.langManager.getLocalized("TASK_SAVE_FAILED", error.toString()))
}
@ -423,7 +422,8 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
start,
radius,
shape,
pendingChunks ?: emptyList()
pendingChunks ?: emptyList(),
TaskState.GENERATING
)
} else {
GenerationTaskSpigot(
@ -433,7 +433,8 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
start,
radius,
shape,
pendingChunks ?: emptyList()
pendingChunks ?: emptyList(),
TaskState.GENERATING
)
}
}

@ -14,7 +14,8 @@ abstract class GenerationTask(
protected val unloader: ChunkUnloader,
startChunk: ChunkCoordinates,
val shape: Shape,
protected val previousPendingChunks: List<ChunkCoordinates>
protected val previousPendingChunks: List<ChunkCoordinates>,
var state: TaskState
) :
Runnable {
@ -27,7 +28,6 @@ abstract class GenerationTask(
var lastChunkCoords = ChunkCoordinates(startChunk.x, startChunk.z)
protected set
protected val msptThreshold = plugin.config.getLong("generation.mspt-pause-threshold")
protected val chunksPerStep = plugin.config.getInt("generation.chunks-per-step")
protected var cancelRun: Boolean = false
private var endReachedCallback: ((GenerationTask) -> Unit)? = null
@ -42,14 +42,22 @@ abstract class GenerationTask(
private val markerAreaStyle = MarkerStyle(null, LineStyle(2, 1.0, 0x0022FF), FillStyle(.0, 0))
private val markerAreaId = "chunkmaster_genarea"
private val markerAreaName = "Chunkmaster Generation Area"
private val markerLastStyle = MarkerStyle(null, LineStyle(2, 1.0, 0x0077FF), FillStyle(.5, 0x0077FF))
private val markerLastId = "chunkmaster_lastchunk"
private val markerLastName = "Chunkmaster Last Chunk"
private val ignoreWorldborder = plugin.config.getBoolean("generation.ignore-worldborder")
abstract override fun run()
abstract fun generate()
abstract fun validate()
abstract fun cancel()
override fun run() {
isRunning = true
when (state) {
TaskState.GENERATING -> this.generate()
TaskState.VALIDATING -> this.validate()
else -> { }
}
isRunning = false
}
val nextChunkCoordinates: ChunkCoordinates
get() {
val nextChunkCoords = shape.next()
@ -59,7 +67,7 @@ abstract class GenerationTask(
/**
* Checks if the World border or the maximum chunk setting for the task is reached.
*/
protected fun borderReached(): Boolean {
private fun borderReached(): Boolean {
return (!world.worldBorder.isInside(lastChunkCoords.getCenterLocation(world)) && !ignoreWorldborder)
|| shape.endReached()
}
@ -80,24 +88,6 @@ abstract class GenerationTask(
}
}
/**
* Updates the dynmap marker for the generation radius
* FIXME
*/
fun updateLastChunkMarker(clear: Boolean = false) {
if (clear) {
markerSet?.deleteAreaMarker(markerLastId)
} else if (dynmapIntegration) {
markerSet?.creUpdateAreMarker(
markerLastId,
markerLastName,
this.lastChunkCoords.getCenterLocation(world).chunk.getBlock(0, 0, 0).location,
this.lastChunkCoords.getCenterLocation(world).chunk.getBlock(15, 0, 15).location,
markerLastStyle
)
}
}
/**
* Handles the invocation of the end reached callback and additional logic
*/
@ -106,7 +96,6 @@ abstract class GenerationTask(
count = shape.count
endReachedCallback?.invoke(this)
updateGenerationAreaMarker(true)
updateLastChunkMarker(true)
}
/**

@ -0,0 +1,7 @@
package net.trivernis.chunkmaster.lib.generation
enum class TaskState {
GENERATING,
VALIDATING,
PAUSING,
}

@ -4,6 +4,7 @@ import net.trivernis.chunkmaster.Chunkmaster
import net.trivernis.chunkmaster.lib.generation.ChunkCoordinates
import net.trivernis.chunkmaster.lib.generation.ChunkUnloader
import net.trivernis.chunkmaster.lib.generation.GenerationTask
import net.trivernis.chunkmaster.lib.generation.TaskState
import net.trivernis.chunkmaster.lib.shapes.Shape
import org.bukkit.World
import java.util.concurrent.*
@ -15,8 +16,9 @@ class GenerationTaskPaper(
startChunk: ChunkCoordinates,
override val radius: Int = -1,
shape: Shape,
previousPendingChunks: List<ChunkCoordinates>
) : GenerationTask(plugin, unloader, startChunk, shape, previousPendingChunks) {
previousPendingChunks: List<ChunkCoordinates>,
state: TaskState
) : GenerationTask(plugin, unloader, startChunk, shape, previousPendingChunks, state) {
private val maxPendingChunks = plugin.config.getInt("generation.max-pending-chunks")
val pendingChunks = ArrayBlockingQueue<PendingChunkEntry>(maxPendingChunks)
@ -34,28 +36,46 @@ class GenerationTaskPaper(
* they haven't been generated already
* After a configured number of chunks chunks have been generated, they will all be unloaded and saved.
*/
override fun run() {
override fun generate() {
try {
isRunning = true
for (pending in this.previousPendingChunks) {
this.requestGeneration(pending)
}
var chunkCoordinates: ChunkCoordinates
do {
chunkCoordinates = nextChunkCoordinates
} while (world.isChunkGenerated(chunkCoordinates.x, chunkCoordinates.z));
while (!cancelRun && !borderReachedCheck()) {
if (plugin.mspt < msptThreshold) {
chunkCoordinates = nextChunkCoordinates
this.requestGeneration(chunkCoordinates)
seekGenerated()
generateUntilBorder()
} catch (_: InterruptedException){}
}
/**
* Validates that all chunks have been generated or generates missing ones
*/
override fun validate() {
generateUntilBorder()
}
this.lastChunkCoords = chunkCoordinates
this.count = shape.count
}
/**
* Seeks until it encounters a chunk that hasn't been generated yet
*/
private fun seekGenerated() {
var chunkCoordinates: ChunkCoordinates
do {
chunkCoordinates = nextChunkCoordinates
} while (world.isChunkGenerated(chunkCoordinates.x, chunkCoordinates.z));
lastChunkCoords = chunkCoordinates
}
private fun generateUntilBorder() {
var chunkCoordinates = lastChunkCoords
while (!cancelRun && !borderReachedCheck()) {
if (plugin.mspt < msptThreshold) {
chunkCoordinates = nextChunkCoordinates
this.requestGeneration(chunkCoordinates)
this.lastChunkCoords = chunkCoordinates
this.count = shape.count
}
} catch (_: InterruptedException){}
isRunning = false
}
}
/**
@ -80,6 +100,5 @@ class GenerationTaskPaper(
this.cancelRun = true
this.pendingChunks.forEach { it.chunk.cancel(false) }
updateGenerationAreaMarker(true)
updateLastChunkMarker(true)
}
}

@ -4,6 +4,7 @@ import net.trivernis.chunkmaster.Chunkmaster
import net.trivernis.chunkmaster.lib.generation.ChunkCoordinates
import net.trivernis.chunkmaster.lib.generation.ChunkUnloader
import net.trivernis.chunkmaster.lib.generation.GenerationTask
import net.trivernis.chunkmaster.lib.generation.TaskState
import net.trivernis.chunkmaster.lib.shapes.Shape
import org.bukkit.World
@ -14,8 +15,9 @@ class GenerationTaskSpigot(
startChunk: ChunkCoordinates,
override val radius: Int = -1,
shape: Shape,
previousPendingChunks: List<ChunkCoordinates>
) : GenerationTask(plugin, unloader, startChunk, shape, previousPendingChunks) {
previousPendingChunks: List<ChunkCoordinates>,
state: TaskState
) : GenerationTask(plugin, unloader, startChunk, shape, previousPendingChunks, state) {
override var count = 0
@ -31,7 +33,7 @@ class GenerationTaskSpigot(
* they haven't been generated already
* After a configured number of chunks chunks have been generated, they will all be unloaded and saved.
*/
override fun run() {
override fun generate() {
isRunning = true
try {
for (pending in this.previousPendingChunks) {
@ -55,6 +57,10 @@ class GenerationTaskSpigot(
isRunning = false
}
override fun validate() {
TODO("Not yet implemented")
}
/**
* Cancels the generation task.
* This unloads all chunks that were generated but not unloaded yet.
@ -62,6 +68,5 @@ class GenerationTaskSpigot(
override fun cancel() {
cancelRun = true
updateGenerationAreaMarker(true)
updateLastChunkMarker(true)
}
}
Loading…
Cancel
Save