Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,19 @@ public static void replaceRegion(
return;
}
VIEWER_INTERACTIONS.compute(viewerId, (ignored, current) -> {
if (current != null && !tableId.equals(current.tableId())) {
return interactions == null || interactions.isEmpty()
? current
: ViewerInteractions.single(tableId, regionKey, interactions);
boolean empty = interactions == null || interactions.isEmpty();
if (current == null) {
return empty ? null : ViewerInteractions.single(tableId, regionKey, interactions);
}
Map<String, List<RayInteraction>> regions = current == null
? new LinkedHashMap<>()
: new LinkedHashMap<>(current.regions());
if (interactions == null || interactions.isEmpty()) {
if (!tableId.equals(current.tableId())) {
return empty ? current : ViewerInteractions.single(tableId, regionKey, interactions);
}
List<RayInteraction> previous = current.regions().get(regionKey);
if ((empty && previous == null) || (!empty && Objects.equals(previous, interactions))) {
return current;
}
Map<String, List<RayInteraction>> regions = new LinkedHashMap<>(current.regions());
if (empty) {
regions.remove(regionKey);
} else {
regions.put(regionKey, List.copyOf(interactions));
Expand Down Expand Up @@ -129,11 +133,11 @@ public static synchronized void replacePublicJoinRegion(
return;
}
PublicRegionKey key = new PublicRegionKey(tableId, regionKey);
List<RayInteraction> publicJoins = interactions == null
? List.of()
: interactions.stream()
.filter(interaction -> isPublicJoinForTable(interaction, tableId))
.toList();
List<RayInteraction> previous = PUBLIC_JOIN_REGIONS.get(key);
if (samePublicJoinInteractions(previous, tableId, interactions)) {
return;
}
List<RayInteraction> publicJoins = filterPublicJoinInteractions(tableId, interactions);
if (publicJoins.isEmpty()) {
PUBLIC_JOIN_REGIONS.remove(key);
} else {
Expand Down Expand Up @@ -211,6 +215,44 @@ private static void rebuildPublicJoinSnapshot() {
publicJoinInteractions = List.copyOf(flattened);
}

private static boolean samePublicJoinInteractions(
List<RayInteraction> previous,
String tableId,
List<RayInteraction> interactions
) {
int previousIndex = 0;
if (interactions != null) {
for (RayInteraction interaction : interactions) {
if (!isPublicJoinForTable(interaction, tableId)) {
continue;
}
if (previous == null
|| previousIndex >= previous.size()
|| !Objects.equals(previous.get(previousIndex), interaction)) {
return false;
}
previousIndex++;
}
}
return previous == null ? previousIndex == 0 : previousIndex == previous.size();
}

private static List<RayInteraction> filterPublicJoinInteractions(
String tableId,
List<RayInteraction> interactions
) {
if (interactions == null || interactions.isEmpty()) {
return List.of();
}
List<RayInteraction> publicJoins = new ArrayList<>(interactions.size());
for (RayInteraction interaction : interactions) {
if (isPublicJoinForTable(interaction, tableId)) {
publicJoins.add(interaction);
}
}
return publicJoins.isEmpty() ? List.of() : List.copyOf(publicJoins);
}

private static boolean isPublicJoinForTable(RayInteraction interaction, String tableId) {
return interaction != null
&& interaction.action().actionType() == DisplayClickAction.ActionType.JOIN_SEAT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ synchronized void replace(
}

Map<UUID, ActiveProxies> previous = this.regions.getOrDefault(regionKey, Map.of());
if (this.canReuseRegion(previous, interactionsByViewer)) {
return;
}
Map<UUID, ActiveProxies> next = new LinkedHashMap<>();
List<PendingSpawn> pendingSpawns = new ArrayList<>();
try {
Expand Down Expand Up @@ -132,6 +135,31 @@ synchronized void replace(
}
}

private boolean canReuseRegion(
Map<UUID, ActiveProxies> previous,
Map<UUID, List<DisplayInteractionRayRegistry.RayInteraction>> interactionsByViewer
) {
int reusableViewers = 0;
for (Map.Entry<UUID, List<DisplayInteractionRayRegistry.RayInteraction>> entry
: interactionsByViewer.entrySet()) {
UUID viewerId = entry.getKey();
List<DisplayInteractionRayRegistry.RayInteraction> interactions = entry.getValue();
if (viewerId == null || interactions == null || interactions.isEmpty()) {
continue;
}
Player viewer = this.session.onlinePlayer(viewerId);
if (viewer == null || !viewer.isOnline()) {
continue;
}
ActiveProxies active = previous.get(viewerId);
if (!this.canReuse(viewerId, viewer, active, interactions)) {
return false;
}
reusableViewers++;
}
return reusableViewers == previous.size();
}

private boolean canReuse(
UUID viewerId,
Player viewer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;

import java.util.List;
import java.util.UUID;
Expand Down Expand Up @@ -132,6 +133,109 @@ void independentActionAndHandRegionsCoexistAndClearSeparately() {
assertEquals(List.of(tile), DisplayInteractionRayRegistry.snapshot(VIEWER_ID));
}

@Test
void identicalRegionReplacementKeepsTheExistingSnapshotAndActionChangesStillApply() {
DisplayInteractionRayRegistry.RayInteraction first = interaction(
0.0D,
3.0D,
1.0D,
0.0D,
action("first")
);
DisplayInteractionRayRegistry.replaceRegion(
VIEWER_ID,
"table-a",
"viewer-actions",
List.of(first)
);
List<DisplayInteractionRayRegistry.RayInteraction> firstSnapshot =
DisplayInteractionRayRegistry.snapshot(VIEWER_ID);

DisplayInteractionRayRegistry.replaceRegion(
VIEWER_ID,
"table-a",
"viewer-actions",
List.of(first)
);

assertSame(firstSnapshot, DisplayInteractionRayRegistry.snapshot(VIEWER_ID));

DisplayInteractionRayRegistry.RayInteraction changed = interaction(
0.0D,
3.0D,
1.0D,
0.0D,
action("second")
);
DisplayInteractionRayRegistry.replaceRegion(
VIEWER_ID,
"table-a",
"viewer-actions",
List.of(changed)
);

assertEquals(List.of(changed), DisplayInteractionRayRegistry.snapshot(VIEWER_ID));
}

@Test
void identicalPublicJoinReplacementKeepsTheExistingFlattenedSnapshot() {
DisplayInteractionRayRegistry.RayInteraction join = interaction(
0.0D,
3.0D,
1.0D,
0.0D,
DisplayClickAction.joinSeat("table-a", SeatWind.EAST)
);
DisplayInteractionRayRegistry.RayInteraction privateDecision = interaction(
0.0D,
4.0D,
1.0D,
0.0D,
action("private")
);
List<DisplayInteractionRayRegistry.RayInteraction> input = List.of(join, privateDecision);

DisplayInteractionRayRegistry.replacePublicJoinRegion("table-a", "seat-label:EAST", input);
List<DisplayInteractionRayRegistry.RayInteraction> firstSnapshot =
DisplayInteractionRayRegistry.publicJoinSnapshot();

DisplayInteractionRayRegistry.replacePublicJoinRegion("table-a", "seat-label:EAST", input);

assertSame(firstSnapshot, DisplayInteractionRayRegistry.publicJoinSnapshot());
assertEquals(List.of(join), firstSnapshot);
}

@Test
void replacingPublicJoinActionStillUpdatesTheFlattenedSnapshot() {
DisplayInteractionRayRegistry.RayInteraction east = interaction(
0.0D,
3.0D,
1.0D,
0.0D,
DisplayClickAction.joinSeat("table-a", SeatWind.EAST)
);
DisplayInteractionRayRegistry.RayInteraction south = interaction(
0.0D,
3.0D,
1.0D,
0.0D,
DisplayClickAction.joinSeat("table-a", SeatWind.SOUTH)
);

DisplayInteractionRayRegistry.replacePublicJoinRegion(
"table-a",
"seat-label:EAST",
List.of(east)
);
DisplayInteractionRayRegistry.replacePublicJoinRegion(
"table-a",
"seat-label:EAST",
List.of(south)
);

assertEquals(List.of(south), DisplayInteractionRayRegistry.publicJoinSnapshot());
}

@Test
void tableAndViewerCleanupCannotLeaveStaleControls() {
DisplayInteractionRayRegistry.RayInteraction interaction = interaction(
Expand Down