72 lines
2.2 KiB
Java
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;
|
|
}
|
|
}
|