From 85a055ec91fea370b474ac076fed0c9b5ae3db89 Mon Sep 17 00:00:00 2001 From: Jonathan Bourdon Date: Tue, 24 Mar 2026 03:03:13 -0400 Subject: [PATCH] refactor: replace `SpaceLayerKinds` with strongly-typed `SpaceLayerKind` enum Replaces string-based `SpaceLayerKinds` constants with a strongly-typed `SpaceLayerKind` enum. Updates backend services, runtime models, and projection logic to use the new enum. Adds `ToContractValue` method for compatibility with existing contracts. --- .../backend/Shared/Runtime/SimulationKinds.cs | 19 ++++++-- .../backend/Ships/Simulation/ShipAiService.cs | 46 +++++++++---------- .../Core/SimulationProjectionService.cs | 4 +- .../Simulation/StationLifecycleService.cs | 2 +- .../Universe/Runtime/SpatialRuntimeModels.cs | 2 +- .../Universe/Scenario/SpatialBuilder.cs | 2 +- .../Simulation/OrbitalStateUpdater.cs | 2 +- 7 files changed, 43 insertions(+), 34 deletions(-) diff --git a/apps/backend/Shared/Runtime/SimulationKinds.cs b/apps/backend/Shared/Runtime/SimulationKinds.cs index 394073c..d6d7084 100644 --- a/apps/backend/Shared/Runtime/SimulationKinds.cs +++ b/apps/backend/Shared/Runtime/SimulationKinds.cs @@ -86,12 +86,12 @@ public enum ShipState Fleeing, } -public static class SpaceLayerKinds +public enum SpaceLayerKind { - public const string UniverseSpace = "universe-space"; - public const string GalaxySpace = "galaxy-space"; - public const string SystemSpace = "system-space"; - public const string LocalSpace = "local-space"; + UniverseSpace, + GalaxySpace, + SystemSpace, + LocalSpace, } public static class MovementRegimeKinds @@ -274,4 +274,13 @@ public static class SimulationEnumMappings ShipState.Fleeing => "fleeing", _ => throw new ArgumentOutOfRangeException(nameof(state), state, null), }; + + public static string ToContractValue(this SpaceLayerKind kind) => kind switch + { + SpaceLayerKind.UniverseSpace => "universe-space", + SpaceLayerKind.GalaxySpace => "galaxy-space", + SpaceLayerKind.SystemSpace => "system-space", + SpaceLayerKind.LocalSpace => "local-space", + _ => throw new ArgumentOutOfRangeException(nameof(kind), kind, null), + }; } diff --git a/apps/backend/Ships/Simulation/ShipAiService.cs b/apps/backend/Ships/Simulation/ShipAiService.cs index 6090922..59348d2 100644 --- a/apps/backend/Ships/Simulation/ShipAiService.cs +++ b/apps/backend/Ships/Simulation/ShipAiService.cs @@ -1646,7 +1646,7 @@ internal sealed class ShipAiService bool completeOnArrival) { var distance = ship.Position.DistanceTo(targetPosition); - ship.SpatialState.SpaceLayer = SpaceLayerKinds.LocalSpace; + ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace; ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight; ship.SpatialState.Transit = null; ship.SpatialState.DestinationNodeId = targetCelestial?.Id; @@ -1691,7 +1691,7 @@ internal sealed class ShipAiService subTask.ElapsedSeconds = 0f; } - ship.SpatialState.SpaceLayer = SpaceLayerKinds.SystemSpace; + ship.SpatialState.SpaceLayer = SpaceLayerKind.SystemSpace; ship.SpatialState.MovementRegime = MovementRegimeKinds.Warp; ship.SpatialState.CurrentCelestialId = null; ship.SpatialState.DestinationNodeId = targetCelestial.Id; @@ -1748,7 +1748,7 @@ internal sealed class ShipAiService subTask.ElapsedSeconds = 0f; } - ship.SpatialState.SpaceLayer = SpaceLayerKinds.GalaxySpace; + ship.SpatialState.SpaceLayer = SpaceLayerKind.GalaxySpace; ship.SpatialState.MovementRegime = MovementRegimeKinds.FtlTransit; ship.SpatialState.CurrentCelestialId = null; ship.SpatialState.DestinationNodeId = destinationNodeId; @@ -1779,7 +1779,7 @@ internal sealed class ShipAiService ship.SystemId = targetSystemId; ship.SpatialState.CurrentSystemId = targetSystemId; ship.SpatialState.Transit = null; - ship.SpatialState.SpaceLayer = SpaceLayerKinds.LocalSpace; + ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace; ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight; ship.SpatialState.CurrentCelestialId = targetCelestial?.Id; ship.SpatialState.DestinationNodeId = targetCelestial?.Id; @@ -1794,7 +1794,7 @@ internal sealed class ShipAiService ship.SystemId = targetSystemId; ship.SpatialState.CurrentSystemId = targetSystemId; ship.SpatialState.Transit = null; - ship.SpatialState.SpaceLayer = SpaceLayerKinds.LocalSpace; + ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace; ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight; ship.SpatialState.CurrentCelestialId = targetCelestial?.Id; ship.SpatialState.DestinationNodeId = targetCelestial?.Id; @@ -2095,27 +2095,27 @@ internal sealed class ShipAiService var source = stationsById.Values .Where(station => { - if (station.Id == destination.Id || GetInventoryAmount(station.Inventory, order.ItemId) <= GetStationReserveFloor(world, station, order.ItemId) + 1f) - { - return false; - } + if (station.Id == destination.Id || GetInventoryAmount(station.Inventory, order.ItemId) <= GetStationReserveFloor(world, station, order.ItemId) + 1f) + { + return false; + } - if (!TryCheckSystemAllowed(world, policy, ship.FactionId, station.SystemId, "trade", out var sourceDeniedReason)) - { - deniedReason ??= sourceDeniedReason; - return false; - } + if (!TryCheckSystemAllowed(world, policy, ship.FactionId, station.SystemId, "trade", out var sourceDeniedReason)) + { + deniedReason ??= sourceDeniedReason; + return false; + } - if (!IsWithinSystemRange(world, originSystemId, station.SystemId, rangeBudget)) - { - return false; - } + if (!IsWithinSystemRange(world, originSystemId, station.SystemId, rangeBudget)) + { + return false; + } - return !requireKnownStations - || ship.KnownStationIds.Count == 0 - || ship.KnownStationIds.Contains(station.Id) - || (homeStation is not null && string.Equals(station.Id, homeStation.Id, StringComparison.Ordinal)); - }) + return !requireKnownStations + || ship.KnownStationIds.Count == 0 + || ship.KnownStationIds.Contains(station.Id) + || (homeStation is not null && string.Equals(station.Id, homeStation.Id, StringComparison.Ordinal)); + }) .OrderByDescending(station => GetInventoryAmount(station.Inventory, order.ItemId) - GetStationReserveFloor(world, station, order.ItemId)) .ThenByDescending(station => homeStation is not null && station.Id == homeStation.Id ? 1 : 0) .ThenBy(station => station.Id, StringComparer.Ordinal) diff --git a/apps/backend/Simulation/Core/SimulationProjectionService.cs b/apps/backend/Simulation/Core/SimulationProjectionService.cs index d40ceaf..345587a 100644 --- a/apps/backend/Simulation/Core/SimulationProjectionService.cs +++ b/apps/backend/Simulation/Core/SimulationProjectionService.cs @@ -578,7 +578,7 @@ internal sealed class SimulationProjectionService ship.DockedStationId ?? "none", ship.CommanderId ?? "none", ship.PolicySetId ?? "none", - ship.SpatialState.SpaceLayer, + ship.SpatialState.SpaceLayer.ToContractValue(), ship.SpatialState.CurrentCelestialId ?? "none", ship.SpatialState.MovementRegime, ship.SpatialState.DestinationNodeId ?? "none", @@ -1872,7 +1872,7 @@ internal sealed class SimulationProjectionService } private static ShipSpatialStateSnapshot ToShipSpatialStateSnapshot(ShipSpatialStateRuntime state) => new( - state.SpaceLayer, + state.SpaceLayer.ToContractValue(), state.CurrentSystemId, state.CurrentCelestialId, state.LocalPosition is null ? null : ToDto(state.LocalPosition.Value), diff --git a/apps/backend/Stations/Simulation/StationLifecycleService.cs b/apps/backend/Stations/Simulation/StationLifecycleService.cs index 7ff361c..4863b65 100644 --- a/apps/backend/Stations/Simulation/StationLifecycleService.cs +++ b/apps/backend/Stations/Simulation/StationLifecycleService.cs @@ -97,7 +97,7 @@ internal sealed class StationLifecycleService private static ShipSpatialStateRuntime CreateSpawnedShipSpatialState(StationRuntime station, Vector3 position) => new() { CurrentSystemId = station.SystemId, - SpaceLayer = SpaceLayerKinds.LocalSpace, + SpaceLayer = SpaceLayerKind.LocalSpace, CurrentCelestialId = station.CelestialId, LocalPosition = position, SystemPosition = position, diff --git a/apps/backend/Universe/Runtime/SpatialRuntimeModels.cs b/apps/backend/Universe/Runtime/SpatialRuntimeModels.cs index cdda136..c61a870 100644 --- a/apps/backend/Universe/Runtime/SpatialRuntimeModels.cs +++ b/apps/backend/Universe/Runtime/SpatialRuntimeModels.cs @@ -50,7 +50,7 @@ public sealed class WreckRuntime public sealed class ShipSpatialStateRuntime { - public string SpaceLayer { get; set; } = SpaceLayerKinds.LocalSpace; + public SpaceLayerKind SpaceLayer { get; set; } = SpaceLayerKind.LocalSpace; public required string CurrentSystemId { get; set; } public string? CurrentCelestialId { get; set; } public Vector3? LocalPosition { get; set; } diff --git a/apps/backend/Universe/Scenario/SpatialBuilder.cs b/apps/backend/Universe/Scenario/SpatialBuilder.cs index 2c82783..ab52939 100644 --- a/apps/backend/Universe/Scenario/SpatialBuilder.cs +++ b/apps/backend/Universe/Scenario/SpatialBuilder.cs @@ -296,7 +296,7 @@ internal sealed class SpatialBuilder return new ShipSpatialStateRuntime { CurrentSystemId = systemId, - SpaceLayer = SpaceLayerKinds.LocalSpace, + SpaceLayer = SpaceLayerKind.LocalSpace, CurrentCelestialId = nearestCelestial?.Id, LocalPosition = position, SystemPosition = position, diff --git a/apps/backend/Universe/Simulation/OrbitalStateUpdater.cs b/apps/backend/Universe/Simulation/OrbitalStateUpdater.cs index 8a1e7b2..77e090e 100644 --- a/apps/backend/Universe/Simulation/OrbitalStateUpdater.cs +++ b/apps/backend/Universe/Simulation/OrbitalStateUpdater.cs @@ -268,7 +268,7 @@ internal sealed class OrbitalStateUpdater continue; } - ship.SpatialState.SpaceLayer = SpaceLayerKinds.LocalSpace; + ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace; ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight; var nearestCelestial = world.Celestials .Where(candidate => candidate.SystemId == ship.SystemId)