Add destroy method to World and change chunk loading functions
This commit is contained in:
parent
1a69b3f3a1
commit
1dbf679659
6 changed files with 35 additions and 24 deletions
|
@ -12,5 +12,5 @@ import space.blokk.world.VoxelLocation
|
|||
*/
|
||||
class PlayerInitializationEvent(override val target: Session, val settings: Player.Settings) : SessionEvent(), Cancellable {
|
||||
override var cancelled = false
|
||||
var compassTarget: VoxelLocation = VoxelLocation(0, 0, 0)
|
||||
var compassTarget: VoxelLocation = VoxelLocation.of(0, 0, 0)
|
||||
}
|
||||
|
|
|
@ -79,28 +79,20 @@ abstract class Chunk(
|
|||
* Returns whether this chunk contains [voxel].
|
||||
*/
|
||||
// It does not just compare voxel.chunk with this because voxel.chunk may be expensive to create
|
||||
operator fun contains(voxel: Voxel) = contains(voxel.location)
|
||||
operator fun contains(voxel: Voxel) = voxel.world == world && contains(voxel.location)
|
||||
|
||||
abstract fun getData(player: Player?): ChunkData
|
||||
|
||||
abstract fun getLightData(player: Player?): ChunkLightData
|
||||
|
||||
/**
|
||||
* Loads this chunk into memory.
|
||||
* Starts loading this chunk into memory.
|
||||
*
|
||||
* If the chunk is already loaded, this function does nothing.
|
||||
* Does nothing if the chunk is already loaded or loading.
|
||||
*/
|
||||
open suspend fun load() {}
|
||||
open fun startLoading() {}
|
||||
open suspend fun waitUntilLoaded() {}
|
||||
|
||||
val loaded get() = loadState == LoadState.LOADED
|
||||
|
||||
open val loadState: LoadState = LoadState.LOADED
|
||||
|
||||
enum class LoadState {
|
||||
NOT_LOADED,
|
||||
LOADING,
|
||||
LOADED
|
||||
}
|
||||
open val loaded = true
|
||||
|
||||
companion object {
|
||||
const val LENGTH: Int = 16
|
||||
|
@ -108,4 +100,8 @@ abstract class Chunk(
|
|||
const val SECTION_HEIGHT: Int = 16
|
||||
const val BLOCKS_IN_A_SECTION = AREA * SECTION_HEIGHT
|
||||
}
|
||||
|
||||
interface Unloadable {
|
||||
suspend fun unload()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,10 @@ abstract class Voxel {
|
|||
val loaded: Boolean get() = chunk.loaded
|
||||
|
||||
/**
|
||||
* Shorthand for [`chunk.load()`][Chunk.load].
|
||||
* Loads [chunk] if it is not yet loaded.
|
||||
*/
|
||||
suspend fun load() = chunk.load()
|
||||
suspend fun loadAndWait() {
|
||||
chunk.startLoading()
|
||||
chunk.waitUntilLoaded()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,13 @@ data class VoxelLocation(val x: Int, val y: UByte, val z: Int) {
|
|||
CoordinatePart.Y -> y.toInt()
|
||||
CoordinatePart.Z -> z
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun of(x: Int, y: Int, z: Int): VoxelLocation {
|
||||
if (y !in 0..255) throw IllegalArgumentException("y must be in 0..255")
|
||||
return VoxelLocation(x, y.toUByte(), z)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -84,18 +84,23 @@ abstract class World(val uuid: UUID) {
|
|||
radius: Int,
|
||||
hollow: Boolean
|
||||
): List<Voxel> {
|
||||
// Implementation example https://git.io/JLysq
|
||||
// Implementation example: https://git.io/JLysq
|
||||
TODO()
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns an [entity][Entity] in this world.
|
||||
* Spawns [entity][Entity] in this world.
|
||||
*/
|
||||
abstract fun spawnEntity(entity: Entity)
|
||||
|
||||
fun unload() {
|
||||
suspend fun destroy() = withContext(coroutineContext) {
|
||||
// TODO: Move or kick players
|
||||
coroutineContext.cancel()
|
||||
// TODO: Unload chunks
|
||||
|
||||
coroutineScope {
|
||||
loadedChunks.values.forEach { launch { (it as? Chunk.Unloadable)?.unload() } }
|
||||
}
|
||||
|
||||
threadExecutor.close()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,16 +24,16 @@ class TestPlugin: Plugin("Test", "1.0.0") {
|
|||
Blokk.dimensionRegistry.register(dimension)
|
||||
|
||||
val world = AnvilWorld(dimension, true)
|
||||
world.getVoxelsInCube(VoxelLocation(16, 0, 16), VoxelLocation(-16, 0, -16)).forEach {
|
||||
world.getVoxelsInCube(VoxelLocation.of(16, 0, 16), VoxelLocation.of(-16, 0, -16)).forEach {
|
||||
it.block = if (it.location.x % 16 == 0 || it.location.z % 16 == 0) GreenWool() else RedWool()
|
||||
}
|
||||
|
||||
world.getVoxel(VoxelLocation(-1, 2, -1)).block = CraftingTable()
|
||||
world.getVoxel(VoxelLocation.of(-1, 2, -1)).block = CraftingTable()
|
||||
|
||||
Blokk.eventBus.on<SessionAfterLoginEvent> { event ->
|
||||
event.initialWorldAndLocation = WorldAndLocationWithRotation(
|
||||
world,
|
||||
VoxelLocation(0, 2, 0).atTopCenter().withRotation(0f, 0f)
|
||||
VoxelLocation.of(0, 2, 0).atTopCenter().withRotation(0f, 0f)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue