Refactoring

This commit is contained in:
filoghost 2022-12-04 11:58:41 +01:00
parent 2f83fdcfdb
commit 850beaebb8
17 changed files with 115 additions and 118 deletions

View File

@ -31,7 +31,7 @@ class APIHologram extends BaseHologram implements Hologram {
LineTrackerManager lineTrackerManager) {
super(position, lineTrackerManager);
Preconditions.notNull(plugin, "plugin");
this.lines = new APIHologramLines(this);
this.lines = new APIHologramLines(this, lineTrackerManager);
this.plugin = plugin;
this.hologramManager = hologramManager;
this.placeholderSetting = PlaceholderSetting.DEFAULT;

View File

@ -11,6 +11,7 @@ import me.filoghost.holographicdisplays.api.hologram.line.HologramLine;
import me.filoghost.holographicdisplays.api.hologram.line.ItemHologramLine;
import me.filoghost.holographicdisplays.api.hologram.line.TextHologramLine;
import me.filoghost.holographicdisplays.core.base.BaseHologramLines;
import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -19,8 +20,8 @@ class APIHologramLines extends BaseHologramLines<APIHologramLine> implements Hol
private final APIHologram hologram;
APIHologramLines(APIHologram hologram) {
super(hologram);
APIHologramLines(APIHologram hologram, LineTrackerManager lineTrackerManager) {
super(hologram, lineTrackerManager);
this.hologram = hologram;
}

View File

@ -43,7 +43,7 @@ class APIItemHologramLine extends BaseItemHologramLine implements ItemHologramLi
}
@Override
protected void invokePickupCallback(Player player) {
protected void invokeExternalPickupCallback(Player player) {
if (pickupListener != null) {
pickupListener.onPickup(new SimpleHologramLinePickupEvent(player));
}
@ -70,7 +70,7 @@ class APIItemHologramLine extends BaseItemHologramLine implements ItemHologramLi
}
@Override
protected void invokeClickCallback(Player player) {
protected void invokeExternalClickCallback(Player player) {
if (clickListener != null) {
clickListener.onClick(new SimpleHologramLineClickEvent(player));
}

View File

@ -49,7 +49,7 @@ class APITextHologramLine extends BaseTextHologramLine implements TextHologramLi
}
@Override
protected void invokeClickCallback(Player player) {
protected void invokeExternalClickCallback(Player player) {
if (clickListener != null) {
clickListener.onClick(new SimpleHologramLineClickEvent(player));
}

View File

@ -37,7 +37,7 @@ class V2Hologram extends BaseHologram implements Hologram {
super(position, lineTrackerManager);
this.plugin = plugin;
this.hologramManager = hologramManager;
this.lines = new BaseHologramLines<>(this);
this.lines = new BaseHologramLines<>(this, lineTrackerManager);
this.visibilityManager = new V2VisibilityManager(getVisibilitySettings());
this.creationTimestamp = System.currentTimeMillis();
}

View File

@ -46,7 +46,7 @@ class V2ItemLine extends BaseItemHologramLine implements ItemLine, V2HologramLin
}
@Override
protected void invokeClickCallback(Player player) {
protected void invokeExternalClickCallback(Player player) {
if (touchHandler != null) {
touchHandler.onTouch(player);
}
@ -68,7 +68,7 @@ class V2ItemLine extends BaseItemHologramLine implements ItemLine, V2HologramLin
}
@Override
protected void invokePickupCallback(Player player) {
protected void invokeExternalPickupCallback(Player player) {
if (pickupHandler != null) {
pickupHandler.onPickup(player);
}

View File

@ -48,7 +48,7 @@ class V2TextLine extends BaseTextHologramLine implements TextLine, V2HologramLin
}
@Override
protected void invokeClickCallback(Player player) {
protected void invokeExternalClickCallback(Player player) {
if (touchHandler != null) {
touchHandler.onTouch(player);
}

View File

@ -6,8 +6,6 @@
package me.filoghost.holographicdisplays.core.base;
import me.filoghost.fcommons.logging.Log;
import me.filoghost.holographicdisplays.common.PositionCoordinates;
import org.bukkit.Location;
import org.bukkit.entity.Player;
public abstract class BaseClickableHologramLine extends BaseHologramLine {
@ -17,30 +15,16 @@ public abstract class BaseClickableHologramLine extends BaseHologramLine {
}
public void onClick(Player player) {
if (hasClickCallback() && canInteract(player) && isInClickRange(player)) {
try {
invokeClickCallback(player);
} catch (Throwable t) {
Log.warning("The plugin " + getCreatorPlugin().getName() + " generated an exception"
+ " when the player " + player.getName() + " clicked a hologram.", t);
}
try {
invokeExternalClickCallback(player);
} catch (Throwable t) {
Log.warning("The plugin " + getCreatorPlugin().getName() + " generated an exception"
+ " when the player " + player.getName() + " clicked a hologram.", t);
}
}
public abstract boolean hasClickCallback();
protected abstract void invokeClickCallback(Player player);
private boolean isInClickRange(Player player) {
Location playerLocation = player.getLocation();
PositionCoordinates positionCoordinates = this.getCoordinates();
double xDiff = playerLocation.getX() - positionCoordinates.getX();
double yDiff = playerLocation.getY() + 1.3 - positionCoordinates.getY(); // Use shoulder height
double zDiff = playerLocation.getZ() - positionCoordinates.getZ();
double distanceSquared = (xDiff * xDiff) + (yDiff * yDiff) + (zDiff * zDiff);
return distanceSquared < 5 * 5;
}
protected abstract void invokeExternalClickCallback(Player player);
}

View File

@ -8,9 +8,6 @@ package me.filoghost.holographicdisplays.core.base;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.holographicdisplays.common.PositionCoordinates;
import me.filoghost.holographicdisplays.core.api.current.DefaultVisibilitySettings;
import me.filoghost.holographicdisplays.core.tracking.LineTracker;
import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager;
import org.bukkit.GameMode;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
@ -20,24 +17,30 @@ import org.jetbrains.annotations.Nullable;
public abstract class BaseHologramLine extends BaseHologramComponent implements EditableHologramLine {
private final BaseHologram hologram;
private final LineTracker<?> tracker;
private PositionCoordinates coordinates;
/**
* Flag to indicate that the line has changed in some way and update packets might be necessary.
*/
private boolean changed;
protected BaseHologramLine(BaseHologram hologram) {
Preconditions.notNull(hologram, "hologram");
this.hologram = hologram;
this.tracker = createTracker(hologram.getTrackerManager());
setChanged(); // Force the initial refresh
}
protected abstract LineTracker<?> createTracker(LineTrackerManager trackerManager);
public boolean hasChanged() {
return changed;
}
public final void setChanged() {
tracker.setLineChanged();
changed = true;
}
protected final boolean isViewer(Player player) {
return tracker.isViewer(player);
public void clearChanged() {
changed = false;
}
@Override
@ -77,12 +80,4 @@ public abstract class BaseHologramLine extends BaseHologramComponent implements
return hologram.getVisibilitySettings();
}
protected boolean canInteract(Player player) {
return !isDeleted()
&& player.isOnline()
&& player.getGameMode() != GameMode.SPECTATOR
&& isViewer(player)
&& isVisibleTo(player);
}
}

View File

@ -8,6 +8,7 @@ package me.filoghost.holographicdisplays.core.base;
import me.filoghost.holographicdisplays.api.Position;
import me.filoghost.holographicdisplays.core.CoreGlobalConfig;
import me.filoghost.holographicdisplays.core.CorePreconditions;
import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@ -18,11 +19,13 @@ import java.util.List;
public class BaseHologramLines<T extends EditableHologramLine> implements Iterable<T> {
private final BaseHologram hologram;
private final LineTrackerManager lineTrackerManager;
private final List<T> lines;
private final List<T> unmodifiableLinesView;
public BaseHologramLines(BaseHologram hologram) {
public BaseHologramLines(BaseHologram hologram, LineTrackerManager lineTrackerManager) {
this.hologram = hologram;
this.lineTrackerManager = lineTrackerManager;
this.lines = new ArrayList<>();
this.unmodifiableLinesView = Collections.unmodifiableList(lines);
}
@ -48,6 +51,7 @@ public class BaseHologramLines<T extends EditableHologramLine> implements Iterab
checkNotDeleted();
lines.add(line);
lineTrackerManager.startTracking(line);
updatePositions();
}
@ -56,6 +60,7 @@ public class BaseHologramLines<T extends EditableHologramLine> implements Iterab
checkNotDeleted();
lines.add(beforeIndex, line);
lineTrackerManager.startTracking(line);
updatePositions();
}

View File

@ -9,8 +9,6 @@ import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.logging.Log;
import me.filoghost.holographicdisplays.core.CorePreconditions;
import me.filoghost.holographicdisplays.nms.common.entity.ItemNMSPacketEntity;
import me.filoghost.holographicdisplays.core.tracking.ItemLineTracker;
import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
@ -24,25 +22,18 @@ public abstract class BaseItemHologramLine extends BaseClickableHologramLine {
setItemStack(itemStack);
}
@Override
public ItemLineTracker createTracker(LineTrackerManager trackerManager) {
return trackerManager.startTracking(this);
}
public void onPickup(Player player) {
if (hasPickupCallback() && canInteract(player)) {
try {
invokePickupCallback(player);
} catch (Throwable t) {
Log.warning("The plugin " + getCreatorPlugin().getName() + " generated an exception"
+ " when the player " + player.getName() + " picked up an item from a hologram.", t);
}
try {
invokeExternalPickupCallback(player);
} catch (Throwable t) {
Log.warning("The plugin " + getCreatorPlugin().getName() + " generated an exception"
+ " when the player " + player.getName() + " picked up an item from a hologram.", t);
}
}
public abstract boolean hasPickupCallback();
protected abstract void invokePickupCallback(Player player);
protected abstract void invokeExternalPickupCallback(Player player);
public @Nullable ItemStack getItemStack() {
return clone(itemStack);

View File

@ -7,8 +7,6 @@ package me.filoghost.holographicdisplays.core.base;
import me.filoghost.holographicdisplays.core.CorePreconditions;
import me.filoghost.holographicdisplays.nms.common.entity.TextNMSPacketEntity;
import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager;
import me.filoghost.holographicdisplays.core.tracking.TextLineTracker;
import org.jetbrains.annotations.Nullable;
public abstract class BaseTextHologramLine extends BaseClickableHologramLine {
@ -22,11 +20,6 @@ public abstract class BaseTextHologramLine extends BaseClickableHologramLine {
public abstract boolean isAllowPlaceholders();
@Override
protected TextLineTracker createTracker(LineTrackerManager trackerManager) {
return trackerManager.startTracking(this);
}
public @Nullable String getText() {
return text;
}

View File

@ -5,9 +5,9 @@
*/
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 me.filoghost.holographicdisplays.core.base.BaseClickableHologramLine;
import org.bukkit.entity.Player;
import java.util.Collections;
@ -17,22 +17,22 @@ import java.util.concurrent.ConcurrentMap;
public class LineClickListener implements PacketListener {
private final ConcurrentMap<Integer, BaseClickableHologramLine> linesByEntityID;
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() {
linesByEntityID = new ConcurrentHashMap<>();
lineTrackerByEntityID = new ConcurrentHashMap<>();
queuedClickEvents = Collections.newSetFromMap(new ConcurrentHashMap<>());
}
@Override
public boolean onAsyncEntityInteract(Player player, int entityID) {
BaseClickableHologramLine line = linesByEntityID.get(entityID);
if (line != null) {
queuedClickEvents.add(new QueuedClickEvent(player, line));
ClickableLineTracker<?> lineTracker = lineTrackerByEntityID.get(entityID);
if (lineTracker != null) {
queuedClickEvents.add(new QueuedClickEvent(player, lineTracker));
return true;
} else {
return false;
@ -41,19 +41,19 @@ public class LineClickListener implements PacketListener {
// This method is called from the main thread
public void processQueuedClickEvents() {
for (QueuedClickEvent queuedClickEvent : queuedClickEvents) {
queuedClickEvent.line.onClick(queuedClickEvent.player);
for (QueuedClickEvent event : queuedClickEvents) {
event.lineTracker.onClientClick(event.player);
}
queuedClickEvents.clear();
}
public void registerLine(EntityID clickableEntityID, BaseClickableHologramLine line) {
linesByEntityID.put(clickableEntityID.getNumericID(), line);
public void addLineTracker(EntityID clickableEntityID, ClickableLineTracker<?> lineTracker) {
lineTrackerByEntityID.put(clickableEntityID.getNumericID(), lineTracker);
}
public void unregisterLine(EntityID clickableEntityID) {
public void removeLineTracker(EntityID clickableEntityID) {
if (clickableEntityID.hasInitializedNumericID()) {
linesByEntityID.remove(clickableEntityID.getNumericID());
lineTrackerByEntityID.remove(clickableEntityID.getNumericID());
}
}
@ -61,11 +61,11 @@ public class LineClickListener implements PacketListener {
private static class QueuedClickEvent {
private final Player player;
private final BaseClickableHologramLine line;
private final ClickableLineTracker<?> lineTracker;
QueuedClickEvent(Player player, BaseClickableHologramLine line) {
QueuedClickEvent(Player player, ClickableLineTracker<?> lineTracker) {
this.player = player;
this.line = line;
this.lineTracker = lineTracker;
}
@Override
@ -78,13 +78,13 @@ public class LineClickListener implements PacketListener {
}
QueuedClickEvent other = (QueuedClickEvent) obj;
return this.player.equals(other.player) && this.line.equals(other.line);
return this.player.equals(other.player) && this.lineTracker.equals(other.lineTracker);
}
@Override
public int hashCode() {
int result = player.hashCode();
result = 31 * result + line.hashCode();
result = 31 * result + lineTracker.hashCode();
return result;
}

View File

@ -10,6 +10,8 @@ import me.filoghost.holographicdisplays.core.base.BaseClickableHologramLine;
import me.filoghost.holographicdisplays.core.listener.LineClickListener;
import me.filoghost.holographicdisplays.nms.common.NMSManager;
import me.filoghost.holographicdisplays.nms.common.entity.ClickableNMSPacketEntity;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.MustBeInvokedByOverriders;
public abstract class ClickableLineTracker<T extends Viewer> extends LineTracker<T> {
@ -27,14 +29,32 @@ public abstract class ClickableLineTracker<T extends Viewer> extends LineTracker
this.lineClickListener = lineClickListener;
}
public void onClientClick(Player player) {
if (getLine().hasClickCallback() && canInteract(player) && isInClickRange(player)) {
getLine().onClick(player);
}
}
private boolean isInClickRange(Player player) {
Location playerLocation = player.getLocation();
PositionCoordinates positionCoordinates = getLine().getCoordinates();
double xDiff = playerLocation.getX() - positionCoordinates.getX();
double yDiff = playerLocation.getY() + 1.3 - positionCoordinates.getY(); // Use shoulder height
double zDiff = playerLocation.getZ() - positionCoordinates.getZ();
double distanceSquared = (xDiff * xDiff) + (yDiff * yDiff) + (zDiff * zDiff);
return distanceSquared < 5 * 5;
}
@Override
protected abstract BaseClickableHologramLine getLine();
public abstract BaseClickableHologramLine getLine();
@MustBeInvokedByOverriders
@Override
public void onRemoval() {
super.onRemoval();
lineClickListener.unregisterLine(clickableEntity.getID());
lineClickListener.removeLineTracker(clickableEntity.getID());
}
@MustBeInvokedByOverriders
@ -47,9 +67,9 @@ public abstract class ClickableLineTracker<T extends Viewer> extends LineTracker
this.spawnClickableEntity = spawnClickableEntity;
this.spawnClickableEntityChanged = true;
if (spawnClickableEntity) {
lineClickListener.registerLine(clickableEntity.getID(), getLine());
lineClickListener.addLineTracker(clickableEntity.getID(), this);
} else {
lineClickListener.unregisterLine(clickableEntity.getID());
lineClickListener.removeLineTracker(clickableEntity.getID());
}
}
}

View File

@ -10,6 +10,8 @@ import me.filoghost.holographicdisplays.core.listener.LineClickListener;
import me.filoghost.holographicdisplays.core.tick.CachedPlayer;
import me.filoghost.holographicdisplays.nms.common.NMSManager;
import me.filoghost.holographicdisplays.nms.common.entity.ItemNMSPacketEntity;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.MustBeInvokedByOverriders;
@ -48,13 +50,20 @@ public class ItemLineTracker extends ClickableLineTracker<Viewer> {
if (spawnItemEntity && hasViewers() && line.hasPickupCallback()) {
for (Viewer viewer : getViewers()) {
if (viewer.getLocation() != null && CollisionHelper.isInPickupRange(viewer.getLocation(), positionCoordinates)) {
line.onPickup(viewer.getBukkitPlayer());
}
invokePickupIfNecessary(viewer);
}
}
}
private void invokePickupIfNecessary(Viewer viewer) {
Location location = viewer.getLocation();
Player player = viewer.getBukkitPlayer();
if (location != null && CollisionHelper.isInPickupRange(location, positionCoordinates) && canInteract(player)) {
line.onPickup(player);
}
}
@Override
protected boolean updatePlaceholders() {
return false;

View File

@ -8,6 +8,7 @@ package me.filoghost.holographicdisplays.core.tracking;
import me.filoghost.holographicdisplays.common.PositionCoordinates;
import me.filoghost.holographicdisplays.core.base.BaseHologramLine;
import me.filoghost.holographicdisplays.core.tick.CachedPlayer;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.MustBeInvokedByOverriders;
@ -27,17 +28,12 @@ public abstract class LineTracker<T extends Viewer> {
protected PositionCoordinates positionCoordinates;
private boolean positionChanged;
/**
* Flag to indicate that the line has changed in some way and there could be the need to send update packets.
*/
private boolean lineChanged;
private boolean inLoadedChunk;
private int lastVisibilitySettingsVersion;
protected LineTracker() {
this.viewers = new HashMap<>();
this.iterableViewers = new DelegateViewers<>(viewers.values());
setLineChanged(); // Force the initial refresh
}
protected abstract BaseHologramLine getLine();
@ -51,17 +47,13 @@ public abstract class LineTracker<T extends Viewer> {
resetViewersAndSendDestroyPackets();
}
public final void setLineChanged() {
lineChanged = true;
}
@MustBeInvokedByOverriders
protected void update(List<CachedPlayer> onlinePlayers, List<CachedPlayer> movedPlayers, int maxViewRange) {
boolean sendChangesPackets = false;
// First, detect the changes if the flag is on and set it off
if (lineChanged) {
lineChanged = false;
if (getLine().hasChanged()) {
getLine().clearChanged();
detectChanges();
sendChangesPackets = true;
}
@ -190,7 +182,7 @@ public abstract class LineTracker<T extends Viewer> {
return viewers.values();
}
public final boolean isViewer(Player player) {
protected final boolean isViewer(Player player) {
return viewers.containsKey(player);
}
@ -198,6 +190,14 @@ public abstract class LineTracker<T extends Viewer> {
viewers.remove(player);
}
protected boolean canInteract(Player player) {
return !getLine().isDeleted()
&& player.isOnline()
&& player.getGameMode() != GameMode.SPECTATOR
&& isViewer(player)
&& getLine().isVisibleTo(player);
}
@MustBeInvokedByOverriders
protected void detectChanges() {
PositionCoordinates positionCoordinates = getLine().getCoordinates();

View File

@ -7,6 +7,7 @@ package me.filoghost.holographicdisplays.core.tracking;
import me.filoghost.holographicdisplays.core.base.BaseItemHologramLine;
import me.filoghost.holographicdisplays.core.base.BaseTextHologramLine;
import me.filoghost.holographicdisplays.core.base.EditableHologramLine;
import me.filoghost.holographicdisplays.core.listener.LineClickListener;
import me.filoghost.holographicdisplays.core.placeholder.tracking.ActivePlaceholderTracker;
import me.filoghost.holographicdisplays.core.tick.CachedPlayer;
@ -35,16 +36,14 @@ public class LineTrackerManager {
this.lineTrackers = new LinkedList<>();
}
public TextLineTracker startTracking(BaseTextHologramLine line) {
TextLineTracker tracker = new TextLineTracker(line, nmsManager, lineClickListener, placeholderTracker);
lineTrackers.add(tracker);
return tracker;
}
public ItemLineTracker startTracking(BaseItemHologramLine line) {
ItemLineTracker tracker = new ItemLineTracker(line, nmsManager, lineClickListener);
lineTrackers.add(tracker);
return tracker;
public <T extends EditableHologramLine> void startTracking(T line) {
if (line instanceof BaseTextHologramLine) {
lineTrackers.add(new TextLineTracker((BaseTextHologramLine) line, nmsManager, lineClickListener, placeholderTracker));
} else if (line instanceof BaseItemHologramLine) {
lineTrackers.add(new ItemLineTracker((BaseItemHologramLine) line, nmsManager, lineClickListener));
} else {
throw new UnsupportedOperationException("unsupported line class: " + line.getClass().getName());
}
}
public void update(List<CachedPlayer> onlinePlayers, List<CachedPlayer> movedPlayers, int maxViewRange) {