Skip to content

Commit 8c1f24c

Browse files
committed
Reduce visibility allocations and block update gaps
1 parent 6c37b29 commit 8c1f24c

7 files changed

Lines changed: 361 additions & 101 deletions

File tree

common/src/main/java/com/loohp/interactionvisualizer/blocks/BeeHiveDisplay.java

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
import org.bukkit.block.BlockFace;
4848
import org.bukkit.block.data.BlockData;
4949
import org.bukkit.block.data.Directional;
50-
import org.bukkit.entity.Bee;
5150
import org.bukkit.event.EventHandler;
5251
import org.bukkit.event.EventPriority;
5352
import org.bukkit.event.Listener;
@@ -364,55 +363,39 @@ public void onBeehiveDeactivated(TileEntityDeactivatedEvent event) {
364363

365364
@EventHandler(priority = EventPriority.MONITOR)
366365
public void onBeeEnterBeehive(EntityEnterBlockEvent event) {
366+
if (InteractionVisualizer.eventDrivenBlockUpdates) {
367+
return;
368+
}
367369
if (event.isCancelled()) {
368370
return;
369371
}
370372
Block block = event.getBlock();
371-
if (InteractionVisualizer.eventDrivenBlockUpdates) {
372-
if (!(event.getEntity() instanceof Bee) || block.getType() != Material.BEEHIVE
373-
|| !beehiveMap.containsKey(block)) {
374-
return;
375-
}
376-
markDirty(block);
377-
} else {
378-
Scheduler.runTaskLater(InteractionVisualizer.plugin, () -> measureLegacyUpdate(block), 1, block.getLocation());
379-
}
373+
Scheduler.runTaskLater(InteractionVisualizer.plugin, () -> measureLegacyUpdate(block), 1, block.getLocation());
380374
}
381375

382376
@EventHandler(priority = EventPriority.MONITOR)
383377
public void onBeeLeaveBeehive(EntityChangeBlockEvent event) {
378+
if (InteractionVisualizer.eventDrivenBlockUpdates) {
379+
return;
380+
}
384381
if (event.isCancelled()) {
385382
return;
386383
}
387384
Block block = event.getBlock();
388-
if (InteractionVisualizer.eventDrivenBlockUpdates) {
389-
markAffectedColumnDirty(block);
390-
if (!(event.getEntity() instanceof Bee) || block.getType() != Material.BEEHIVE
391-
|| !beehiveMap.containsKey(block)) {
392-
return;
393-
}
394-
markDirty(block);
395-
} else {
396-
Scheduler.runTaskLater(InteractionVisualizer.plugin, () -> measureLegacyUpdate(block), 1, block.getLocation());
397-
}
385+
Scheduler.runTaskLater(InteractionVisualizer.plugin, () -> measureLegacyUpdate(block), 1, block.getLocation());
398386
}
399387

400388
@SuppressWarnings("deprecation")
401389
@EventHandler(priority = EventPriority.MONITOR)
402390
public void onInteractBeehive(PlayerInteractEvent event) {
391+
if (InteractionVisualizer.eventDrivenBlockUpdates) {
392+
return;
393+
}
403394
if (event.isCancelled()) {
404395
return;
405396
}
406397
Block block = event.getClickedBlock();
407-
if (InteractionVisualizer.eventDrivenBlockUpdates) {
408-
if (block == null) {
409-
return;
410-
}
411-
// Covers both harvesting the hive itself and toggling an
412-
// obstruction (for example a trapdoor) in the smoke column.
413-
markAffectedColumnDirty(block);
414-
markDirty(block);
415-
} else if (block != null) {
398+
if (block != null) {
416399
Scheduler.runTaskLater(InteractionVisualizer.plugin, () -> measureLegacyUpdate(block), 1, block.getLocation());
417400
}
418401
}

common/src/main/java/com/loohp/interactionvisualizer/blocks/BeeNestDisplay.java

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
import org.bukkit.block.BlockFace;
4848
import org.bukkit.block.data.BlockData;
4949
import org.bukkit.block.data.Directional;
50-
import org.bukkit.entity.Bee;
5150
import org.bukkit.event.EventHandler;
5251
import org.bukkit.event.EventPriority;
5352
import org.bukkit.event.Listener;
@@ -364,55 +363,39 @@ public void onBeenestDeactivated(TileEntityDeactivatedEvent event) {
364363

365364
@EventHandler(priority = EventPriority.MONITOR)
366365
public void onBeeEnterBeenest(EntityEnterBlockEvent event) {
366+
if (InteractionVisualizer.eventDrivenBlockUpdates) {
367+
return;
368+
}
367369
if (event.isCancelled()) {
368370
return;
369371
}
370372
Block block = event.getBlock();
371-
if (InteractionVisualizer.eventDrivenBlockUpdates) {
372-
if (!(event.getEntity() instanceof Bee) || block.getType() != Material.BEE_NEST
373-
|| !beenestMap.containsKey(block)) {
374-
return;
375-
}
376-
markDirty(block);
377-
} else {
378-
Scheduler.runTaskLater(InteractionVisualizer.plugin, () -> measureLegacyUpdate(block), 1, block.getLocation());
379-
}
373+
Scheduler.runTaskLater(InteractionVisualizer.plugin, () -> measureLegacyUpdate(block), 1, block.getLocation());
380374
}
381375

382376
@EventHandler(priority = EventPriority.MONITOR)
383377
public void onBeeLeaveBeenest(EntityChangeBlockEvent event) {
378+
if (InteractionVisualizer.eventDrivenBlockUpdates) {
379+
return;
380+
}
384381
if (event.isCancelled()) {
385382
return;
386383
}
387384
Block block = event.getBlock();
388-
if (InteractionVisualizer.eventDrivenBlockUpdates) {
389-
markAffectedColumnDirty(block);
390-
if (!(event.getEntity() instanceof Bee) || block.getType() != Material.BEE_NEST
391-
|| !beenestMap.containsKey(block)) {
392-
return;
393-
}
394-
markDirty(block);
395-
} else {
396-
Scheduler.runTaskLater(InteractionVisualizer.plugin, () -> measureLegacyUpdate(block), 1, block.getLocation());
397-
}
385+
Scheduler.runTaskLater(InteractionVisualizer.plugin, () -> measureLegacyUpdate(block), 1, block.getLocation());
398386
}
399387

400388
@SuppressWarnings("deprecation")
401389
@EventHandler(priority = EventPriority.MONITOR)
402390
public void onInteractBeenest(PlayerInteractEvent event) {
391+
if (InteractionVisualizer.eventDrivenBlockUpdates) {
392+
return;
393+
}
403394
if (event.isCancelled()) {
404395
return;
405396
}
406397
Block block = event.getClickedBlock();
407-
if (InteractionVisualizer.eventDrivenBlockUpdates) {
408-
if (block == null) {
409-
return;
410-
}
411-
// Covers both harvesting the nest itself and toggling an
412-
// obstruction (for example a trapdoor) in the smoke column.
413-
markAffectedColumnDirty(block);
414-
markDirty(block);
415-
} else if (block != null) {
398+
if (block != null) {
416399
Scheduler.runTaskLater(InteractionVisualizer.plugin, () -> measureLegacyUpdate(block), 1, block.getLocation());
417400
}
418401
}

common/src/main/java/com/loohp/interactionvisualizer/managers/DisplayManager.java

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,10 @@
5050
import org.bukkit.plugin.Plugin;
5151
import org.bukkit.util.Vector;
5252

53-
import java.util.ArrayDeque;
5453
import java.util.ArrayList;
5554
import java.util.Collection;
56-
import java.util.Deque;
57-
import java.util.HashMap;
5855
import java.util.HashSet;
56+
import java.util.LinkedHashSet;
5957
import java.util.List;
6058
import java.util.Map;
6159
import java.util.Set;
@@ -1189,7 +1187,9 @@ private static void requestViewerShow(VisualizerEntity logical, Player player) {
11891187
}
11901188

11911189
private static void showViewerNow(VisualizerEntity logical, Player player) {
1192-
cancelVisibilityShow(logical, player.getUniqueId());
1190+
// Both callers remove the pending request before entering: the immediate
1191+
// path cancels it, while VisibilityShowQueue removes it before invoking
1192+
// the drain action. Avoid a second queue lookup on every successful show.
11931193
Set<UUID> shown = shownViewers.computeIfAbsent(logical, ignored -> ConcurrentHashMap.newKeySet());
11941194
UUID viewer = player.getUniqueId();
11951195
if (!shown.add(viewer)) {
@@ -1621,38 +1621,26 @@ public void onEntityRemove(EntityRemoveEvent event) {
16211621

16221622
static final class VisibilityShowQueue<T> {
16231623

1624-
private final Deque<QueuedShow<T>> pending;
1625-
private final Map<T, Long> queued;
1624+
private final LinkedHashSet<T> pending;
16261625
private int tokens;
16271626
private long lastRefillTick;
1628-
private long nextGeneration;
16291627

16301628
VisibilityShowQueue(int initialTokens) {
16311629
this(initialTokens, 0L);
16321630
}
16331631

16341632
VisibilityShowQueue(int initialTokens, long initialTick) {
1635-
this.pending = new ArrayDeque<>();
1636-
this.queued = new HashMap<>();
1633+
this.pending = new LinkedHashSet<>();
16371634
this.tokens = Math.max(0, initialTokens);
16381635
this.lastRefillTick = initialTick;
16391636
}
16401637

16411638
boolean request(T value) {
1642-
if (queued.containsKey(value)) {
1643-
return false;
1644-
}
1645-
long generation = ++nextGeneration;
1646-
queued.put(value, generation);
1647-
pending.addLast(new QueuedShow<>(value, generation));
1648-
return true;
1639+
return pending.add(value);
16491640
}
16501641

16511642
void cancel(T value) {
1652-
queued.remove(value);
1653-
if (queued.isEmpty()) {
1654-
pending.clear();
1655-
}
1643+
pending.remove(value);
16561644
}
16571645

16581646
List<T> drain(int capacity, int refill, Predicate<T> desired) {
@@ -1677,21 +1665,20 @@ int drainTo(int capacity, int refill, long currentTick, DrainAction<T> action) {
16771665
long restored = elapsedTicks * (long) Math.max(0, refill);
16781666
tokens = (int) Math.min(boundedCapacity, Math.max(0L, tokens + restored));
16791667
lastRefillTick = Math.max(lastRefillTick, currentTick);
1668+
if (tokens == 0 || pending.isEmpty()) {
1669+
return 0;
1670+
}
16801671
int drained = 0;
16811672
int inspected = 0;
16821673
while (tokens > 0 && inspected < boundedCapacity && !pending.isEmpty()) {
1683-
QueuedShow<T> request = pending.removeFirst();
1674+
T value = pending.removeFirst();
16841675
inspected++;
1685-
T value = request.value();
1686-
if (!queued.remove(value, request.generation()) || !action.accept(value)) {
1676+
if (!action.accept(value)) {
16871677
continue;
16881678
}
16891679
tokens--;
16901680
drained++;
16911681
}
1692-
if (queued.isEmpty()) {
1693-
pending.clear();
1694-
}
16951682
return drained;
16961683
}
16971684

@@ -1710,26 +1697,24 @@ List<T> drainAll(Predicate<T> desired) {
17101697
int drainAllTo(DrainAction<T> action) {
17111698
int drained = 0;
17121699
while (!pending.isEmpty()) {
1713-
QueuedShow<T> request = pending.removeFirst();
1714-
T value = request.value();
1715-
if (queued.remove(value, request.generation()) && action.accept(value)) {
1700+
T value = pending.removeFirst();
1701+
if (action.accept(value)) {
17161702
drained++;
17171703
}
17181704
}
17191705
return drained;
17201706
}
17211707

17221708
boolean isEmpty() {
1723-
return queued.isEmpty();
1709+
return pending.isEmpty();
17241710
}
17251711

17261712
boolean hasPending() {
1727-
return !queued.isEmpty();
1713+
return !pending.isEmpty();
17281714
}
17291715

17301716
void clear() {
17311717
pending.clear();
1732-
queued.clear();
17331718
}
17341719

17351720
@FunctionalInterface
@@ -1738,8 +1723,6 @@ interface DrainAction<T> {
17381723
boolean accept(T value);
17391724
}
17401725

1741-
private record QueuedShow<T>(T value, long generation) {
1742-
}
17431726
}
17441727

17451728
private static final class ItemAnimationState {

0 commit comments

Comments
 (0)