diff --git a/src/main/kotlin/net/axay/kspigot/gui/GUI.kt b/src/main/kotlin/net/axay/kspigot/gui/GUI.kt index 189a6f32..1e9a0131 100644 --- a/src/main/kotlin/net/axay/kspigot/gui/GUI.kt +++ b/src/main/kotlin/net/axay/kspigot/gui/GUI.kt @@ -2,14 +2,16 @@ package net.axay.kspigot.gui +import net.axay.kspigot.event.listen +import net.axay.kspigot.extensions.bukkit.closeForViewers import org.bukkit.entity.Player +import org.bukkit.event.inventory.InventoryCloseEvent +import org.bukkit.event.player.PlayerQuitEvent import org.bukkit.inventory.Inventory import org.bukkit.inventory.ItemStack import java.util.* import kotlin.collections.HashSet -// TODO unregister in all layers - private const val DEFAULT_PAGE = 1 class GUIData( @@ -24,22 +26,59 @@ class GUIData( abstract class GUI( val data: GUIData ) { + + /** + * Returns the instance beloning to the given player. + * If not existing, a new instance will be created. + */ abstract fun getInstance(player: Player): GUIInstance + + /** + * Returns all active instances of this GUI. + */ + abstract fun getAllInstances(): Collection> + + /** + * Closes this GUI for all viewers and unregisters + * all instances. + */ + abstract fun closeGUI() + + protected fun unregisterAndClose() { + getAllInstances().forEach { + it.bukkitInventory.closeForViewers() + it.unregister() + } + } + } class GUIShared( guiData: GUIData ) : GUI(guiData) { - val singleInstance by lazy { GUIInstance(this, null).apply { register() } } + private var _singleInstance: GUIInstance? = null + val singleInstance + get() = _singleInstance ?: GUIInstance(this, null).apply { + _singleInstance = this + register() + } override fun getInstance(player: Player) = singleInstance + override fun getAllInstances() = _singleInstance?.let { listOf(it) } ?: emptyList() + + override fun closeGUI() { + unregisterAndClose() + _singleInstance = null + } + } class GUIIndividual( guiData: GUIData, - val resetOnClose: Boolean + resetOnClose: Boolean, + resetOnQuit: Boolean ) : GUI(guiData) { private val playerInstances = HashMap>() @@ -47,9 +86,34 @@ class GUIIndividual( override fun getInstance(player: Player) = playerInstances[player] ?: createInstance(player) + override fun getAllInstances() = playerInstances.values + private fun createInstance(player: Player) = GUIInstance(this, player).apply { playerInstances[player] = this } + fun deleteInstance(player: Player) = playerInstances.remove(player)?.unregister() + + override fun closeGUI() { + unregisterAndClose() + playerInstances.clear() + } + + init { + + if (resetOnClose) { + listen { + deleteInstance(it.player as? Player ?: return@listen) + } + } + + if (resetOnQuit) { + listen { + deleteInstance(it.player) + } + } + + } + } class GUIInstance( diff --git a/src/main/kotlin/net/axay/kspigot/gui/GUICreator.kt b/src/main/kotlin/net/axay/kspigot/gui/GUICreator.kt index b3438fb9..8d449f4e 100644 --- a/src/main/kotlin/net/axay/kspigot/gui/GUICreator.kt +++ b/src/main/kotlin/net/axay/kspigot/gui/GUICreator.kt @@ -9,7 +9,8 @@ class SharedGUICreator : GUICreator() { } class IndividualGUICreator( - private val resetOnClose: Boolean + private val resetOnClose: Boolean, + private val resetOnQuit: Boolean ) : GUICreator() { - override fun createInstance(guiData: GUIData) = GUIIndividual(guiData, resetOnClose) + override fun createInstance(guiData: GUIData) = GUIIndividual(guiData, resetOnClose, resetOnQuit) } \ No newline at end of file diff --git a/src/main/kotlin/net/axay/kspigot/gui/GUIHolder.kt b/src/main/kotlin/net/axay/kspigot/gui/GUIHolder.kt index 83eafc36..681bf53b 100644 --- a/src/main/kotlin/net/axay/kspigot/gui/GUIHolder.kt +++ b/src/main/kotlin/net/axay/kspigot/gui/GUIHolder.kt @@ -1,20 +1,22 @@ package net.axay.kspigot.gui import net.axay.kspigot.event.listen +import net.axay.kspigot.extensions.bukkit.closeForViewers import org.bukkit.entity.Player import org.bukkit.event.inventory.InventoryAction import org.bukkit.event.inventory.InventoryClickEvent +import org.bukkit.inventory.Inventory object GUIHolder : AutoCloseable { - private val registered = HashSet>() + private val registered = HashMap>() fun register(guiInstance: GUIInstance) { - registered.add(guiInstance) + registered[guiInstance.bukkitInventory] = guiInstance } fun unregister(guiInstance: GUIInstance) { - registered.remove(guiInstance) + registered -= guiInstance.bukkitInventory } init { @@ -23,7 +25,7 @@ object GUIHolder : AutoCloseable { val clickedInv = it.clickedInventory ?: return@listen - val inv = registered.find { search -> search.isThisInv(clickedInv) } ?: return@listen + val inv = registered[clickedInv] ?: return@listen val player = it.whoClicked as? Player ?: kotlin.run { it.isCancelled = true @@ -46,7 +48,7 @@ object GUIHolder : AutoCloseable { } override fun close() { - registered.forEach { inv -> inv.bukkitInventory.viewers.forEach { it.closeInventory() } } + registered.keys.forEach { it.closeForViewers() } registered.clear() }