Files
purpur-leaf/src/main/java/games/dmg/leaf/LeafStateManager.java
T

72 lines
2.2 KiB
Java

package games.dmg.leaf;
import java.io.IOException;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.function.UnaryOperator;
public final class LeafStateManager {
private final YamlLeafStateRepository repository;
private final Map<UUID, PlayerLeafState> players;
private boolean dirty;
public LeafStateManager(YamlLeafStateRepository repository) throws IOException {
this.repository = repository;
this.players = new HashMap<>(repository.load().players());
}
public synchronized PlayerLeafState observePlayer(
UUID playerId,
String latestName,
Instant observedAt
) {
PlayerLeafState existing = players.get(playerId);
PlayerLeafState observed = existing == null
? PlayerLeafState.newPlayer(playerId, latestName, observedAt)
: existing.withLatestName(latestName);
if (!observed.equals(existing)) {
players.put(playerId, observed);
dirty = true;
}
return observed;
}
public synchronized Optional<PlayerLeafState> find(UUID playerId) {
return Optional.ofNullable(players.get(playerId));
}
public synchronized Map<UUID, PlayerLeafState> players() {
return Map.copyOf(players);
}
public synchronized PlayerLeafState update(
UUID playerId,
UnaryOperator<PlayerLeafState> change
) {
PlayerLeafState existing = players.get(playerId);
if (existing == null) {
throw new IllegalArgumentException("unknown player: " + playerId);
}
PlayerLeafState updated = change.apply(existing);
if (!playerId.equals(updated.playerId())) {
throw new IllegalArgumentException("an update cannot change the player ID");
}
if (!updated.equals(existing)) {
players.put(playerId, updated);
dirty = true;
}
return updated;
}
public synchronized void saveIfDirty() throws IOException {
if (!dirty) {
return;
}
repository.save(new LeafPersistentState(players));
dirty = false;
}
}