From 27d2b5c8a4105ea11a51e64535bf0f06d6ba7830 Mon Sep 17 00:00:00 2001 From: Auxilor Date: Fri, 30 Sep 2022 12:44:06 +0100 Subject: [PATCH] Added menu signals --- .../com/willfp/eco/core/gui/menu/Menu.java | 11 +++++ .../willfp/eco/core/gui/menu/MenuBuilder.java | 18 ++++++-- .../com/willfp/eco/core/gui/menu/Signal.java | 8 ++++ .../eco/core/gui/menu/SignalHandler.java | 45 +++++++++++++++++++ .../eco/core/gui/page/PageChangeSignal.java | 16 +++++++ .../willfp/eco/core/gui/page/PageChanger.java | 9 ++++ .../com/willfp/eco/core/gui/GUIHelpers.kt | 10 +++++ .../willfp/eco/internal/gui/menu/EcoMenu.kt | 17 ++++++- .../eco/internal/gui/menu/EcoMenuBuilder.kt | 15 +++++-- 9 files changed, 140 insertions(+), 9 deletions(-) create mode 100644 eco-api/src/main/java/com/willfp/eco/core/gui/menu/Signal.java create mode 100644 eco-api/src/main/java/com/willfp/eco/core/gui/menu/SignalHandler.java create mode 100644 eco-api/src/main/java/com/willfp/eco/core/gui/page/PageChangeSignal.java diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/menu/Menu.java b/eco-api/src/main/java/com/willfp/eco/core/gui/menu/Menu.java index 79acbdf4..cd0ed51c 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/gui/menu/Menu.java +++ b/eco-api/src/main/java/com/willfp/eco/core/gui/menu/Menu.java @@ -135,6 +135,17 @@ public interface Menu { */ void refresh(@NotNull Player player); + /** + * Send a signal to the menu. + * + * @param player The player. + * @param signal The signal. + */ + default void sendSignal(@NotNull final Player player, + @NotNull final Signal signal) { + // Override when needed. + } + /** * Write data. * diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/menu/MenuBuilder.java b/eco-api/src/main/java/com/willfp/eco/core/gui/menu/MenuBuilder.java index f59ca8d6..9d69352a 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/gui/menu/MenuBuilder.java +++ b/eco-api/src/main/java/com/willfp/eco/core/gui/menu/MenuBuilder.java @@ -122,7 +122,7 @@ public interface MenuBuilder extends PageBuilder { } /** - * Set the menu close handler. + * Add a menu close handler. * * @param action The handler. * @return The builder. @@ -132,7 +132,7 @@ public interface MenuBuilder extends PageBuilder { } /** - * Set the menu close handler. + * Add a menu close handler. * * @param action The handler. * @return The builder. @@ -140,7 +140,7 @@ public interface MenuBuilder extends PageBuilder { MenuBuilder onClose(@NotNull CloseHandler action); /** - * Set the menu open handler. + * Add a menu open handler. * * @param action The handler. * @return The builder. @@ -148,13 +148,23 @@ public interface MenuBuilder extends PageBuilder { MenuBuilder onOpen(@NotNull OpenHandler action); /** - * Set the action to run on render. + * Add an action to run on render. * * @param action The action. * @return The builder. */ MenuBuilder onRender(@NotNull BiConsumer action); + /** + * Add an action to run on signal receive. + * + * @param action The action. + * @return THe builder. + */ + default MenuBuilder onSignalReceive(@NotNull final SignalHandler action) { + return this; + } + /** * Build the menu. * diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/menu/Signal.java b/eco-api/src/main/java/com/willfp/eco/core/gui/menu/Signal.java new file mode 100644 index 00000000..0378383e --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/gui/menu/Signal.java @@ -0,0 +1,8 @@ +package com.willfp.eco.core.gui.menu; + +/** + * Represents a signal sent to a menu. + */ +public interface Signal { + +} diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/menu/SignalHandler.java b/eco-api/src/main/java/com/willfp/eco/core/gui/menu/SignalHandler.java new file mode 100644 index 00000000..f9dbafc1 --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/gui/menu/SignalHandler.java @@ -0,0 +1,45 @@ +package com.willfp.eco.core.gui.menu; + +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +/** + * Handles signals sent to menus. + */ +public abstract class SignalHandler { + /** + * The class of signal. + */ + private final Class signalClass; + + /** + * Create a new signal handler. + * + * @param signalClass The class of signal to handle. + */ + protected SignalHandler(@NotNull final Class signalClass) { + this.signalClass = signalClass; + } + + + /** + * Performs this operation on the given arguments. + * + * @param player The player. + * @param menu The menu. + * @param signal The signal. + */ + public abstract void handle(@NotNull Player player, + @NotNull Menu menu, + @NotNull T signal); + + /** + * Get if this handler can handle a certain signal. + * + * @param signal The signal + * @return If the signal can be handled. + */ + public boolean canHandleSignal(@NotNull final Signal signal) { + return signalClass.isAssignableFrom(signal.getClass()); + } +} diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/page/PageChangeSignal.java b/eco-api/src/main/java/com/willfp/eco/core/gui/page/PageChangeSignal.java new file mode 100644 index 00000000..a51b87fd --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/gui/page/PageChangeSignal.java @@ -0,0 +1,16 @@ +package com.willfp.eco.core.gui.page; + +import com.willfp.eco.core.gui.menu.Signal; + +/** + * Represents a page change. + * + * @param newPage The new page. + * @param oldPage The old page. + */ +public record PageChangeSignal( + int newPage, + int oldPage +) implements Signal { + +} diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/page/PageChanger.java b/eco-api/src/main/java/com/willfp/eco/core/gui/page/PageChanger.java index e1561514..26d154ab 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/gui/page/PageChanger.java +++ b/eco-api/src/main/java/com/willfp/eco/core/gui/page/PageChanger.java @@ -43,7 +43,16 @@ public final class PageChanger implements GUIComponent { Page.getMaxPage(player, menu) ) ); + + if (newPage == page) { + return; + } + menu.addState(player, Page.PAGE_KEY, newPage); + menu.sendSignal(player, new PageChangeSignal( + newPage, + page + )); }) .build(); } diff --git a/eco-api/src/main/kotlin/com/willfp/eco/core/gui/GUIHelpers.kt b/eco-api/src/main/kotlin/com/willfp/eco/core/gui/GUIHelpers.kt index 2092df24..34956b0c 100644 --- a/eco-api/src/main/kotlin/com/willfp/eco/core/gui/GUIHelpers.kt +++ b/eco-api/src/main/kotlin/com/willfp/eco/core/gui/GUIHelpers.kt @@ -4,6 +4,8 @@ package com.willfp.eco.core.gui import com.willfp.eco.core.gui.menu.Menu import com.willfp.eco.core.gui.menu.MenuBuilder +import com.willfp.eco.core.gui.menu.Signal +import com.willfp.eco.core.gui.menu.SignalHandler import com.willfp.eco.core.gui.page.Page import com.willfp.eco.core.gui.page.PageBuilder import com.willfp.eco.core.gui.slot.Slot @@ -140,6 +142,14 @@ fun MenuBuilder.addPage(page: Int, creation: PageBuilder.() -> Unit): MenuBuilde return this.addPage(Page(page, builder.build())) } +/** @see MenuBuilder.onSignalReceive */ +inline fun MenuBuilder.onSignalReceive(crossinline handler: (Player, Menu, T) -> Unit): MenuBuilder { + return this.onSignalReceive(object : SignalHandler(T::class.java) { + override fun handle(player: Player, menu: Menu, signal: T) = + handler(player, menu, signal) + }) +} + /** Kotlin builder for menus. */ fun menu( rows: Int, diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenu.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenu.kt index 62bb8091..675aad1c 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenu.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenu.kt @@ -4,6 +4,8 @@ import com.willfp.eco.core.gui.component.GUIComponent import com.willfp.eco.core.gui.menu.CloseHandler import com.willfp.eco.core.gui.menu.Menu import com.willfp.eco.core.gui.menu.OpenHandler +import com.willfp.eco.core.gui.menu.Signal +import com.willfp.eco.core.gui.menu.SignalHandler import com.willfp.eco.core.gui.slot.FillerSlot import com.willfp.eco.core.gui.slot.Slot import com.willfp.eco.util.NamespacedKeyUtils @@ -23,7 +25,8 @@ class EcoMenu( private val title: String, private val onClose: List, private val onRender: List<(Player, Menu) -> Unit>, - private val onOpen: List + private val onOpen: List, + private val signalHandlers: List> ) : Menu { private fun getPossiblyReactiveSlot(row: Int, column: Int, player: Player?, menu: Menu?): Slot { if (row < 1 || row > this.rows || column < 1 || column > 9) { @@ -93,6 +96,18 @@ class EcoMenu( return inventory.captiveItems } + override fun sendSignal(player: Player, signal: Signal) { + for (handler in signalHandlers) { + if (handler.canHandleSignal(signal)) { + handler.handle(signal, player) + } + } + } + + private fun SignalHandler.handle(signal: Signal, player: Player) { + this.handle(player, this@EcoMenu, signal as T) + } + @Deprecated("Deprecated in Java", ReplaceWith("addState(player, key.toString(), value)")) override fun writeData( player: Player, diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenuBuilder.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenuBuilder.kt index 44a970a3..bf5d3c30 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenuBuilder.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenuBuilder.kt @@ -6,6 +6,7 @@ import com.willfp.eco.core.gui.menu.Menu import com.willfp.eco.core.gui.menu.MenuBuilder import com.willfp.eco.core.gui.menu.MenuLayer import com.willfp.eco.core.gui.menu.OpenHandler +import com.willfp.eco.core.gui.menu.SignalHandler import com.willfp.eco.util.StringUtils import org.bukkit.entity.Player import java.util.function.BiConsumer @@ -14,9 +15,10 @@ import java.util.function.Consumer class EcoMenuBuilder(private val rows: Int) : MenuBuilder { private var title = "Menu" private val components = mutableMapOf>>() - private var onClose = mutableListOf() - private var onOpen = mutableListOf() - private var onRender = mutableListOf<(Player, Menu) -> Unit>() + private val onClose = mutableListOf() + private val onOpen = mutableListOf() + private val onRender = mutableListOf<(Player, Menu) -> Unit>() + private val signalHandlers = mutableListOf>() override fun getRows() = rows @@ -58,6 +60,11 @@ class EcoMenuBuilder(private val rows: Int) : MenuBuilder { return this } + override fun onSignalReceive(action: SignalHandler<*>): MenuBuilder { + signalHandlers += action + return this + } + override fun build(): Menu { val layeredComponents = mutableMapOf>>() @@ -100,6 +107,6 @@ class EcoMenuBuilder(private val rows: Int) : MenuBuilder { } } - return EcoMenu(rows, componentsAtPoints, title, onClose, onRender, onOpen) + return EcoMenu(rows, componentsAtPoints, title, onClose, onRender, onOpen, signalHandlers) } }