Added unregister functionality

This commit is contained in:
bluefireoly
2020-10-25 11:50:33 +01:00
parent 6db78d08f4
commit b43e17360f
3 changed files with 78 additions and 11 deletions

View File

@@ -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<T : ForInventory>(
@@ -24,22 +26,59 @@ class GUIData<T : ForInventory>(
abstract class GUI<T : ForInventory>(
val data: GUIData<T>
) {
/**
* Returns the instance beloning to the given player.
* If not existing, a new instance will be created.
*/
abstract fun getInstance(player: Player): GUIInstance<T>
/**
* Returns all active instances of this GUI.
*/
abstract fun getAllInstances(): Collection<GUIInstance<T>>
/**
* 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<T : ForInventory>(
guiData: GUIData<T>
) : GUI<T>(guiData) {
val singleInstance by lazy { GUIInstance(this, null).apply { register() } }
private var _singleInstance: GUIInstance<T>? = 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<T : ForInventory>(
guiData: GUIData<T>,
val resetOnClose: Boolean
resetOnClose: Boolean,
resetOnQuit: Boolean
) : GUI<T>(guiData) {
private val playerInstances = HashMap<Player, GUIInstance<T>>()
@@ -47,9 +86,34 @@ class GUIIndividual<T : ForInventory>(
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<InventoryCloseEvent> {
deleteInstance(it.player as? Player ?: return@listen)
}
}
if (resetOnQuit) {
listen<PlayerQuitEvent> {
deleteInstance(it.player)
}
}
}
}
class GUIInstance<T : ForInventory>(

View File

@@ -9,7 +9,8 @@ class SharedGUICreator<T : ForInventory> : GUICreator<T>() {
}
class IndividualGUICreator<T : ForInventory>(
private val resetOnClose: Boolean
private val resetOnClose: Boolean,
private val resetOnQuit: Boolean
) : GUICreator<T>() {
override fun createInstance(guiData: GUIData<T>) = GUIIndividual(guiData, resetOnClose)
override fun createInstance(guiData: GUIData<T>) = GUIIndividual(guiData, resetOnClose, resetOnQuit)
}

View File

@@ -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<GUIInstance<ForInventory>>()
private val registered = HashMap<Inventory, GUIInstance<ForInventory>>()
fun register(guiInstance: GUIInstance<ForInventory>) {
registered.add(guiInstance)
registered[guiInstance.bukkitInventory] = guiInstance
}
fun unregister(guiInstance: GUIInstance<ForInventory>) {
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()
}