94 lines
3.0 KiB
Java
94 lines
3.0 KiB
Java
/*
|
|
* Copyright (C) filoghost and contributors
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*/
|
|
package me.filoghost.holographicdisplays.core.listener;
|
|
|
|
import me.filoghost.holographicdisplays.core.tracking.ClickableLineTracker;
|
|
import me.filoghost.holographicdisplays.nms.common.EntityID;
|
|
import me.filoghost.holographicdisplays.nms.common.PacketListener;
|
|
import org.bukkit.entity.Player;
|
|
|
|
import java.util.Collections;
|
|
import java.util.Set;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
import java.util.concurrent.ConcurrentMap;
|
|
|
|
public class LineClickListener implements PacketListener {
|
|
|
|
private final ConcurrentMap<Integer, ClickableLineTracker<?>> lineTrackerByEntityID;
|
|
|
|
// It is necessary to queue async click events to process them from the main thread.
|
|
// Use a set to avoid duplicate click events to the same line.
|
|
private final Set<QueuedClickEvent> queuedClickEvents;
|
|
|
|
public LineClickListener() {
|
|
lineTrackerByEntityID = new ConcurrentHashMap<>();
|
|
queuedClickEvents = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
|
}
|
|
|
|
@Override
|
|
public boolean onAsyncEntityInteract(Player player, int entityID) {
|
|
ClickableLineTracker<?> lineTracker = lineTrackerByEntityID.get(entityID);
|
|
if (lineTracker != null) {
|
|
queuedClickEvents.add(new QueuedClickEvent(player, lineTracker));
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// This method is called from the main thread
|
|
public void processQueuedClickEvents() {
|
|
for (QueuedClickEvent event : queuedClickEvents) {
|
|
event.lineTracker.onClientClick(event.player);
|
|
}
|
|
queuedClickEvents.clear();
|
|
}
|
|
|
|
public void addLineTracker(EntityID clickableEntityID, ClickableLineTracker<?> lineTracker) {
|
|
lineTrackerByEntityID.put(clickableEntityID.getNumericID(), lineTracker);
|
|
}
|
|
|
|
public void removeLineTracker(EntityID clickableEntityID) {
|
|
if (clickableEntityID.hasInitializedNumericID()) {
|
|
lineTrackerByEntityID.remove(clickableEntityID.getNumericID());
|
|
}
|
|
}
|
|
|
|
|
|
private static class QueuedClickEvent {
|
|
|
|
private final Player player;
|
|
private final ClickableLineTracker<?> lineTracker;
|
|
|
|
QueuedClickEvent(Player player, ClickableLineTracker<?> lineTracker) {
|
|
this.player = player;
|
|
this.lineTracker = lineTracker;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object obj) {
|
|
if (this == obj) {
|
|
return true;
|
|
}
|
|
if (obj == null || getClass() != obj.getClass()) {
|
|
return false;
|
|
}
|
|
|
|
QueuedClickEvent other = (QueuedClickEvent) obj;
|
|
return this.player.equals(other.player) && this.lineTracker.equals(other.lineTracker);
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
int result = player.hashCode();
|
|
result = 31 * result + lineTracker.hashCode();
|
|
return result;
|
|
}
|
|
|
|
}
|
|
|
|
}
|