Implement per-school save functionality by introducing a dedicated save directory and updating the school management system to support loading and saving school states. Revise documentation to reflect these changes, including updates to the architecture and design documents, and enhance the API for reloading schools from disk. Update tests to ensure proper functionality of the new save and reload features.
This commit is contained in:
@@ -22,13 +22,25 @@ public sealed class School : IDisposable
|
||||
World = World.Create();
|
||||
}
|
||||
|
||||
/// <summary>A brand-new school: calendar running at the start date, empty world.</summary>
|
||||
public static School Create(int id, string name, DateTime startDate) => new(id, name, startDate);
|
||||
|
||||
/// <summary>Rebuilds a school from a save. Time, pause and speed come from disk, not defaults.</summary>
|
||||
public static School Load(int id, string name, DateTime time, bool running, int speedIndex)
|
||||
{
|
||||
var school = new School(id, name, time);
|
||||
school.Clock.IsRunning = running;
|
||||
school.Clock.SpeedIndex = speedIndex;
|
||||
return school;
|
||||
}
|
||||
|
||||
public int Id { get; }
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public GameClock Clock { get; }
|
||||
|
||||
/// <summary>The Arch world backing this school. Only the loop thread may touch it.</summary>
|
||||
/// <summary>The Arch world backing this school. Only this school's worker thread may touch it.</summary>
|
||||
public World World { get; }
|
||||
|
||||
/// <summary>Runs one fixed step of the school. Today that is only the calendar.</summary>
|
||||
|
||||
@@ -18,8 +18,8 @@ public readonly record struct SchoolCreationResult(School? School, SchoolCreatio
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Every school that currently exists, plus the cap from configuration. Not thread-safe by design —
|
||||
/// only the loop thread touches it, everything else goes through the command queue in the server.
|
||||
/// In-memory set of schools plus the cap from configuration. Not thread-safe — unit tests and
|
||||
/// name/limit checks use it; the live server gives each school its own worker instead.
|
||||
/// </summary>
|
||||
public sealed class SchoolRegistry : IDisposable
|
||||
{
|
||||
@@ -67,7 +67,7 @@ public sealed class SchoolRegistry : IDisposable
|
||||
return SchoolCreationResult.Failed(SchoolCreationError.InvalidStartDate);
|
||||
}
|
||||
|
||||
var school = new School(_nextId++, normalized, startDate);
|
||||
var school = School.Create(_nextId++, normalized, startDate);
|
||||
_schools.Add(school);
|
||||
|
||||
return new SchoolCreationResult(school, SchoolCreationError.None);
|
||||
|
||||
@@ -26,8 +26,21 @@ public sealed class SimulationOptions
|
||||
set => _defaultStartDate = DateTime.SpecifyKind(value, DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Directory for per-school save files. Relative paths are resolved against the content root.
|
||||
/// </summary>
|
||||
public string SavesDirectory { get; set; } = "saves";
|
||||
|
||||
/// <summary>
|
||||
/// How often a running school writes its clock to disk. Create, pause, speed and shutdown
|
||||
/// write immediately; the tick itself never does.
|
||||
/// </summary>
|
||||
public int SaveIntervalSeconds { get; set; } = 30;
|
||||
|
||||
/// <summary>Length of one fixed step.</summary>
|
||||
public double FixedDeltaTime => 1d / TickRate;
|
||||
|
||||
public TimeSpan TickInterval => TimeSpan.FromSeconds(1d / TickRate);
|
||||
|
||||
public TimeSpan SaveInterval => TimeSpan.FromSeconds(SaveIntervalSeconds);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user