diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/HolographicDisplays.java b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/HolographicDisplays.java index 41747d67..4da2ac6b 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/HolographicDisplays.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/HolographicDisplays.java @@ -103,6 +103,7 @@ public class HolographicDisplays extends FCommonsPlugin { LineClickListener lineClickListener = new LineClickListener(); lineTrackerManager = new LineTrackerManager(nmsManager, placeholderTracker, lineClickListener); internalHologramManager = new InternalHologramManager(lineTrackerManager); + APIHologramManager apiHologramManager = new APIHologramManager(lineTrackerManager); // Run only once at startup, before loading the configuration try { @@ -129,7 +130,7 @@ public class HolographicDisplays extends FCommonsPlugin { // Listeners registerListener(new PlayerListener(nmsManager, lineTrackerManager, lineClickListener)); - registerListener(new ChunkListener(this, lineTrackerManager)); + registerListener(new ChunkListener(this, internalHologramManager, apiHologramManager)); UpdateNotificationListener updateNotificationListener = new UpdateNotificationListener(); registerListener(updateNotificationListener); @@ -139,7 +140,6 @@ public class HolographicDisplays extends FCommonsPlugin { updateNotificationListener.runAsyncUpdateCheck(this); // Enable the APIs - APIHologramManager apiHologramManager = new APIHologramManager(lineTrackerManager); HolographicDisplaysAPIProvider.setImplementation( new DefaultHolographicDisplaysAPIProvider(apiHologramManager, nmsManager, placeholderRegistry)); enableLegacyAPI(apiHologramManager, placeholderRegistry); diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/base/BaseHologram.java b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/base/BaseHologram.java index 896bd48f..d24acb38 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/base/BaseHologram.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/base/BaseHologram.java @@ -8,6 +8,8 @@ package me.filoghost.holographicdisplays.plugin.hologram.base; import me.filoghost.fcommons.Preconditions; import me.filoghost.holographicdisplays.plugin.config.Settings; import me.filoghost.holographicdisplays.plugin.hologram.tracking.LineTrackerManager; +import me.filoghost.holographicdisplays.plugin.util.CachedBoolean; +import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; @@ -24,6 +26,7 @@ public abstract class BaseHologram extends BaseH private final LineTrackerManager lineTrackerManager; private final List lines; private final List unmodifiableLinesView; + private final CachedBoolean isInLoadedChunk; public BaseHologram(Location location, LineTrackerManager lineTrackerManager) { Preconditions.notNull(location, "location"); @@ -31,6 +34,7 @@ public abstract class BaseHologram extends BaseH this.lineTrackerManager = lineTrackerManager; this.lines = new ArrayList<>(); this.unmodifiableLinesView = Collections.unmodifiableList(lines); + this.isInLoadedChunk = new CachedBoolean(() -> getWorld().isChunkLoaded(getChunkX(), getChunkZ())); } protected abstract boolean isVisibleTo(Player player); @@ -133,9 +137,26 @@ public abstract class BaseHologram extends BaseH Preconditions.notNull(world, "world"); setLocation(world, x, y, z); + this.isInLoadedChunk.invalidate(); updateLineLocations(); } + protected final void onChunkLoad(Chunk chunk) { + if (this.getWorld() == chunk.getWorld() && this.getChunkX() == chunk.getX() && this.getChunkZ() == chunk.getZ()) { + this.isInLoadedChunk.set(true); + } + } + + protected final void onChunkUnload(Chunk chunk) { + if (this.getWorld() == chunk.getWorld() && this.getChunkX() == chunk.getX() && this.getChunkZ() == chunk.getZ()) { + this.isInLoadedChunk.set(false); + } + } + + public boolean isInLoadedChunk() { + return isInLoadedChunk.get(); + } + /** * When spawning at a location, the top part of the first line should be exactly on that location. * The second line is below the first, and so on. diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/base/BaseHologramLine.java b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/base/BaseHologramLine.java index bdee1a0d..42ba8884 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/base/BaseHologramLine.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/base/BaseHologramLine.java @@ -56,4 +56,8 @@ public abstract class BaseHologramLine extends BaseHologramComponent implements && isVisibleTo(player); } + public boolean isInLoadedChunk() { + return hologram.isInLoadedChunk(); + } + } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/base/BaseHologramManager.java b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/base/BaseHologramManager.java index 590ee973..22af5938 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/base/BaseHologramManager.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/base/BaseHologramManager.java @@ -5,6 +5,8 @@ */ package me.filoghost.holographicdisplays.plugin.hologram.base; +import org.bukkit.Chunk; + import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; @@ -37,4 +39,16 @@ public abstract class BaseHologramManager> { } } + public void onChunkLoad(Chunk chunk) { + for (H hologram : holograms) { + hologram.onChunkLoad(chunk); + } + } + + public void onChunkUnload(Chunk chunk) { + for (H hologram : holograms) { + hologram.onChunkUnload(chunk); + } + } + } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/tracking/LineTracker.java b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/tracking/LineTracker.java index 38c3f3c4..035829ff 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/tracking/LineTracker.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/tracking/LineTracker.java @@ -8,7 +8,6 @@ package me.filoghost.holographicdisplays.plugin.hologram.tracking; import me.filoghost.holographicdisplays.common.nms.NMSManager; import me.filoghost.holographicdisplays.common.nms.NMSPacketList; import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramLine; -import org.bukkit.Chunk; import org.bukkit.entity.Player; import org.jetbrains.annotations.MustBeInvokedByOverriders; @@ -82,7 +81,7 @@ public abstract class LineTracker { protected abstract boolean updatePlaceholders(); private void updateTrackedPlayersAndSendPackets(Collection onlinePlayers) { - if (!isActive()) { + if (!line.isInLoadedChunk()) { clearTrackedPlayersAndSendPackets(); return; } @@ -112,8 +111,6 @@ public abstract class LineTracker { } } - protected abstract boolean isActive(); - protected abstract boolean shouldTrackPlayer(Player player); protected final boolean hasTrackedPlayers() { @@ -155,8 +152,4 @@ public abstract class LineTracker { protected abstract void addChangesPackets(NMSPacketList packetList); - protected abstract void onChunkLoad(Chunk chunk); - - protected abstract void onChunkUnload(Chunk chunk); - } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/tracking/LineTrackerManager.java b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/tracking/LineTrackerManager.java index b1e6061b..23d66ea0 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/tracking/LineTrackerManager.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/tracking/LineTrackerManager.java @@ -11,7 +11,6 @@ import me.filoghost.holographicdisplays.plugin.hologram.base.BaseTextLine; import me.filoghost.holographicdisplays.plugin.listener.LineClickListener; import me.filoghost.holographicdisplays.plugin.placeholder.tracking.PlaceholderTracker; import org.bukkit.Bukkit; -import org.bukkit.Chunk; import org.bukkit.entity.Player; import java.util.Collection; @@ -74,16 +73,4 @@ public class LineTrackerManager { } } - public void onChunkLoad(Chunk chunk) { - for (LineTracker tracker : lineTrackers) { - tracker.onChunkLoad(chunk); - } - } - - public void onChunkUnload(Chunk chunk) { - for (LineTracker tracker : lineTrackers) { - tracker.onChunkUnload(chunk); - } - } - } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/tracking/LocationBasedLineTracker.java b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/tracking/LocationBasedLineTracker.java index b859f2c8..a522ff23 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/tracking/LocationBasedLineTracker.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/hologram/tracking/LocationBasedLineTracker.java @@ -8,7 +8,6 @@ package me.filoghost.holographicdisplays.plugin.hologram.tracking; import me.filoghost.holographicdisplays.common.nms.NMSManager; import me.filoghost.holographicdisplays.common.nms.NMSPacketList; import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramLine; -import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; @@ -22,38 +21,21 @@ abstract class LocationBasedLineTracker extends Line protected double locationX; protected double locationY; protected double locationZ; - private int chunkX; - private int chunkZ; - private boolean chunkLoaded; private boolean locationChanged; LocationBasedLineTracker(T line, NMSManager nmsManager) { super(line, nmsManager); } - @Override - protected final boolean isActive() { - return chunkLoaded; - } - @MustBeInvokedByOverriders @Override protected void detectChanges() { World world = line.getWorld(); - int chunkX = line.getChunkX(); - int chunkZ = line.getChunkZ(); - if (this.world != world || this.chunkX != chunkX || this.chunkZ != chunkZ) { - this.world = world; - this.chunkX = chunkX; - this.chunkZ = chunkZ; - this.chunkLoaded = world != null && world.isChunkLoaded(chunkX, chunkZ); - this.locationChanged = true; - } - double locationX = line.getX(); double locationY = line.getY(); double locationZ = line.getZ(); - if (this.locationX != locationX || this.locationY != locationY || this.locationZ != locationZ) { + if (this.world != world || this.locationX != locationX || this.locationY != locationY || this.locationZ != locationZ) { + this.world = world; this.locationX = locationX; this.locationY = locationY; this.locationZ = locationZ; @@ -89,18 +71,4 @@ abstract class LocationBasedLineTracker extends Line protected abstract void addLocationChangePackets(NMSPacketList packetList); - @Override - protected final void onChunkLoad(Chunk chunk) { - if (this.world == chunk.getWorld() && this.chunkX == chunk.getX() && this.chunkZ == chunk.getZ()) { - this.chunkLoaded = true; - } - } - - @Override - protected final void onChunkUnload(Chunk chunk) { - if (this.world == chunk.getWorld() && this.chunkX == chunk.getX() && this.chunkZ == chunk.getZ()) { - this.chunkLoaded = false; - } - } - } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/listener/ChunkListener.java b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/listener/ChunkListener.java index 2e377379..b687c198 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/listener/ChunkListener.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/listener/ChunkListener.java @@ -5,7 +5,8 @@ */ package me.filoghost.holographicdisplays.plugin.listener; -import me.filoghost.holographicdisplays.plugin.hologram.tracking.LineTrackerManager; +import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologramManager; +import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramManager; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.event.EventHandler; @@ -18,16 +19,19 @@ import org.bukkit.plugin.Plugin; public class ChunkListener implements Listener { private final Plugin plugin; - private final LineTrackerManager lineTrackerManager; + private final InternalHologramManager internalHologramManager; + private final APIHologramManager apiHologramManager; - public ChunkListener(Plugin plugin, LineTrackerManager lineTrackerManager) { + public ChunkListener(Plugin plugin, InternalHologramManager internalHologramManager, APIHologramManager apiHologramManager) { this.plugin = plugin; - this.lineTrackerManager = lineTrackerManager; + this.internalHologramManager = internalHologramManager; + this.apiHologramManager = apiHologramManager; } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onChunkUnload(ChunkUnloadEvent event) { - lineTrackerManager.onChunkUnload(event.getChunk()); + internalHologramManager.onChunkUnload(event.getChunk()); + apiHologramManager.onChunkUnload(event.getChunk()); } @EventHandler(priority = EventPriority.MONITOR) @@ -48,7 +52,8 @@ public class ChunkListener implements Listener { } private void onChunkLoad(Chunk chunk) { - lineTrackerManager.onChunkLoad(chunk); + internalHologramManager.onChunkLoad(chunk); + apiHologramManager.onChunkLoad(chunk); } } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/util/CachedBoolean.java b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/util/CachedBoolean.java new file mode 100644 index 00000000..d92a3309 --- /dev/null +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/util/CachedBoolean.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) filoghost and contributors + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ +package me.filoghost.holographicdisplays.plugin.util; + +import java.util.function.BooleanSupplier; + +public class CachedBoolean { + + private final BooleanSupplier valueGetter; + private boolean value; + private boolean valid; + + public CachedBoolean(BooleanSupplier valueGetter) { + this.valueGetter = valueGetter; + } + + public void set(boolean value) { + this.valid = true; + this.value = value; + } + + public boolean get() { + if (!valid) { + value = valueGetter.getAsBoolean(); + valid = true; + } + + return value; + } + + public void invalidate() { + valid = false; + } + +}