Consolidate persistence service contract

This commit is contained in:
George
2026-06-07 14:03:55 +01:00
parent 4f5a067300
commit 482e981c36
5 changed files with 22 additions and 50 deletions
@@ -1,6 +1,5 @@
package com.livingworld.core.services; package com.livingworld.core.services;
import com.livingworld.core.simulation.PersistenceService;
import com.livingworld.core.simulation.RegionManager; import com.livingworld.core.simulation.RegionManager;
import com.livingworld.core.simulation.SimulationManager; import com.livingworld.core.simulation.SimulationManager;
import com.livingworld.events.LivingWorldEventBus; import com.livingworld.events.LivingWorldEventBus;
@@ -1,39 +0,0 @@
package com.livingworld.core.simulation;
import java.util.Optional;
import com.livingworld.regions.Region;
import com.livingworld.regions.RegionCoordinate;
/**
* Handles region persistence (save/load) and migration support.
*
* <p><b>TODO (Milestone 8):</b> Implement actual file or database I/O,
* platform-specific save paths, and schema versioning.</p>
*/
public interface PersistenceService {
/**
* Saves a region to persistent storage.
*
* @param region the region to save (must not be null)
*/
void save(Region region);
/**
* Loads a region from persistent storage.
*
* @param coordinate the region coordinate to load (must not be null)
* @return an optional containing the loaded region if found, otherwise empty
*/
Optional<Region> load(RegionCoordinate coordinate);
/**
* Returns whether this persistence service supports data migration.
*
* <p><b>TODO:</b> Implement schema version detection and migration logic.</p>
*
* @return true if migration is supported
*/
boolean supportsMigration();
}
@@ -4,6 +4,7 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import com.livingworld.core.services.PersistenceService;
import com.livingworld.core.services.TimeService; import com.livingworld.core.services.TimeService;
import com.livingworld.debug.DiagnosticCategory; import com.livingworld.debug.DiagnosticCategory;
import com.livingworld.debug.LivingWorldLogger; import com.livingworld.debug.LivingWorldLogger;
@@ -17,6 +17,7 @@ import java.util.Set;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import com.livingworld.config.SimulationConfig; import com.livingworld.config.SimulationConfig;
import com.livingworld.core.services.PersistenceService;
import com.livingworld.core.services.TimeService; import com.livingworld.core.services.TimeService;
import com.livingworld.data.serialization.PersistenceReader; import com.livingworld.data.serialization.PersistenceReader;
import com.livingworld.data.serialization.PersistenceWriter; import com.livingworld.data.serialization.PersistenceWriter;
@@ -240,9 +241,13 @@ class SimulationManagerTest {
} }
private static final class TestPersistenceService implements PersistenceService { private static final class TestPersistenceService implements PersistenceService {
@Override public void save(Region region) {} @Override public void markRegionDirty(Region region) { region.markDirty(); }
@Override public Optional<Region> load(RegionCoordinate coordinate) { return Optional.empty(); } @Override public void saveDirtyRegions() {}
@Override public boolean supportsMigration() { return false; } @Override public void saveRegion(Region region) {}
@Override public Optional<Region> loadRegion(RegionCoordinate coordinate) {
return Optional.empty();
}
@Override public void flushAll() {}
} }
private static final class TestProfiler implements SimulationProfiler { private static final class TestProfiler implements SimulationProfiler {
@@ -5,9 +5,9 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import com.livingworld.config.SimulationConfig; import com.livingworld.config.SimulationConfig;
import com.livingworld.core.services.PersistenceService;
import com.livingworld.core.services.ServiceRegistry; import com.livingworld.core.services.ServiceRegistry;
import com.livingworld.core.simulation.DefaultTimeService; import com.livingworld.core.simulation.DefaultTimeService;
import com.livingworld.core.simulation.PersistenceService;
import com.livingworld.core.simulation.RegionManager; import com.livingworld.core.simulation.RegionManager;
import com.livingworld.core.simulation.RegionUpdateJob; import com.livingworld.core.simulation.RegionUpdateJob;
import com.livingworld.core.simulation.SimulationManager; import com.livingworld.core.simulation.SimulationManager;
@@ -174,11 +174,12 @@ class LongRunSimulationTest {
this.regions = regions; this.regions = regions;
} }
private void saveDirtyRegions() { @Override
public void saveDirtyRegions() {
maxDirtyObserved = Math.max(maxDirtyObserved, countDirtyRegions()); maxDirtyObserved = Math.max(maxDirtyObserved, countDirtyRegions());
regions.stream() regions.stream()
.filter(Region::isDirty) .filter(Region::isDirty)
.forEach(this::save); .forEach(this::saveRegion);
} }
private int countDirtyRegions() { private int countDirtyRegions() {
@@ -194,20 +195,25 @@ class LongRunSimulationTest {
} }
@Override @Override
public void save(Region region) { public void markRegionDirty(Region region) {
region.markDirty();
}
@Override
public void saveRegion(Region region) {
savedRegions.put(region.getCoordinate(), region); savedRegions.put(region.getCoordinate(), region);
region.clearDirty(); region.clearDirty();
saveCount++; saveCount++;
} }
@Override @Override
public Optional<Region> load(RegionCoordinate coordinate) { public Optional<Region> loadRegion(RegionCoordinate coordinate) {
return Optional.ofNullable(savedRegions.get(coordinate)); return Optional.ofNullable(savedRegions.get(coordinate));
} }
@Override @Override
public boolean supportsMigration() { public void flushAll() {
return false; saveDirtyRegions();
} }
} }
} }