Improved window close handling

- WindowManager#windowsByPlayer are now also updated in WindowManager#addWindow and WindowManager#removeWindow

- Opening a new window during window close handlers now properly registers them in the WindowManger maps; but a Spigot issue still prevents this from working as inventories opened during the InventoryCloseEvent don't get click events
This commit is contained in:
NichtStudioCode 2023-06-11 16:41:01 +02:00
parent e19447f7b9
commit 38cc1d57bd
2 changed files with 16 additions and 20 deletions

@ -225,11 +225,10 @@ public abstract class AbstractWindow implements Window, GuiParent {
if (currentlyOpen)
throw new IllegalStateException("Window is already open");
// call handleClosed() close for currently open window
// call handleCloseEvent() close for currently open window
AbstractWindow openWindow = (AbstractWindow) WindowManager.getInstance().getOpenWindow(viewer);
if (openWindow != null) {
openWindow.handleClosed();
openWindow.hasHandledClose = true;
openWindow.handleCloseEvent(true);
}
currentlyOpen = true;
@ -261,35 +260,34 @@ public abstract class AbstractWindow implements Window, GuiParent {
@Override
public void close() {
closeable = true;
Player viewer = getCurrentViewer();
if (viewer != null) {
handleCloseEvent(true);
viewer.closeInventory();
}
}
public void handleCloseEvent(Player player, boolean forceClose) {
public void handleCloseEvent(boolean forceClose) {
// handleCloseEvent might have already been called by close() or open() if the window was replaced by another one
if (hasHandledClose)
return;
if (closeable || forceClose) {
if (!currentlyOpen)
throw new IllegalStateException("Window is already closed!");
closeable = true;
currentlyOpen = false;
hasHandledClose = true;
remove();
// handleClosed() might have already been called by open() if the window was replaced by another one
if (!hasHandledClose) {
handleClosed();
hasHandledClose = true;
}
if (closeHandlers != null) {
closeHandlers.forEach(Runnable::run);
}
} else if (player.equals(getViewer())) {
Bukkit.getScheduler().runTaskLater(InvUI.getInstance().getPlugin(), () -> openInventory(player), 0);
} else {
Bukkit.getScheduler().runTaskLater(InvUI.getInstance().getPlugin(), () -> openInventory(viewer), 0);
}
}

@ -51,6 +51,7 @@ public class WindowManager implements Listener {
*/
public void addWindow(AbstractWindow window) {
windowsByInventory.put(window.getInventories()[0], window);
windowsByPlayer.put(window.getViewer(), window);
}
/**
@ -61,6 +62,7 @@ public class WindowManager implements Listener {
*/
public void removeWindow(AbstractWindow window) {
windowsByInventory.remove(window.getInventories()[0]);
windowsByPlayer.remove(window.getViewer());
}
/**
@ -124,10 +126,8 @@ public class WindowManager implements Listener {
Player player = (Player) event.getPlayer();
AbstractWindow window = (AbstractWindow) getWindow(event.getInventory());
if (window != null) {
window.handleCloseEvent(player, false);
window.handleCloseEvent(false);
}
windowsByPlayer.remove(player);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
@ -135,7 +135,6 @@ public class WindowManager implements Listener {
AbstractWindow window = (AbstractWindow) getWindow(event.getInventory());
if (window != null) {
window.handleOpenEvent(event);
windowsByPlayer.put((Player) event.getPlayer(), window);
}
}
@ -144,8 +143,7 @@ public class WindowManager implements Listener {
Player player = event.getPlayer();
AbstractWindow window = (AbstractWindow) getOpenWindow(player);
if (window != null) {
window.handleCloseEvent(player, true);
windowsByPlayer.remove(player);
window.handleCloseEvent(true);
}
}