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 { class PlayerInitializationEvent(override val target: Session, val settings: Player.Settings) : SessionEvent(), Cancellable {
override var cancelled = false 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]. * Returns whether this chunk contains [voxel].
*/ */
// It does not just compare voxel.chunk with this because voxel.chunk may be expensive to create // 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 getData(player: Player?): ChunkData
abstract fun getLightData(player: Player?): ChunkLightData 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 loaded = true
open val loadState: LoadState = LoadState.LOADED
enum class LoadState {
NOT_LOADED,
LOADING,
LOADED
}
companion object { companion object {
const val LENGTH: Int = 16 const val LENGTH: Int = 16
@ -108,4 +100,8 @@ abstract class Chunk(
const val SECTION_HEIGHT: Int = 16 const val SECTION_HEIGHT: Int = 16
const val BLOCKS_IN_A_SECTION = AREA * SECTION_HEIGHT 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 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.Y -> y.toInt()
CoordinatePart.Z -> z 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, radius: Int,
hollow: Boolean hollow: Boolean
): List<Voxel> { ): List<Voxel> {
// Implementation example https://git.io/JLysq // Implementation example: https://git.io/JLysq
TODO() TODO()
} }
/** /**
* Spawns an [entity][Entity] in this world. * Spawns [entity][Entity] in this world.
*/ */
abstract fun spawnEntity(entity: Entity) abstract fun spawnEntity(entity: Entity)
fun unload() { suspend fun destroy() = withContext(coroutineContext) {
// TODO: Move or kick players
coroutineContext.cancel() coroutineContext.cancel()
// TODO: Unload chunks
coroutineScope {
loadedChunks.values.forEach { launch { (it as? Chunk.Unloadable)?.unload() } }
}
threadExecutor.close() threadExecutor.close()
} }
} }

View file

@ -24,16 +24,16 @@ class TestPlugin: Plugin("Test", "1.0.0") {
Blokk.dimensionRegistry.register(dimension) Blokk.dimensionRegistry.register(dimension)
val world = AnvilWorld(dimension, true) 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() 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 -> Blokk.eventBus.on<SessionAfterLoginEvent> { event ->
event.initialWorldAndLocation = WorldAndLocationWithRotation( event.initialWorldAndLocation = WorldAndLocationWithRotation(
world, world,
VoxelLocation(0, 2, 0).atTopCenter().withRotation(0f, 0f) VoxelLocation.of(0, 2, 0).atTopCenter().withRotation(0f, 0f)
) )
} }
} }