Skip to content

Commit 45bb078

Browse files
committed
fix: Correctly handle onClose per inventory
refactor: Reopen guis automatically, but call exit by default
1 parent a191aab commit 45bb078

File tree

8 files changed

+47
-52
lines changed

8 files changed

+47
-52
lines changed

src/main/kotlin/com/mineinabyss/guiy/components/canvases/Anvil.kt

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.mineinabyss.guiy.components.rememberMiniMsg
66
import com.mineinabyss.guiy.components.state.IntCoordinates
77
import com.mineinabyss.guiy.guiyPlugin
88
import com.mineinabyss.guiy.inventory.CurrentPlayer
9+
import com.mineinabyss.guiy.inventory.GuiyInventory
910
import com.mineinabyss.guiy.inventory.GuiyInventoryHolder
1011
import com.mineinabyss.guiy.inventory.InventoryCloseScope
1112
import com.mineinabyss.guiy.layout.Box
@@ -17,15 +18,14 @@ import com.mineinabyss.idofront.textcomponents.toPlainText
1718
import kotlinx.coroutines.flow.filter
1819
import kotlinx.coroutines.flow.filterNotNull
1920
import org.bukkit.Bukkit
20-
import org.bukkit.entity.Player
2121
import org.bukkit.event.inventory.InventoryType
2222
import org.bukkit.inventory.Inventory
2323

