diff --git a/core/src/main/java/com/volmit/iris/core/service/BoardSVC.java b/core/src/main/java/com/volmit/iris/core/service/BoardSVC.java index e5557b023..e8eadc558 100644 --- a/core/src/main/java/com/volmit/iris/core/service/BoardSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/BoardSVC.java @@ -22,33 +22,39 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.tools.IrisToolbelt; -import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.util.board.BoardManager; import com.volmit.iris.util.board.BoardProvider; import com.volmit.iris.util.board.BoardSettings; import com.volmit.iris.util.board.ScoreDirection; -import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.plugin.IrisService; import com.volmit.iris.util.scheduling.J; import lombok.Data; +import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import java.util.ArrayList; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; public class BoardSVC implements IrisService, BoardProvider { private final KMap boards = new KMap<>(); - private com.volmit.iris.util.board.BoardManager manager; + private ScheduledExecutorService executor; + private BoardManager manager; @Override public void onEnable() { - J.ar(this::tick, 20); + executor = Executors.newScheduledThreadPool(0, Thread.ofVirtual().factory()); manager = new BoardManager(Iris.instance, BoardSettings.builder() .boardProvider(this) .scoreDirection(ScoreDirection.DOWN) @@ -57,6 +63,7 @@ public class BoardSVC implements IrisService, BoardProvider { @Override public void onDisable() { + executor.shutdownNow(); manager.onDisable(); boards.clear(); } @@ -71,14 +78,22 @@ public class BoardSVC implements IrisService, BoardProvider { J.s(() -> updatePlayer(e.getPlayer())); } + @EventHandler + public void on(PlayerQuitEvent e) { + remove(e.getPlayer()); + } + public void updatePlayer(Player p) { if (IrisToolbelt.isIrisStudioWorld(p.getWorld())) { manager.remove(p); manager.setup(p); - } else { - manager.remove(p); - boards.remove(p); - } + } else remove(p); + } + + private void remove(Player player) { + manager.remove(player); + var board = boards.remove(player); + if (board != null) board.task.cancel(true); } @Override @@ -86,73 +101,63 @@ public class BoardSVC implements IrisService, BoardProvider { return C.GREEN + "Iris"; } - public void tick() { - if (!Iris.service(StudioSVC.class).isProjectOpen()) { - return; - } - - boards.forEach((k, v) -> v.update()); - } - @Override public List getLines(Player player) { - PlayerBoard pb = boards.computeIfAbsent(player, PlayerBoard::new); - synchronized (pb.lines) { - return pb.lines; - } + return boards.computeIfAbsent(player, PlayerBoard::new).lines; } @Data - public static class PlayerBoard { + public class PlayerBoard { private final Player player; - private final CopyOnWriteArrayList lines; + private final ScheduledFuture task; + private volatile List lines; public PlayerBoard(Player player) { this.player = player; - this.lines = new CopyOnWriteArrayList<>(); + this.lines = new ArrayList<>(); + this.task = executor.scheduleAtFixedRate(this::tick, 0, 1, TimeUnit.SECONDS); + } + + private void tick() { + if (!Iris.service(StudioSVC.class).isProjectOpen()) { + return; + } + update(); } public void update() { - synchronized (lines) { - lines.clear(); + final World world = player.getWorld(); + final Location loc = player.getLocation(); - if (!IrisToolbelt.isIrisStudioWorld(player.getWorld())) { - return; - } + final var access = IrisToolbelt.access(world); + if (access == null) return; - Engine engine = IrisToolbelt.access(player.getWorld()).getEngine(); - int x = player.getLocation().getBlockX(); - int y = player.getLocation().getBlockY() - player.getWorld().getMinHeight(); - int z = player.getLocation().getBlockZ(); + final var engine = access.getEngine(); + if (engine == null) return; - if(IrisSettings.get().getGeneral().debug){ - lines.add("&7&m "); - lines.add(C.GREEN + "Speed" + C.GRAY + ": " + Form.f(engine.getGeneratedPerSecond(), 0) + "/s " + Form.duration(1000D / engine.getGeneratedPerSecond(), 0)); - lines.add(C.AQUA + "Cache" + C.GRAY + ": " + Form.f(IrisData.cacheSize())); - lines.add(C.AQUA + "Mantle" + C.GRAY + ": " + engine.getMantle().getLoadedRegionCount()); - lines.add(C.LIGHT_PURPLE + "Carving" + C.GRAY + ": " + engine.getMantle().isCarved(x,y,z)); - lines.add("&7&m "); - lines.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName()); - lines.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiomeOrMantle(x, y, z).getName()); - lines.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z))); - lines.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getComplex().getSlopeStream().get(x, z), 2)); - lines.add(C.AQUA + "BUD/s" + C.GRAY + ": " + Form.f(engine.getBlockUpdatesPerSecond())); - lines.add("&7&m "); - } else { - lines.add("&7&m "); - lines.add(C.GREEN + "Speed" + C.GRAY + ": " + Form.f(engine.getGeneratedPerSecond(), 0) + "/s " + Form.duration(1000D / engine.getGeneratedPerSecond(), 0)); - lines.add(C.AQUA + "Cache" + C.GRAY + ": " + Form.f(IrisData.cacheSize())); - lines.add(C.AQUA + "Mantle" + C.GRAY + ": " + engine.getMantle().getLoadedRegionCount()); - lines.add("&7&m "); - lines.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName()); - lines.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiomeOrMantle(x, y, z).getName()); - lines.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z))); - lines.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getComplex().getSlopeStream().get(x, z), 2)); - lines.add(C.AQUA + "BUD/s" + C.GRAY + ": " + Form.f(engine.getBlockUpdatesPerSecond())); - lines.add("&7&m "); - } + int x = loc.getBlockX(); + int y = loc.getBlockY() - world.getMinHeight(); + int z = loc.getBlockZ(); + + List lines = new ArrayList<>(this.lines.size()); + lines.add("&7&m "); + lines.add(C.GREEN + "Speed" + C.GRAY + ": " + Form.f(engine.getGeneratedPerSecond(), 0) + "/s " + Form.duration(1000D / engine.getGeneratedPerSecond(), 0)); + lines.add(C.AQUA + "Cache" + C.GRAY + ": " + Form.f(IrisData.cacheSize())); + lines.add(C.AQUA + "Mantle" + C.GRAY + ": " + engine.getMantle().getLoadedRegionCount()); + + if (IrisSettings.get().getGeneral().debug) { + lines.add(C.LIGHT_PURPLE + "Carving" + C.GRAY + ": " + engine.getMantle().isCarved(x,y,z)); } + + lines.add("&7&m "); + lines.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName()); + lines.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiomeOrMantle(x, y, z).getName()); + lines.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z))); + lines.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getComplex().getSlopeStream().get(x, z), 2)); + lines.add(C.AQUA + "BUD/s" + C.GRAY + ": " + Form.f(engine.getBlockUpdatesPerSecond())); + lines.add("&7&m "); + this.lines = lines; } } } diff --git a/core/src/main/java/com/volmit/iris/util/board/Board.java b/core/src/main/java/com/volmit/iris/util/board/Board.java index eb37ef182..eecbac731 100644 --- a/core/src/main/java/com/volmit/iris/util/board/Board.java +++ b/core/src/main/java/com/volmit/iris/util/board/Board.java @@ -23,15 +23,11 @@ import lombok.NonNull; import lombok.Setter; import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.scoreboard.DisplaySlot; -import org.bukkit.scoreboard.Objective; -import org.bukkit.scoreboard.Scoreboard; -import org.bukkit.scoreboard.Team; +import org.bukkit.scoreboard.*; import java.util.Collections; import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; +import java.util.function.UnaryOperator; import java.util.stream.IntStream; /** @@ -42,7 +38,7 @@ public class Board { private static final String[] CACHED_ENTRIES = new String[C.values().length]; - private static final Function APPLY_COLOR_TRANSLATION = s -> C.translateAlternateColorCodes('&', s); + private static final UnaryOperator APPLY_COLOR_TRANSLATION = s -> C.translateAlternateColorCodes('&', s); static { IntStream.range(0, 15).forEach(i -> CACHED_ENTRIES[i] = C.values()[i].toString() + C.RESET); @@ -54,13 +50,14 @@ public class Board { private BoardSettings boardSettings; private boolean ready; - @SuppressWarnings("deprecation") public Board(@NonNull final Player player, final BoardSettings boardSettings) { this.player = player; this.boardSettings = boardSettings; - this.objective = this.getScoreboard().getObjective("board") == null ? this.getScoreboard().registerNewObjective("board", "dummy") : this.getScoreboard().getObjective("board"); + var obj = getScoreboard().getObjective("board"); + this.objective = obj == null ? this.getScoreboard().registerNewObjective("board", Criteria.DUMMY, "Iris") : obj; this.objective.setDisplaySlot(DisplaySlot.SIDEBAR); - Team team = this.getScoreboard().getTeam("board") == null ? this.getScoreboard().registerNewTeam("board") : this.getScoreboard().getTeam("board"); + Team team = getScoreboard().getTeam("board"); + team = team == null ? getScoreboard().registerNewTeam("board") : team; team.setAllowFriendlyFire(true); team.setCanSeeFriendlyInvisibles(false); team.setPrefix(""); @@ -94,7 +91,8 @@ public class Board { } // Getting their Scoreboard display from the Scoreboard Provider. - final List entries = boardSettings.getBoardProvider().getLines(player).stream().map(APPLY_COLOR_TRANSLATION).collect(Collectors.toList()); + final List entries = boardSettings.getBoardProvider().getLines(player); + entries.replaceAll(APPLY_COLOR_TRANSLATION); if (boardSettings.getScoreDirection() == ScoreDirection.UP) { Collections.reverse(entries); diff --git a/core/src/main/java/com/volmit/iris/util/board/BoardUpdateTask.java b/core/src/main/java/com/volmit/iris/util/board/BoardUpdateTask.java index ce7ded229..1a54bf498 100644 --- a/core/src/main/java/com/volmit/iris/util/board/BoardUpdateTask.java +++ b/core/src/main/java/com/volmit/iris/util/board/BoardUpdateTask.java @@ -38,6 +38,12 @@ public class BoardUpdateTask extends BukkitRunnable { @Override public void run() { - boardManager.getScoreboards().entrySet().stream().filter(entrySet -> PLAYER_IS_ONLINE.test(entrySet.getKey())).forEach(entrySet -> entrySet.getValue().update()); + for (var entry : boardManager.getScoreboards().entrySet()) { + if (!PLAYER_IS_ONLINE.test(entry.getKey())) { + continue; + } + + entry.getValue().update(); + } } }