Skip to content

Commit 3c3e2f8

Browse files
committed
Fix switching within menus calling close handlers causing a cascade
Caused child menus to be closed when opening said child menu
1 parent d400919 commit 3c3e2f8

File tree

6 files changed

+30
-20
lines changed

6 files changed

+30
-20
lines changed

build.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ val javaVersion: Int = 21
1515

1616
allprojects {
1717
group = "com.noxcrew.interfaces"
18-
version = "1.1.9-SNAPSHOT"
18+
version = "1.1.10"
1919

2020
tasks.withType<JavaCompile> {
2121
sourceCompatibility = javaVersion.toString()

interfaces/src/main/kotlin/com/noxcrew/interfaces/InterfacesListeners.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public class InterfacesListeners private constructor(private val plugin: Plugin)
162162
val shouldReopen = reason in REOPEN_REASONS && !event.player.isDead && openInterface != null
163163

164164
// Mark the current view as closed properly
165-
view.markClosed(reason, !shouldReopen && reason != Reason.OPEN_NEW)
165+
view.markClosed(reason, shouldReopen || reason == Reason.OPEN_NEW)
166166

167167
// If possible, open back up a previous interface
168168
if (shouldReopen) {

interfaces/src/main/kotlin/com/noxcrew/interfaces/interfaces/AbstractInterfaceBuilder.kt

+5-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ public abstract class AbstractInterfaceBuilder<P : Pane, I : Interface<P>> inter
4242
/** Keeps items that were previously in the inventory before opening the view. */
4343
public var inheritExistingItems: Boolean = false
4444

45+
/** Whether close handlers should be called when switching to a different view. */
46+
public var callCloseHandlerOnViewSwitch: Boolean = true
47+
4548
/** The properties object to use for the created interface. */
4649
public val properties: InterfaceProperties<P>
4750
get() = InterfaceProperties(
@@ -52,7 +55,8 @@ public abstract class AbstractInterfaceBuilder<P : Pane, I : Interface<P>> inter
5255
preventClickingEmptySlots,
5356
preventedInteractions,
5457
persistAddedItems,
55-
inheritExistingItems
58+
inheritExistingItems,
59+
callCloseHandlerOnViewSwitch
5660
)
5761

5862
/** Adds a new transform to the interface that updates whenever [triggers] change. */

interfaces/src/main/kotlin/com/noxcrew/interfaces/interfaces/InterfaceProperties.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,7 @@ public data class InterfaceProperties<P : Pane>(
2424
/** Persists items added to this pane in a previous instance. */
2525
public val persistAddedItems: Boolean = false,
2626
/** Keeps items that were previously in the inventory before opening this. */
27-
public val inheritExistingItems: Boolean = false
27+
public val inheritExistingItems: Boolean = false,
28+
/** Whether close handlers should be called when switching to a different view. */
29+
public val callCloseHandlerOnViewSwitch: Boolean = true
2830
)

interfaces/src/main/kotlin/com/noxcrew/interfaces/view/AbstractInterfaceView.kt

+18-14
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public abstract class AbstractInterfaceView<I : InterfacesInventory, P : Pane>(
8484
/** Marks this menu as closed and processes it. */
8585
internal suspend fun markClosed(
8686
reason: InventoryCloseEvent.Reason = InventoryCloseEvent.Reason.UNKNOWN,
87-
closeInventory: Boolean = reason != InventoryCloseEvent.Reason.OPEN_NEW
87+
changingView: Boolean = reason == InventoryCloseEvent.Reason.OPEN_NEW
8888
) {
8989
// End a possible chat query with the listener
9090
InterfacesListeners.INSTANCE.abortQuery(player.uniqueId, this)
@@ -93,18 +93,21 @@ public abstract class AbstractInterfaceView<I : InterfacesInventory, P : Pane>(
9393
openIfClosed.set(false)
9494

9595
// Run a generic close handler if it's still opened
96-
if (shouldBeOpened.compareAndSet(true, false)) {
96+
if (shouldBeOpened.compareAndSet(true, false) && (!changingView || backing.properties.callCloseHandlerOnViewSwitch)) {
9797
backing.properties.closeHandlers[reason]?.invoke(reason, this)
9898
}
9999

100-
// Close any children, this is a bit of a lossy system,
101-
// we don't particularly care if this happens nicely we
102-
// just want to make sure the ones that need closing get
103-
// closed. The hashmap is weak so children can get GC'd
104-
// properly.
105-
for ((child) in children) {
106-
if (child.shouldBeOpened.get()) {
107-
child.close(reason, closeInventory)
100+
// Don't close children when changing views!
101+
if (!changingView) {
102+
// Close any children, this is a bit of a lossy system,
103+
// we don't particularly care if this happens nicely we
104+
// just want to make sure the ones that need closing get
105+
// closed. The hashmap is weak so children can get GC'd
106+
// properly.
107+
for ((child) in children) {
108+
if (child.shouldBeOpened.get()) {
109+
child.close(reason, false)
110+
}
108111
}
109112
}
110113
}
@@ -156,11 +159,12 @@ public abstract class AbstractInterfaceView<I : InterfacesInventory, P : Pane>(
156159
}
157160
}
158161

159-
override suspend fun close(reason: InventoryCloseEvent.Reason, closeInventory: Boolean) {
160-
markClosed(reason, closeInventory)
162+
override suspend fun close(reason: InventoryCloseEvent.Reason, changingView: Boolean) {
163+
markClosed(reason, changingView)
161164

162-
if (isOpen() && closeInventory) {
163-
// Ensure we always close on the main thread!
165+
// Ensure we always close on the main thread! Don't close if we are
166+
// changing views though.
167+
if (!changingView && isOpen()) {
164168
runSync {
165169
player.closeInventory()
166170
}

interfaces/src/main/kotlin/com/noxcrew/interfaces/view/PlayerInterfaceView.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ public class PlayerInterfaceView internal constructor(
6060
}
6161
}
6262

63-
override suspend fun close(reason: InventoryCloseEvent.Reason, closeInventory: Boolean) {
64-
markClosed(reason, closeInventory)
63+
override suspend fun close(reason: InventoryCloseEvent.Reason, changingView: Boolean) {
64+
markClosed(reason, changingView)
6565

6666
// Ensure we update the interface state in the main thread!
6767
// Even if the menu is not currently on the screen.

0 commit comments

Comments
 (0)