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

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