Skip to content

Commit 1bfe489

Browse files
committed
Optimize dropped-item section candidates
1 parent b8f0d56 commit 1bfe489

15 files changed

Lines changed: 924 additions & 119 deletions

.github/workflows/phase2-runtime-ab.yml

Lines changed: 180 additions & 21 deletions
Large diffs are not rendered by default.

common/src/main/java/com/loohp/interactionvisualizer/Commands.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -307,17 +307,18 @@ private boolean handlePerformanceCommand(CommandSender sender, String[] args) {
307307
case "scene" -> {
308308
if (args.length < 4) {
309309
sender.sendMessage(Component.text(
310-
"Usage: /iv perf scene <static|motion|itemdisplay|textdisplay> " +
310+
"Usage: /iv perf scene <static|motion|itemdisplay|textdisplay|dropped> " +
311311
"<count> [lifetimeTicks] [player]"));
312312
return true;
313313
}
314314
boolean moving = args[2].equalsIgnoreCase("motion");
315315
boolean staticItem = args[2].equalsIgnoreCase("static");
316316
boolean itemDisplay = args[2].equalsIgnoreCase("itemdisplay");
317317
boolean textDisplay = args[2].equalsIgnoreCase("textdisplay");
318-
if (!moving && !staticItem && !itemDisplay && !textDisplay) {
318+
boolean dropped = args[2].equalsIgnoreCase("dropped");
319+
if (!moving && !staticItem && !itemDisplay && !textDisplay && !dropped) {
319320
sender.sendMessage(Component.text(
320-
"[InteractionVisualizer] Scene type must be static, motion, itemdisplay, or textdisplay."));
321+
"[InteractionVisualizer] Scene type must be static, motion, itemdisplay, textdisplay, or dropped."));
321322
return true;
322323
}
323324
long defaultLifetime = moving ? 80L : 200L;
@@ -343,12 +344,15 @@ private boolean handlePerformanceCommand(CommandSender sender, String[] args) {
343344
return true;
344345
}
345346
int count = parseInteger(args[3], 1);
346-
int spawned = itemDisplay || textDisplay
347+
int spawned = dropped
348+
? PerformanceScene.spawnDroppedItems(player, count, lifetime)
349+
: itemDisplay || textDisplay
347350
? PerformanceScene.spawnDisplay(player, textDisplay, count, lifetime)
348351
: PerformanceScene.spawn(player, moving, count, lifetime);
349352
String sceneName = moving ? "moving" : staticItem ? "static"
350-
: itemDisplay ? "itemdisplay" : "textdisplay";
351-
String entityLabel = staticItem || moving ? " benchmark items" : " benchmark entities";
353+
: itemDisplay ? "itemdisplay" : textDisplay ? "textdisplay" : "dropped";
354+
String entityLabel = staticItem || moving || dropped
355+
? " benchmark items" : " benchmark entities";
352356
sender.sendMessage(Component.text("[InteractionVisualizer] Spawned " + spawned + " "
353357
+ sceneName + entityLabel + " for " + lifetime + " ticks."));
354358
}
@@ -708,7 +712,7 @@ public List<String> onTabComplete(CommandSender sender, Command cmd, String labe
708712
case 3:
709713
if (args[0].equalsIgnoreCase("perf") && args[1].equalsIgnoreCase("scene")
710714
&& sender.hasPermission("interactionvisualizer.performance")) {
711-
for (String option : List.of("static", "motion", "itemdisplay", "textdisplay")) {
715+
for (String option : List.of("static", "motion", "itemdisplay", "textdisplay", "dropped")) {
712716
if (option.startsWith(args[2].toLowerCase())) {
713717
tab.add(option);
714718
}

common/src/main/java/com/loohp/interactionvisualizer/debug/PerformanceScene.java

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.bukkit.Bukkit;
2222
import org.bukkit.Location;
2323
import org.bukkit.Material;
24+
import org.bukkit.World;
2425
import org.bukkit.entity.Player;
2526
import org.bukkit.inventory.ItemStack;
2627
import org.bukkit.util.Vector;
@@ -40,6 +41,7 @@ public final class PerformanceScene {
4041
private static final int MAX_ITEMS = 8_192;
4142
private static final long MAX_LIFETIME_TICKS = 12_000L;
4243
private static final Map<UUID, Set<VisualizerEntity>> scenes = new HashMap<>();
44+
private static final Map<UUID, Set<org.bukkit.entity.Item>> droppedScenes = new HashMap<>();
4345

4446
private PerformanceScene() {
4547
}
@@ -121,6 +123,44 @@ public static int spawnDisplay(Player owner, boolean text, int requestedCount,
121123
return count;
122124
}
123125

126+
/** Creates real Paper Item entities for the dropped-label runtime factor. */
127+
public static int spawnDroppedItems(Player owner, int requestedCount,
128+
long requestedLifetimeTicks) {
129+
int count = Math.max(1, Math.min(MAX_ITEMS, requestedCount));
130+
long lifetimeTicks = Math.max(1L, Math.min(MAX_LIFETIME_TICKS, requestedLifetimeTicks));
131+
clear(owner);
132+
133+
World world = owner.getWorld();
134+
Location center = owner.getLocation().add(0.0D, 1.5D, 0.0D);
135+
int width = (int) Math.ceil(Math.sqrt(count));
136+
double spacing = 1.25D;
137+
double offset = (width - 1) * spacing / 2.0D;
138+
Set<org.bukkit.entity.Item> items = new HashSet<>(count);
139+
for (int index = 0; index < count; index++) {
140+
double x = center.getX() + index % width * spacing - offset;
141+
double z = center.getZ() + index / width * spacing - offset;
142+
Location location = new Location(world, x, center.getY(), z);
143+
location.getChunk().load();
144+
ItemStack stack = new ItemStack(Material.STONE, index % 64 + 1);
145+
int ordinal = index;
146+
stack.editMeta(meta -> meta.customName(Component.text("iv-dropped-benchmark-" + ordinal)));
147+
org.bukkit.entity.Item item = world.dropItem(location, stack, entity -> {
148+
entity.setGravity(false);
149+
entity.setVelocity(new Vector());
150+
entity.setPickupDelay(Short.MAX_VALUE - 1);
151+
entity.setUnlimitedLifetime(true);
152+
entity.setPersistent(false);
153+
});
154+
items.add(item);
155+
}
156+
157+
UUID ownerId = owner.getUniqueId();
158+
droppedScenes.put(ownerId, items);
159+
Scheduler.runTaskLater(InteractionVisualizer.plugin,
160+
() -> expireDropped(ownerId, items), lifetimeTicks, owner.getLocation());
161+
return count;
162+
}
163+
124164
public static void clear(Player owner) {
125165
clear(owner.getUniqueId());
126166
}
@@ -131,6 +171,10 @@ public static void clear(UUID ownerId) {
131171
if (previous != null) {
132172
removeEntities(previous);
133173
}
174+
Set<org.bukkit.entity.Item> dropped = droppedScenes.remove(ownerId);
175+
if (dropped != null) {
176+
removeDroppedItems(dropped);
177+
}
134178
}
135179

136180
/** Deterministically removes every disposable benchmark scene. */
@@ -140,10 +184,15 @@ public static void shutdown() {
140184
for (Set<VisualizerEntity> entities : remaining) {
141185
removeEntities(entities);
142186
}
187+
List<Set<org.bukkit.entity.Item>> remainingDropped = new ArrayList<>(droppedScenes.values());
188+
droppedScenes.clear();
189+
for (Set<org.bukkit.entity.Item> items : remainingDropped) {
190+
removeDroppedItems(items);
191+
}
143192
}
144193

145194
public static int retainedStateCount() {
146-
return scenes.size();
195+
return scenes.size() + droppedScenes.size();
147196
}
148197

149198
private static void expire(UUID ownerId, Set<VisualizerEntity> entities) {
@@ -152,6 +201,12 @@ private static void expire(UUID ownerId, Set<VisualizerEntity> entities) {
152201
}
153202
}
154203

204+
private static void expireDropped(UUID ownerId, Set<org.bukkit.entity.Item> items) {
205+
if (droppedScenes.remove(ownerId, items)) {
206+
removeDroppedItems(items);
207+
}
208+
}
209+
155210
private static void removeEntities(Set<VisualizerEntity> entities) {
156211
for (VisualizerEntity entity : entities) {
157212
if (entity instanceof Item item) {
@@ -161,4 +216,12 @@ private static void removeEntities(Set<VisualizerEntity> entities) {
161216
}
162217
}
163218
}
219+
220+
private static void removeDroppedItems(Set<org.bukkit.entity.Item> items) {
221+
for (org.bukkit.entity.Item item : items) {
222+
if (item.isValid()) {
223+
item.remove();
224+
}
225+
}
226+
}
164227
}

0 commit comments

Comments
 (0)