Kotlinx Coroutines
arslanarm opened this issue · 6 comments
Adding support for coroutines would be nice. First of all, the new KItem class contains a list of callbacks, with coroutines and flows KItem would look
public sealed class ClickEvent
public data class LeftClick(val player: Player, val hand: Player.Hand): ClickEvent()
public data class RightClick(val player: Player, val hand: Player.Hand): ClickEvent()
public class KItem(material: Material, amount: Byte = 1, damage: Int = 0): ItemStack(material, amount, damage) {
private val _events = MutableSharedFlow<ClickEvent>()
public val clicks = _events.asSharedFlow()
public val leftClicks get() = clicks.filterIsInstance<LeftClick>()
public val rightClick get() = clicks.filterIsInstance<RightClick>()
override fun onLeftClick(player: Player, hand: Player.Hand) {
GlobalScope.launch { _events.emit(LeftClick(player, hand)) } // in most cases
}
override fun onRightClick(player: Player, hand: Player.Hand) {
GlobalScope.launch { _events.emit(RightClick(player, hand)) }
}
}
from the call site, it would look like
item.leftClicks.collect { (player, hand) ->
// do something
}
Flow API allows doing a lot of stuff as rxjava does. https://kotlinlang.org/docs/reference/coroutines/flow.html
Wow! I did not know about the Flow API -- will take this into consideration. I'll see what I can do 👍
Actually, it won't work sadly -- Minestom calls it via the override.
Strange, this example works perfectly well. Are you adding suspend modifier to the function? We can't add suspend modifier because it changes the function signature, so that's why there is GlobalScope.launch. In our case, runBlocking can be used, because we emit the value and immediately return from the function.
public sealed class ClickEvent
public data class LeftClick(val player: Player, val hand: Player.Hand): ClickEvent()
public data class RightClick(val player: Player, val hand: Player.Hand): ClickEvent()
public class KItem(material: Material, amount: Byte = 1, damage: Int = 0): ItemStack(material, amount, damage) {
private val _events = MutableSharedFlow<ClickEvent>()
public val clicks = _events.asSharedFlow()
public val leftClicks get() = clicks.filterIsInstance<LeftClick>()
public val rightClick get() = clicks.filterIsInstance<RightClick>()
override fun onLeftClick(player: Player, hand: Player.Hand): Unit = runBlocking {
_events.emit(LeftClick(player, hand))
}
override fun onRightClick(player: Player, hand: Player.Hand): Unit = runBlocking {
_events.emit(RightClick(player, hand))
}
}
How would we add left/right clicks?
if we have a click event we can just emit that click event to the _events. On the other side, if someone wants to listen to the events it can be done as
val item = KItem(Material.STICK)
item.leftClicks
.onEach { println("${it.player.name} used left click") }
.launch(GlobalScope)
Yeah, left/right click triggering already happens natively through Minestom -- that does seem like an interesting way to add them.