Archived
1
0
Fork 0

Add destroy method to World and change chunk loading functions

This commit is contained in:
Moritz Ruth 2020-12-29 22:57:11 +01:00
parent 1a69b3f3a1
commit 1dbf679659
No known key found for this signature in database
GPG key ID: AFD57E23E753841B
6 changed files with 35 additions and 24 deletions

View file

@ -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)
}

View file

@ -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()
}
}

View file

@ -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()
}
}

View file

@ -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)
}
}
}

View file

@ -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()
}
}

View file

@ -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)
)
}
}