Skip to content
Merged
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 @@ -4,32 +4,40 @@
import top.ellan.mahjong.render.TableRenderSubject;
import top.ellan.mahjong.render.snapshot.TableRenderSnapshot;
import top.ellan.mahjong.render.snapshot.TableSeatRenderSnapshot;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.entity.Player;

public final class TableRenderSnapshotFactory {
private static final Comparator<SerializedViewerId> SERIALIZED_VIEWER_ID_COMPARATOR =
Comparator.comparing(SerializedViewerId::serializedId);

public TableRenderSnapshot create(TableRenderSubject session, long version, long cancellationNonce) {
Location tableCenter = session.center();
boolean started = session.isStarted();
List<SerializedViewerId> serializedOnlineViewerIds = session.viewers().stream()
.map(Player::getUniqueId)
.distinct()
.map(viewerId -> new SerializedViewerId(viewerId, viewerId.toString()))
.sorted(Comparator.comparing(SerializedViewerId::serializedId))
.sorted(SERIALIZED_VIEWER_ID_COMPARATOR)
.toList();
List<UUID> onlineViewerIds = serializedOnlineViewerIds.stream()
.map(SerializedViewerId::id)
.toList();
Set<UUID> onlineViewerIdSet = new HashSet<>(onlineViewerIds);
Map<UUID, SerializedViewerId> serializedOnlineViewersById = new HashMap<>(
Math.max(16, (int) (serializedOnlineViewerIds.size() / 0.75F) + 1)
);
for (SerializedViewerId viewer : serializedOnlineViewerIds) {
serializedOnlineViewersById.put(viewer.id(), viewer);
}
StringBuilder viewerMembershipBuffer = this.viewerMembershipBuffer(serializedOnlineViewerIds);
SeatWind[] seatWinds = SeatWind.values();
EnumMap<SeatWind, UUID> seatPlayerIds = new EnumMap<>(SeatWind.class);
for (SeatWind wind : seatWinds) {
Expand All @@ -38,13 +46,28 @@ public TableRenderSnapshot create(TableRenderSubject session, long version, long
Map<UUID, String> viewerMembershipSignatures = new HashMap<>();
Map<UUID, List<UUID>> viewerIdsExcluding = new HashMap<>();
for (UUID playerId : seatPlayerIds.values()) {
if (viewerMembershipSignatures.containsKey(playerId)
|| playerId != null && !onlineViewerIdSet.contains(playerId)) {
if (viewerMembershipSignatures.containsKey(playerId)) {
continue;
}
SerializedViewerId excludedViewer = playerId == null
? null
: serializedOnlineViewersById.get(playerId);
if (playerId != null && excludedViewer == null) {
continue;
}
viewerMembershipSignatures.put(
playerId,
this.viewerMembershipSignature(serializedOnlineViewerIds, playerId)
excludedViewer == null
? viewerMembershipBuffer.toString()
: this.viewerMembershipSignature(
viewerMembershipBuffer,
excludedViewer,
Collections.binarySearch(
serializedOnlineViewerIds,
excludedViewer,
SERIALIZED_VIEWER_ID_COMPARATOR
)
)
);
viewerIdsExcluding.put(
playerId,
Expand All @@ -59,7 +82,7 @@ public TableRenderSnapshot create(TableRenderSubject session, long version, long
session,
wind,
seatPlayerIds.get(wind),
onlineViewerIdSet,
serializedOnlineViewersById,
viewerMembershipSignatures,
viewerIdsExcluding
)
Expand Down Expand Up @@ -131,7 +154,7 @@ private TableSeatRenderSnapshot captureSeatSnapshot(
TableRenderSubject session,
SeatWind wind,
UUID playerId,
Set<UUID> onlineViewerIdSet,
Map<UUID, SerializedViewerId> serializedOnlineViewersById,
Map<UUID, String> viewerMembershipSignatures,
Map<UUID, List<UUID>> viewerIdsExcluding
) {
Expand All @@ -145,7 +168,7 @@ private TableSeatRenderSnapshot captureSeatSnapshot(
occupied && session.isRiichi(playerId),
occupied && session.isReady(playerId),
occupied && session.isQueuedToLeave(playerId),
occupied && onlineViewerIdSet.contains(playerId),
occupied && serializedOnlineViewersById.containsKey(playerId),
viewerMembershipSignatures.getOrDefault(playerId, ""),
occupied ? session.selectedHandTileIndex(playerId) : -1,
occupied ? session.selectedHandTileIndices(playerId) : List.of(),
Expand All @@ -160,14 +183,25 @@ private TableSeatRenderSnapshot captureSeatSnapshot(
);
}

private String viewerMembershipSignature(List<SerializedViewerId> onlineViewerIds, UUID excludedPlayerId) {
private StringBuilder viewerMembershipBuffer(List<SerializedViewerId> onlineViewerIds) {
StringBuilder builder = new StringBuilder(onlineViewerIds.size() * 36);
for (SerializedViewerId viewer : onlineViewerIds) {
if (!viewer.id().equals(excludedPlayerId)) {
builder.append(viewer.serializedId());
}
builder.append(viewer.serializedId());
}
return builder.toString();
return builder;
}

private String viewerMembershipSignature(
StringBuilder viewerMembershipBuffer,
SerializedViewerId excludedViewer,
int excludedViewerIndex
) {
String serializedId = excludedViewer.serializedId();
int start = excludedViewerIndex * serializedId.length();
viewerMembershipBuffer.delete(start, start + serializedId.length());
String signature = viewerMembershipBuffer.toString();
viewerMembershipBuffer.insert(start, serializedId);
return signature;
}

private List<UUID> viewerIdsExcluding(List<UUID> onlineViewerIds, UUID excludedPlayerId) {
Expand Down
Loading