Archived
0

Improve async command approach - use coroutines correctly

This commit is contained in:
Dico200
2018-07-26 17:21:26 +01:00
parent c0e4ab728e
commit bf1da03370
12 changed files with 344 additions and 131 deletions

View File

@@ -2,20 +2,29 @@ package io.dico.parcels2.command
import io.dico.dicore.command.CommandException
import io.dico.dicore.command.ExecutionContext
import io.dico.dicore.command.ICommandReceiver
import io.dico.dicore.command.annotation.Cmd
import io.dico.dicore.command.annotation.Desc
import io.dico.dicore.command.annotation.RequireParameters
import io.dico.parcels2.ParcelOwner
import io.dico.parcels2.ParcelsPlugin
import io.dico.parcels2.logger
import io.dico.parcels2.storage.getParcelBySerializedValue
import io.dico.parcels2.util.hasParcelHomeOthers
import io.dico.parcels2.util.parcelLimit
import io.dico.parcels2.util.uuid
import org.bukkit.entity.Player
import org.bukkit.plugin.Plugin
import java.lang.reflect.Method
@Suppress("unused")
class ParcelCommands(override val plugin: ParcelsPlugin) : HasWorlds, HasPlugin {
override val worlds = plugin.worlds
//@Suppress("unused")
class ParcelCommands(val plugin: ParcelsPlugin) : ICommandReceiver.Factory {
private inline val worlds get() = plugin.worlds
override fun getPlugin(): Plugin = plugin
override fun getReceiver(context: ExecutionContext, target: Method, cmdName: String): ICommandReceiver {
return getParcelCommandReceiver(plugin.worlds, context, target, cmdName)
}
private fun error(message: String): Nothing {
throw CommandException(message)
@@ -25,31 +34,29 @@ class ParcelCommands(override val plugin: ParcelsPlugin) : HasWorlds, HasPlugin
@Desc("Finds the unclaimed parcel nearest to origin,",
"and gives it to you",
shortVersion = "sets you up with a fresh, unclaimed parcel")
fun cmdAuto(player: Player, context: ExecutionContext) = requireInWorld(player) {
delegateCommandAsync(context) {
val numOwnedParcels = plugin.storage.getNumParcels(ParcelOwner(uuid = player.uuid)).await()
suspend fun WorldOnlyScope.cmdAuto(player: Player): Any? {
logger.info("cmdAuto thread before await: ${Thread.currentThread().name}")
val numOwnedParcels = plugin.storage.getNumParcels(ParcelOwner(uuid = player.uuid)).await()
logger.info("cmdAuto thread before await: ${Thread.currentThread().name}")
awaitSynchronousTask {
val limit = player.parcelLimit
val limit = player.parcelLimit
if (numOwnedParcels >= limit) {
error("You have enough plots for now")
}
val parcel = world.nextEmptyParcel()
?: error("This world is full, please ask an admin to upsize it")
parcel.owner = ParcelOwner(uuid = player.uuid)
player.teleport(parcel.homeLocation)
"Enjoy your new parcel!"
}
if (numOwnedParcels >= limit) {
error("You have enough plots for now")
}
val parcel = world.nextEmptyParcel()
?: error("This world is full, please ask an admin to upsize it")
parcel.owner = ParcelOwner(uuid = player.uuid)
player.teleport(parcel.homeLocation)
return "Enjoy your new parcel!"
}
@Cmd("info", aliases = ["i"])
@Desc("Displays general information",
"about the parcel you're on",
shortVersion = "displays information about this parcel")
fun cmdInfo(player: Player) = requireInParcel(player) { parcel.infoString }
fun ParcelScope.cmdInfo(player: Player) = parcel.infoString
@Cmd("home", aliases = ["h"])
@Desc("Teleports you to your parcels,",
@@ -58,36 +65,33 @@ class ParcelCommands(override val plugin: ParcelsPlugin) : HasWorlds, HasPlugin
"more than one parcel",
shortVersion = "teleports you to parcels")
@RequireParameters(0)
fun cmdHome(player: Player, context: ExecutionContext, target: NamedParcelTarget) {
suspend fun SuspendOnlyScope.cmdHome(player: Player, context: ExecutionContext,
@NamedParcelDefault(NamedParcelDefaultValue.FIRST_OWNED) target: NamedParcelTarget): Any? {
if (player !== target.player && !player.hasParcelHomeOthers) {
error("You do not have permission to teleport to other people's parcels")
}
return delegateCommandAsync(context) {
val ownedParcelsResult = plugin.storage.getOwnedParcels(ParcelOwner(uuid = target.player.uuid)).await()
awaitSynchronousTask {
val uuid = target.player.uuid
val ownedParcels = ownedParcelsResult
.map { worlds.getParcelBySerializedValue(it) }
.filter { it != null && it.world == target.world && it.owner?.uuid == uuid }
logger.info("cmdHome thread before await: ${Thread.currentThread().name}")
val ownedParcelsResult = plugin.storage.getOwnedParcels(ParcelOwner(uuid = target.player.uuid)).await()
logger.info("cmdHome thread after await: ${Thread.currentThread().name}")
val targetMatch = ownedParcels.getOrNull(target.index)
?: error("The specified parcel could not be matched")
val uuid = target.player.uuid
val ownedParcels = ownedParcelsResult
.map { worlds.getParcelBySerializedValue(it) }
.filter { it != null && it.world == target.world && it.owner?.uuid == uuid }
player.teleport(targetMatch.homeLocation)
""
}
}
val targetMatch = ownedParcels.getOrNull(target.index)
?: error("The specified parcel could not be matched")
player.teleport(targetMatch.homeLocation)
return ""
}
@Cmd("claim")
@Desc("If this parcel is unowned, makes you the owner",
shortVersion = "claims this parcel")
fun cmdClaim(player: Player) {
fun ParcelScope.cmdClaim(player: Player) {
}
}