mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Front-end 'push' updates for SupplyRoutes
This commit is contained in:
parent
74142536e9
commit
e9917ba00e
@ -22,6 +22,7 @@ import {
|
||||
FrontLine,
|
||||
IadsConnection,
|
||||
NavMesh,
|
||||
SupplyRoute,
|
||||
Tgo,
|
||||
ThreatZones,
|
||||
UnculledZone,
|
||||
@ -32,6 +33,8 @@ import { threatZonesUpdated } from "./threatZonesSlice";
|
||||
import { unculledZonesUpdated } from "./unculledZonesSlice";
|
||||
import { LatLng } from "leaflet";
|
||||
import { updateIadsConnection, removeIadsConnection } from "./iadsNetworkSlice";
|
||||
import { IadsConnection } from "./_liberationApi";
|
||||
import { supplyRoutesUpdated } from "./supplyRoutesSlice";
|
||||
|
||||
interface GameUpdateEvents {
|
||||
updated_flight_positions: { [id: string]: LatLng };
|
||||
@ -52,6 +55,7 @@ interface GameUpdateEvents {
|
||||
updated_control_points: ControlPoint[];
|
||||
updated_iads: IadsConnection[];
|
||||
deleted_iads: string[];
|
||||
updated_supply_routes: SupplyRoute[];
|
||||
reset_on_map_center: LatLng | null;
|
||||
game_unloaded: boolean;
|
||||
new_turn: boolean;
|
||||
@ -135,6 +139,10 @@ export const handleStreamedEvents = (
|
||||
dispatch(updateIadsConnection(events.updated_iads));
|
||||
}
|
||||
|
||||
if (events.updated_supply_routes.length > 0) {
|
||||
dispatch(supplyRoutesUpdated(events.updated_supply_routes));
|
||||
}
|
||||
|
||||
if (events.reset_on_map_center != null) {
|
||||
reloadGameState(dispatch);
|
||||
}
|
||||
|
||||
@ -1,26 +1,46 @@
|
||||
import { RootState } from "../app/store";
|
||||
import { gameLoaded, gameUnloaded } from "./actions";
|
||||
import { SupplyRoute } from "./liberationApi";
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
|
||||
interface SupplyRoutesState {
|
||||
routes: SupplyRoute[];
|
||||
routes: { [id: string]: SupplyRoute };
|
||||
}
|
||||
|
||||
const initialState: SupplyRoutesState = {
|
||||
routes: [],
|
||||
routes: {},
|
||||
};
|
||||
|
||||
export const supplyRoutesSlice = createSlice({
|
||||
name: "supplyRoutes",
|
||||
initialState,
|
||||
reducers: {},
|
||||
reducers: {
|
||||
updated: (state, action: PayloadAction<SupplyRoute[]>) => {
|
||||
for (const route of action.payload) {
|
||||
const id = route.id;
|
||||
let points = route.points;
|
||||
if (points.length > 0) {
|
||||
state.routes[id] = route;
|
||||
} else if (id in state.routes) {
|
||||
points = state.routes[id].points;
|
||||
state.routes[id] = route;
|
||||
state.routes[id].points = points;
|
||||
} else {
|
||||
console.log("Trying to update a route that doesn't exist without points...");
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
builder.addCase(gameLoaded, (state, action) => {
|
||||
state.routes = action.payload.supply_routes;
|
||||
state.routes = {}
|
||||
for (const route of action.payload.supply_routes)
|
||||
{
|
||||
state.routes[route.id] = route;
|
||||
}
|
||||
});
|
||||
builder.addCase(gameUnloaded, (state) => {
|
||||
state.routes = [];
|
||||
state.routes = {};
|
||||
});
|
||||
},
|
||||
});
|
||||
@ -28,3 +48,5 @@ export const supplyRoutesSlice = createSlice({
|
||||
export const selectSupplyRoutes = (state: RootState) => state.supplyRoutes;
|
||||
|
||||
export default supplyRoutesSlice.reducer;
|
||||
|
||||
export const { updated: supplyRoutesUpdated } = supplyRoutesSlice.actions;
|
||||
|
||||
@ -56,8 +56,7 @@ export default function SupplyRoute(props: SupplyRouteProps) {
|
||||
return (
|
||||
<Polyline
|
||||
positions={props.route.points}
|
||||
color={color}
|
||||
weight={weight}
|
||||
pathOptions={{ color: color, weight: weight}}
|
||||
ref={(ref) => (path.current = ref)}
|
||||
>
|
||||
<SupplyRouteTooltip {...props} />
|
||||
|
||||
@ -7,7 +7,7 @@ export default function SupplyRoutesLayer() {
|
||||
const routes = useAppSelector(selectSupplyRoutes).routes;
|
||||
return (
|
||||
<LayerGroup>
|
||||
{routes.map((route) => {
|
||||
{Object.values(routes).map( route => {
|
||||
return <SupplyRoute key={route.id} route={route} />;
|
||||
})}
|
||||
</LayerGroup>
|
||||
|
||||
@ -15,6 +15,7 @@ from game.server.mapzones.models import ThreatZonesJs
|
||||
from game.server.navmesh.models import NavMeshJs
|
||||
from game.server.tgos.models import TgoJs
|
||||
from game.server.mapzones.models import UnculledZoneJs
|
||||
from game.server.supplyroutes.models import SupplyRouteJs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game import Game
|
||||
@ -40,6 +41,7 @@ class GameUpdateEventsJs(BaseModel):
|
||||
updated_control_points: list[ControlPointJs]
|
||||
updated_iads: list[IadsConnectionJs]
|
||||
deleted_iads: set[UUID]
|
||||
updated_supply_routes: list[SupplyRouteJs]
|
||||
reset_on_map_center: LeafletPoint | None
|
||||
game_unloaded: bool
|
||||
new_turn: bool
|
||||
@ -57,6 +59,7 @@ class GameUpdateEventsJs(BaseModel):
|
||||
updated_threat_zones = {}
|
||||
updated_unculled_zones = []
|
||||
updated_iads = []
|
||||
updated_supply_routes = []
|
||||
if game is not None:
|
||||
new_combats = [
|
||||
FrozenCombatJs.for_combat(c, game.theater) for c in events.new_combats
|
||||
@ -76,6 +79,10 @@ class GameUpdateEventsJs(BaseModel):
|
||||
updated_unculled_zones = UnculledZoneJs.from_game(game)
|
||||
for node in events.updated_iads:
|
||||
updated_iads.extend(IadsConnectionJs.connections_for_node(node))
|
||||
if events.updated_supply_routes:
|
||||
updated_supply_routes = SupplyRouteJs.all_in_game(game)
|
||||
for route in updated_supply_routes:
|
||||
route.points = []
|
||||
|
||||
return GameUpdateEventsJs(
|
||||
updated_flight_positions={
|
||||
@ -108,6 +115,7 @@ class GameUpdateEventsJs(BaseModel):
|
||||
],
|
||||
updated_iads=updated_iads,
|
||||
deleted_iads=events.deleted_iads_connections,
|
||||
updated_supply_routes=updated_supply_routes,
|
||||
reset_on_map_center=events.reset_on_map_center,
|
||||
game_unloaded=events.game_unloaded,
|
||||
new_turn=events.new_turn,
|
||||
|
||||
@ -64,7 +64,7 @@ class TransportFinder:
|
||||
|
||||
|
||||
class SupplyRouteJs(BaseModel):
|
||||
id: UUID
|
||||
id: str
|
||||
points: list[LeafletPoint]
|
||||
front_active: bool
|
||||
is_sea: bool
|
||||
@ -91,7 +91,7 @@ class SupplyRouteJs(BaseModel):
|
||||
#
|
||||
# https://reactjs.org/docs/lists-and-keys.html#keys
|
||||
# https://github.com/dcs-liberation/dcs_liberation/issues/2167
|
||||
id=uuid.uuid4(),
|
||||
id=f"{a}:{b}",
|
||||
points=[p.latlng() for p in points],
|
||||
front_active=not sea and a.front_is_active(b),
|
||||
is_sea=sea,
|
||||
|
||||
@ -38,6 +38,7 @@ class GameUpdateEvents:
|
||||
updated_control_points: set[ControlPoint] = field(default_factory=set)
|
||||
updated_iads: set[IadsNetworkNode] = field(default_factory=set)
|
||||
deleted_iads_connections: set[UUID] = field(default_factory=set)
|
||||
updated_supply_routes: bool = False
|
||||
reset_on_map_center: LatLng | None = None
|
||||
game_unloaded: bool = False
|
||||
new_turn: bool = False
|
||||
@ -133,6 +134,10 @@ class GameUpdateEvents:
|
||||
|
||||
def delete_iads_connection(self, connection_id: UUID) -> GameUpdateEvents:
|
||||
self.deleted_iads_connections.add(connection_id)
|
||||
return self.update_supply_routes()
|
||||
|
||||
def update_supply_routes(self) -> GameUpdateEvents:
|
||||
self.updated_supply_routes = True
|
||||
return self
|
||||
|
||||
def game_loaded(self, game: Game | None) -> GameUpdateEvents:
|
||||
|
||||
@ -571,6 +571,12 @@ class PendingTransfers:
|
||||
def __iter__(self) -> Iterator[TransferOrder]:
|
||||
yield from self.pending_transfers
|
||||
|
||||
def _send_supply_route_event_stream_update(self) -> None:
|
||||
from game.server import EventStream
|
||||
|
||||
with EventStream.event_context() as events:
|
||||
events.update_supply_routes()
|
||||
|
||||
@property
|
||||
def pending_transfer_count(self) -> int:
|
||||
return len(self.pending_transfers)
|
||||
@ -605,6 +611,7 @@ class PendingTransfers:
|
||||
transfer.origin.base.commit_losses(transfer.units)
|
||||
self.pending_transfers.append(transfer)
|
||||
self.arrange_transport(transfer)
|
||||
self._send_supply_route_event_stream_update()
|
||||
|
||||
def split_transfer(self, transfer: TransferOrder, size: int) -> TransferOrder:
|
||||
"""Creates a smaller transfer that is a subset of the original."""
|
||||
@ -659,6 +666,7 @@ class PendingTransfers:
|
||||
self.cancel_transport(transfer.transport, transfer)
|
||||
self.pending_transfers.remove(transfer)
|
||||
transfer.origin.base.commission_units(transfer.units)
|
||||
self._send_supply_route_event_stream_update()
|
||||
|
||||
def perform_transfers(self) -> None:
|
||||
"""
|
||||
@ -675,6 +683,7 @@ class PendingTransfers:
|
||||
self.pending_transfers = incomplete
|
||||
self.convoys.disband_all()
|
||||
self.cargo_ships.disband_all()
|
||||
self._send_supply_route_event_stream_update()
|
||||
|
||||
def plan_transports(self) -> None:
|
||||
"""
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user