2424
@Composable
2525
fun Anvil(
2626
title: String,
2727
onTextChanged: (String) -> Unit,
28-
onClose: (InventoryCloseScope.(player: Player) -> Unit) = {},
28+
onClose: InventoryCloseScope.() -> Unit = { exit() },
2929
onSubmit: (String) -> Unit = {},
3030
inputLeft: @Composable () -> Unit = { InvisibleItem() },
3131
inputRight: @Composable () -> Unit = { InvisibleItem() },
@@ -34,10 +34,12 @@ fun Anvil(
3434
val holder: GuiyInventoryHolder = LocalInventoryHolder.current
3535
val player = CurrentPlayer
3636
val titleMM = rememberMiniMsg(title)
37-
val inventory: Inventory =
38-
remember(holder) { Bukkit.getServer().createInventory(holder, InventoryType.ANVIL, titleMM) }
39-
holder.setActiveInventory(inventory)
37+
val inventory: Inventory = remember(holder) {
38+
Bukkit.getServer().createInventory(holder, InventoryType.ANVIL, titleMM)
39+
}
40+
holder.setActiveInventory(GuiyInventory(inventory, onClose))
4041

42+
// Track updates to anvil text via packets
4143
var playerViewText by remember(inventory) { mutableStateOf("") }
4244
LaunchedEffect(player) {
4345
guiyPlugin.anvilPacketFlow.filter { it?.second == player }.filterNotNull().collect {
@@ -48,7 +50,7 @@ fun Anvil(
4850
}
4951
}
5052

51-
val constrainedModifier = Modifier.Companion.size(width = 3, height = 1)
53+
val constrainedModifier = Modifier.size(width = 3, height = 1)
5254

5355
Inventory(
5456
inventory,
@@ -57,13 +59,13 @@ fun Anvil(
5759
gridToInventoryIndex = { it.x },
5860
inventoryIndexToGrid = { IntCoordinates(it, 0) }) {
5961
Row {
60-
Box(Modifier.Companion.size(1)) {
62+
Box(Modifier.size(1)) {
6163
inputLeft()
6264
}
63-
Box(Modifier.Companion.size(1)) {
65+
Box(Modifier.size(1)) {
6466
inputRight()
6567
}
66-
Box(Modifier.Companion.size(1).clickable { onSubmit(playerViewText) }) {
68+
Box(Modifier.size(1).clickable { onSubmit(playerViewText) }) {
6769
output()
6870
}
6971
}

src/main/kotlin/com/mineinabyss/guiy/components/canvases/Chest.kt

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@ package com.mineinabyss.guiy.components.canvases
33
import androidx.compose.runtime.*
44
import com.mineinabyss.guiy.components.rememberMiniMsg
55
import com.mineinabyss.guiy.components.state.IntCoordinates
6+
import com.mineinabyss.guiy.inventory.GuiyInventory
67
import com.mineinabyss.guiy.inventory.GuiyInventoryHolder
7-
import com.mineinabyss.guiy.inventory.LocalGuiyOwner
8+
import com.mineinabyss.guiy.inventory.InventoryCloseScope
89
import com.mineinabyss.guiy.layout.Layout
910
import com.mineinabyss.guiy.layout.Size
11+
import com.mineinabyss.guiy.layout.StaticMeasurePolicy
1012
import com.mineinabyss.guiy.modifiers.Modifier
1113
import com.mineinabyss.guiy.modifiers.onSizeChanged
1214
import com.mineinabyss.guiy.modifiers.sizeIn
13-
import com.mineinabyss.guiy.inventory.InventoryCloseScope
14-
import com.mineinabyss.guiy.layout.StaticMeasurePolicy
1515
import net.kyori.adventure.text.Component
1616
import org.bukkit.Bukkit
17-
import org.bukkit.entity.Player
1817
import org.bukkit.inventory.Inventory
1918

2019
const val CHEST_WIDTH = 9
@@ -30,7 +29,7 @@ const val MAX_CHEST_HEIGHT = 6
3029
fun Chest(
3130
title: String,
3231
modifier: Modifier = Modifier,
33-
onClose: (InventoryCloseScope.(player: Player) -> Unit) = { exit() },
32+
onClose: InventoryCloseScope.() -> Unit = { exit() },
3433
content: @Composable () -> Unit,
3534
) {
3635
val titleMM = rememberMiniMsg(title)
@@ -50,7 +49,7 @@ fun Chest(
5049
fun Chest(
5150
title: Component,
5251
modifier: Modifier = Modifier,
53-
onClose: (InventoryCloseScope.(player: Player) -> Unit) = {},
52+
onClose: InventoryCloseScope.() -> Unit = { exit() },
5453
content: @Composable () -> Unit,
5554
) {
5655
val holder: GuiyInventoryHolder = LocalInventoryHolder.current
@@ -59,10 +58,6 @@ fun Chest(
5958
Modifier.sizeIn(CHEST_WIDTH, CHEST_WIDTH, MIN_CHEST_HEIGHT, MAX_CHEST_HEIGHT).then(modifier)
6059
.onSizeChanged { if (size != it) size = it }
6160

62-
val viewers by LocalGuiyOwner.current.viewers.collectAsState()
63-
64-
// Create new inventory when any appropriate value changes
65-
6661
// Draw nothing if empty
6762
if (size == Size()) {
6863
Layout(
@@ -74,11 +69,10 @@ fun Chest(
7469

7570
val inventory: Inventory = remember(size) {
7671
Bukkit.createInventory(holder, CHEST_WIDTH * size.height, title).also {
77-
holder.setActiveInventory(it)
7872
}
7973
}
74+
holder.setActiveInventory(GuiyInventory(inventory, onClose))
8075

81-
//TODO handle sending correct title when player list changes
8276
Inventory(
8377
inventory = inventory,
8478
title = title,

src/main/kotlin/com/mineinabyss/guiy/components/canvases/Inventory.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.mineinabyss.guiy.components.canvases
22

33
import androidx.compose.runtime.*
4-
import com.github.shynixn.mccoroutine.bukkit.launch
54
import com.github.shynixn.mccoroutine.bukkit.minecraftDispatcher
65
import com.mineinabyss.guiy.components.state.IntCoordinates
76
import com.mineinabyss.guiy.guiyPlugin
@@ -11,13 +10,12 @@ import com.mineinabyss.guiy.inventory.LocalGuiyOwner
1110
import com.mineinabyss.guiy.inventory.MapBackedGuiyCanvas
1211
import com.mineinabyss.guiy.layout.Layout
1312
import com.mineinabyss.guiy.layout.Renderer
13+
import com.mineinabyss.guiy.layout.StaticMeasurePolicy
1414
import com.mineinabyss.guiy.modifiers.Modifier
1515
import com.mineinabyss.guiy.nodes.GuiyNode
16-
import com.mineinabyss.guiy.layout.StaticMeasurePolicy
1716
import com.mineinabyss.idofront.entities.title
1817
import kotlinx.coroutines.withContext
1918
import net.kyori.adventure.text.Component
20-
import org.bukkit.entity.Player
2119
import org.bukkit.event.inventory.InventoryCloseEvent
2220
import org.bukkit.inventory.Inventory
2321

@@ -42,8 +40,8 @@ fun Inventory(
4240
) {
4341
val viewers by LocalGuiyOwner.current.viewers.collectAsState()
4442

45-
// This just sends a packet, doesn't need to be on sync thread
46-
LaunchedEffect(title) {
43+
// Update title
44+
LaunchedEffect(title, viewers) {
4745
if (title != null) inventory.viewers.forEach { it.openInventory.title(title) }
4846
}
4947

@@ -64,6 +62,7 @@ fun Inventory(
6462
}
6563
}
6664
}
65+
6766
val canvas = remember { MapBackedGuiyCanvas() }
6867

6968
CompositionLocalProvider(

src/main/kotlin/com/mineinabyss/guiy/components/canvases/rememberInventoryHolder.kt

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,11 @@ fun ProvideInventoryHolder(content: @Composable () -> Unit) {
3333
}
3434

3535
@Composable
36-
fun rememberInventoryHolder(
37-
onClose: InventoryCloseScope.(Player) -> Unit = {},
38-
): GuiyInventoryHolder {
36+
fun rememberInventoryHolder(): GuiyInventoryHolder {
3937
val clickHandler = LocalClickHandler.current
4038
val owner = LocalGuiyOwner.current
4139
val viewers by owner.viewers.collectAsState()
42-
return remember(clickHandler, onClose) {
40+
return remember(clickHandler, viewers) {
4341
object : GuiyInventoryHolder() {
4442
override fun processClick(scope: ClickScope, event: Cancellable) {
4543
clickHandler.processClick(scope)
@@ -50,22 +48,20 @@ fun rememberInventoryHolder(
5048
}
5149

5250
override fun onClose(player: Player) {
51+
val inventory = activeInventory.value ?: return
5352
val scope = object : InventoryCloseScope {
54-
override fun reopen() {
55-
guiyPlugin.launch {
56-
delay(1.ticks)
57-
//TODO don't think this reference updates properly in the remember block
58-
viewers.filter { it.openInventory.topInventory != inventory }
59-
.forEach { it.openInventory(inventory) }
60-
}
61-
}
53+
override val player = player
6254

6355
override fun exit() {
6456
owner.exit()
6557
}
6658
}
67-
onClose.invoke(scope, player)
68-
closeIfNoLongerViewing(player)
59+
inventory.onClose.invoke(scope)
60+
if (!owner.exitScheduled) guiyPlugin.launch {
61+
delay(1.ticks)
62+
viewers.filter { it.openInventory.topInventory != inventory }
63+
.forEach { it.openInventory(inventory.inventory) }
64+
}
6965
}
7066

7167
override fun closeIfNoLongerViewing(player: Player) {

src/main/kotlin/com/mineinabyss/guiy/components/items/Text.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import net.kyori.adventure.text.Component
1212
* Text with invisible item, use [LocalItemTheme] to choose the invisible item based on your resourcepack.
1313
*/
1414
@Composable
15-
fun Text(name: String, vararg lore: String, hideTooltip: Boolean = false, modifier: Modifier = Modifier.Companion) {
15+
fun Text(name: String, vararg lore: String, hideTooltip: Boolean = false, modifier: Modifier = Modifier) {
1616
val mmName = rememberMiniMsg(name)
1717
val mmLore = rememberMiniMsg(*lore).toTypedArray()
1818
Text(mmName, lore = mmLore, hideTooltip, modifier)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.mineinabyss.guiy.inventory
2+
3+
import androidx.compose.runtime.Immutable
4+
import org.bukkit.inventory.Inventory
5+
6+
@Immutable
7+
data class GuiyInventory(
8+
val inventory: Inventory,
9+
val onClose: InventoryCloseScope.() -> Unit,
10+
)

src/main/kotlin/com/mineinabyss/guiy/inventory/GuiyInventoryHolder.kt

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.mineinabyss.guiy.inventory
22

3-
import androidx.compose.runtime.Immutable
43
import com.mineinabyss.guiy.modifiers.click.ClickScope
54
import com.mineinabyss.guiy.modifiers.drag.DragScope
65
import kotlinx.coroutines.flow.MutableStateFlow
@@ -12,20 +11,14 @@ import org.bukkit.event.inventory.InventoryCloseEvent
1211
import org.bukkit.inventory.Inventory
1312
import org.bukkit.inventory.InventoryHolder
1413

15-
@Immutable
16-
data class GuiyInventory(
17-
val inventory: Inventory,
18-
val onClose: () -> Unit,
19-
)
20-
2114
abstract class GuiyInventoryHolder : InventoryHolder {
22-
private val _activeInventory = MutableStateFlow<Inventory?>(null)
15+
private val _activeInventory = MutableStateFlow<GuiyInventory?>(null)
2316
val activeInventory = _activeInventory.asStateFlow()
2417

2518
override fun getInventory(): Inventory =
26-
activeInventory.value ?: error("Guiy inventory is used in bukkit but has not been rendered yet.")
19+
activeInventory.value?.inventory ?: error("Guiy inventory is used in bukkit but has not been rendered yet.")
2720

28-
fun setActiveInventory(inventory: Inventory) = _activeInventory.update { inventory }
21+
fun setActiveInventory(inventory: GuiyInventory) = _activeInventory.update { inventory }
2922

3023
abstract fun processClick(scope: ClickScope, event: Cancellable)
3124
abstract fun processDrag(scope: DragScope)
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package com.mineinabyss.guiy.inventory
22

33
import androidx.compose.runtime.Stable
4+
import org.bukkit.entity.Player
45

56
@Stable
67
interface InventoryCloseScope {
7-
fun reopen()
8+
val player: Player
89
fun exit()
910
}

0 commit comments

Comments
 (0)