Added unregister functionality
This commit is contained in:
@@ -2,14 +2,16 @@
|
|||||||
|
|
||||||
package net.axay.kspigot.gui
|
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.entity.Player
|
||||||
|
import org.bukkit.event.inventory.InventoryCloseEvent
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent
|
||||||
import org.bukkit.inventory.Inventory
|
import org.bukkit.inventory.Inventory
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.HashSet
|
import kotlin.collections.HashSet
|
||||||
|
|
||||||
// TODO unregister in all layers
|
|
||||||
|
|
||||||
private const val DEFAULT_PAGE = 1
|
private const val DEFAULT_PAGE = 1
|
||||||
|
|
||||||
class GUIData<T : ForInventory>(
|
class GUIData<T : ForInventory>(
|
||||||
@@ -24,22 +26,59 @@ class GUIData<T : ForInventory>(
|
|||||||
abstract class GUI<T : ForInventory>(
|
abstract class GUI<T : ForInventory>(
|
||||||
val data: GUIData<T>
|
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>
|
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>(
|
class GUIShared<T : ForInventory>(
|
||||||
guiData: GUIData<T>
|
guiData: GUIData<T>
|
||||||
) : GUI<T>(guiData) {
|
) : 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 getInstance(player: Player) = singleInstance
|
||||||
|
|
||||||
|
override fun getAllInstances() = _singleInstance?.let { listOf(it) } ?: emptyList()
|
||||||
|
|
||||||
|
override fun closeGUI() {
|
||||||
|
unregisterAndClose()
|
||||||
|
_singleInstance = null
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class GUIIndividual<T : ForInventory>(
|
class GUIIndividual<T : ForInventory>(
|
||||||
guiData: GUIData<T>,
|
guiData: GUIData<T>,
|
||||||
val resetOnClose: Boolean
|
resetOnClose: Boolean,
|
||||||
|
resetOnQuit: Boolean
|
||||||
) : GUI<T>(guiData) {
|
) : GUI<T>(guiData) {
|
||||||
|
|
||||||
private val playerInstances = HashMap<Player, GUIInstance<T>>()
|
private val playerInstances = HashMap<Player, GUIInstance<T>>()
|
||||||
@@ -47,9 +86,34 @@ class GUIIndividual<T : ForInventory>(
|
|||||||
override fun getInstance(player: Player) =
|
override fun getInstance(player: Player) =
|
||||||
playerInstances[player] ?: createInstance(player)
|
playerInstances[player] ?: createInstance(player)
|
||||||
|
|
||||||
|
override fun getAllInstances() = playerInstances.values
|
||||||
|
|
||||||
private fun createInstance(player: Player) =
|
private fun createInstance(player: Player) =
|
||||||
GUIInstance(this, player).apply { playerInstances[player] = this }
|
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>(
|
class GUIInstance<T : ForInventory>(
|
||||||
|
@@ -9,7 +9,8 @@ class SharedGUICreator<T : ForInventory> : GUICreator<T>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class IndividualGUICreator<T : ForInventory>(
|
class IndividualGUICreator<T : ForInventory>(
|
||||||
private val resetOnClose: Boolean
|
private val resetOnClose: Boolean,
|
||||||
|
private val resetOnQuit: Boolean
|
||||||
) : GUICreator<T>() {
|
) : GUICreator<T>() {
|
||||||
override fun createInstance(guiData: GUIData<T>) = GUIIndividual(guiData, resetOnClose)
|
override fun createInstance(guiData: GUIData<T>) = GUIIndividual(guiData, resetOnClose, resetOnQuit)
|
||||||
}
|
}
|
@@ -1,20 +1,22 @@
|
|||||||
package net.axay.kspigot.gui
|
package net.axay.kspigot.gui
|
||||||
|
|
||||||
import net.axay.kspigot.event.listen
|
import net.axay.kspigot.event.listen
|
||||||
|
import net.axay.kspigot.extensions.bukkit.closeForViewers
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.event.inventory.InventoryAction
|
import org.bukkit.event.inventory.InventoryAction
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
import org.bukkit.inventory.Inventory
|
||||||
|
|
||||||
object GUIHolder : AutoCloseable {
|
object GUIHolder : AutoCloseable {
|
||||||
|
|
||||||
private val registered = HashSet<GUIInstance<ForInventory>>()
|
private val registered = HashMap<Inventory, GUIInstance<ForInventory>>()
|
||||||
|
|
||||||
fun register(guiInstance: GUIInstance<ForInventory>) {
|
fun register(guiInstance: GUIInstance<ForInventory>) {
|
||||||
registered.add(guiInstance)
|
registered[guiInstance.bukkitInventory] = guiInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unregister(guiInstance: GUIInstance<ForInventory>) {
|
fun unregister(guiInstance: GUIInstance<ForInventory>) {
|
||||||
registered.remove(guiInstance)
|
registered -= guiInstance.bukkitInventory
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -23,7 +25,7 @@ object GUIHolder : AutoCloseable {
|
|||||||
|
|
||||||
val clickedInv = it.clickedInventory ?: return@listen
|
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 {
|
val player = it.whoClicked as? Player ?: kotlin.run {
|
||||||
it.isCancelled = true
|
it.isCancelled = true
|
||||||
@@ -46,7 +48,7 @@ object GUIHolder : AutoCloseable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
registered.forEach { inv -> inv.bukkitInventory.viewers.forEach { it.closeInventory() } }
|
registered.keys.forEach { it.closeForViewers() }
|
||||||
registered.clear()
|
registered.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user