package net.hareworks.ghostdisplays.internal.controller import java.util.UUID import java.util.concurrent.ConcurrentHashMap import net.hareworks.ghostdisplays.api.click.ClickSurface import org.bukkit.entity.Display import org.bukkit.entity.Entity import org.bukkit.entity.Interaction import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.player.PlayerChangedWorldEvent import org.bukkit.event.player.PlayerInteractEntityEvent import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerQuitEvent import org.bukkit.event.player.PlayerRespawnEvent internal class DisplayRegistry : Listener { private val displayControllers = ConcurrentHashMap>() private val interactionControllers = ConcurrentHashMap>() fun register(controller: BaseDisplayController) { displayControllers[controller.display.uniqueId] = controller controller.interaction?.let { interactionControllers[it.uniqueId] = controller } } fun unregister(controller: BaseDisplayController) { displayControllers.remove(controller.display.uniqueId, controller) controller.interaction?.let { interactionControllers.remove(it.uniqueId, controller) } } fun controllerCount(): Int = displayControllers.size fun shutdown() { displayControllers.clear() interactionControllers.clear() } @EventHandler fun onPlayerInteractEntity(event: PlayerInteractEntityEvent) { val entity = event.rightClicked val controller = lookupController(entity) ?: return val surface = if (entity is Interaction) ClickSurface.INTERACTION else ClickSurface.DISPLAY controller.handleClick(event, entity, surface) } @EventHandler fun onPlayerQuit(event: PlayerQuitEvent) { controllersSnapshot().forEach { it.handlePlayerQuit(event.player) } } @EventHandler fun onPlayerJoin(event: PlayerJoinEvent) { refreshAudiences(event.player) } @EventHandler fun onPlayerChangedWorld(event: PlayerChangedWorldEvent) { refreshAudiences(event.player) } @EventHandler fun onPlayerRespawn(event: PlayerRespawnEvent) { refreshAudiences(event.player) } private fun lookupController(entity: Entity): BaseDisplayController? { return displayControllers[entity.uniqueId] ?: interactionControllers[entity.uniqueId] } private fun controllersSnapshot(): Collection> = displayControllers.values.toSet() private fun refreshAudiences(player: Player) { val controllers = controllersSnapshot() if (controllers.isEmpty()) return controllers.forEach { it.refreshAudience(player) } } }