Handle IADS updates properly.

This adds the missing events in the backend, and handles them properly in the front end.
This commit is contained in:
Raffson 2022-06-30 03:58:49 +02:00 committed by GitHub
parent 5f071a6138
commit 27dff95df5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 47 additions and 14 deletions

View File

@ -31,7 +31,7 @@ import { updateTgo } from "./tgosSlice";
import { threatZonesUpdated } from "./threatZonesSlice"; import { threatZonesUpdated } from "./threatZonesSlice";
import { unculledZonesUpdated } from "./unculledZonesSlice"; import { unculledZonesUpdated } from "./unculledZonesSlice";
import { LatLng } from "leaflet"; import { LatLng } from "leaflet";
import { updateIadsConnection } from "./iadsNetworkSlice"; import { updateIadsConnection, removeIadsConnection } from "./iadsNetworkSlice";
interface GameUpdateEvents { interface GameUpdateEvents {
updated_flight_positions: { [id: string]: LatLng }; updated_flight_positions: { [id: string]: LatLng };
@ -50,6 +50,8 @@ interface GameUpdateEvents {
deleted_front_lines: string[]; deleted_front_lines: string[];
updated_tgos: string[]; updated_tgos: string[];
updated_control_points: ControlPoint[]; updated_control_points: ControlPoint[];
updated_iads: IadsConnection[];
deleted_iads: string[];
reset_on_map_center: LatLng | null; reset_on_map_center: LatLng | null;
game_unloaded: boolean; game_unloaded: boolean;
new_turn: boolean; new_turn: boolean;
@ -134,17 +136,20 @@ export const handleStreamedEvents = (
const tgo = response.data as Tgo; const tgo = response.data as Tgo;
dispatch(updateTgo(tgo)); dispatch(updateTgo(tgo));
}); });
backend.get(`/iads-network/for-tgo/${id}`).then((response) => {
for (const connection of response.data) {
dispatch(updateIadsConnection(connection as IadsConnection));
}
});
} }
if (events.updated_control_points.length > 0) { if (events.updated_control_points.length > 0) {
dispatch(updateControlPoint(events.updated_control_points)); dispatch(updateControlPoint(events.updated_control_points));
} }
if (events.deleted_iads.length > 0) {
dispatch(removeIadsConnection(events.deleted_iads));
}
if (events.updated_iads.length > 0) {
dispatch(updateIadsConnection(events.updated_iads));
}
if (events.reset_on_map_center != null) { if (events.reset_on_map_center != null) {
reloadGameState(dispatch); reloadGameState(dispatch);
} }

View File

@ -15,10 +15,16 @@ export const IadsNetworkSlice = createSlice({
name: "iadsNetwork", name: "iadsNetwork",
initialState, initialState,
reducers: { reducers: {
updateIadsConnection: (state, action: PayloadAction<IadsConnection>) => { updateIadsConnection: (state, action: PayloadAction<IadsConnection[]>) => {
const connection = action.payload; for (const connection of action.payload) {
state.connections[connection.id] = connection state.connections[connection.id] = connection
}
}, },
removeIadsConnection: (state, action: PayloadAction<string[]>) => {
for (const cID of action.payload) {
delete state.connections[cID];
}
}
}, },
extraReducers: (builder) => { extraReducers: (builder) => {
builder.addCase(gameLoaded, (state, action) => { builder.addCase(gameLoaded, (state, action) => {
@ -36,7 +42,7 @@ export const IadsNetworkSlice = createSlice({
}, },
}); });
export const { updateIadsConnection } = IadsNetworkSlice.actions; export const { updateIadsConnection, removeIadsConnection } = IadsNetworkSlice.actions;
export const selectIadsNetwork = (state: RootState) => state.iadsNetwork; export const selectIadsNetwork = (state: RootState) => state.iadsNetwork;

View File

@ -9,6 +9,7 @@ from game.server.combat.models import FrozenCombatJs
from game.server.controlpoints.models import ControlPointJs from game.server.controlpoints.models import ControlPointJs
from game.server.flights.models import FlightJs from game.server.flights.models import FlightJs
from game.server.frontlines.models import FrontLineJs from game.server.frontlines.models import FrontLineJs
from game.server.iadsnetwork.models import IadsConnectionJs
from game.server.leaflet import LeafletPoint from game.server.leaflet import LeafletPoint
from game.server.mapzones.models import UnculledZoneJs from game.server.mapzones.models import UnculledZoneJs
@ -34,6 +35,8 @@ class GameUpdateEventsJs(BaseModel):
deleted_front_lines: set[UUID] deleted_front_lines: set[UUID]
updated_tgos: set[UUID] updated_tgos: set[UUID]
updated_control_points: list[ControlPointJs] updated_control_points: list[ControlPointJs]
updated_iads: list[IadsConnectionJs]
deleted_iads: set[UUID]
reset_on_map_center: LeafletPoint | None reset_on_map_center: LeafletPoint | None
game_unloaded: bool game_unloaded: bool
new_turn: bool new_turn: bool
@ -48,6 +51,7 @@ class GameUpdateEventsJs(BaseModel):
new_combats = [] new_combats = []
updated_combats = [] updated_combats = []
updated_unculled_zones = [] updated_unculled_zones = []
updated_iads = []
if game is not None: if game is not None:
new_combats = [ new_combats = [
FrozenCombatJs.for_combat(c, game.theater) for c in events.new_combats FrozenCombatJs.for_combat(c, game.theater) for c in events.new_combats
@ -57,6 +61,8 @@ class GameUpdateEventsJs(BaseModel):
for c in events.updated_combats for c in events.updated_combats
] ]
updated_unculled_zones = UnculledZoneJs.from_game(game) updated_unculled_zones = UnculledZoneJs.from_game(game)
for node in events.updated_iads:
updated_iads.extend(IadsConnectionJs.connections_for_node(node))
return GameUpdateEventsJs( return GameUpdateEventsJs(
updated_flight_positions={ updated_flight_positions={
@ -87,6 +93,8 @@ class GameUpdateEventsJs(BaseModel):
ControlPointJs.for_control_point(cp) ControlPointJs.for_control_point(cp)
for cp in events.updated_control_points for cp in events.updated_control_points
], ],
updated_iads=updated_iads,
deleted_iads=events.deleted_iads_connections,
reset_on_map_center=events.reset_on_map_center, reset_on_map_center=events.reset_on_map_center,
game_unloaded=events.game_unloaded, game_unloaded=events.game_unloaded,
new_turn=events.new_turn, new_turn=events.new_turn,

View File

@ -12,6 +12,7 @@ if TYPE_CHECKING:
from game.ato import Flight, Package from game.ato import Flight, Package
from game.sim.combat import FrozenCombat from game.sim.combat import FrozenCombat
from game.theater import ControlPoint, FrontLine, TheaterGroundObject from game.theater import ControlPoint, FrontLine, TheaterGroundObject
from game.theater.iadsnetwork.iadsnetwork import IadsNetworkNode
@dataclass @dataclass
@ -33,6 +34,8 @@ class GameUpdateEvents:
deleted_front_lines: set[UUID] = field(default_factory=set) deleted_front_lines: set[UUID] = field(default_factory=set)
updated_tgos: set[UUID] = field(default_factory=set) updated_tgos: set[UUID] = field(default_factory=set)
updated_control_points: set[ControlPoint] = field(default_factory=set) 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)
reset_on_map_center: LatLng | None = None reset_on_map_center: LatLng | None = None
game_unloaded: bool = False game_unloaded: bool = False
new_turn: bool = False new_turn: bool = False
@ -121,6 +124,14 @@ class GameUpdateEvents:
self.updated_control_points.add(control_point) self.updated_control_points.add(control_point)
return self return self
def update_iads_node(self, iads_node: IadsNetworkNode) -> GameUpdateEvents:
self.updated_iads.add(iads_node)
return self
def delete_iads_connection(self, connection_id: UUID) -> GameUpdateEvents:
self.deleted_iads_connections.add(connection_id)
return self
def game_loaded(self, game: Game | None) -> GameUpdateEvents: def game_loaded(self, game: Game | None) -> GameUpdateEvents:
if game is None: if game is None:
self.game_unloaded = True self.game_unloaded = True

View File

@ -843,7 +843,7 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
tgo, VehicleGroupGroundObject tgo, VehicleGroupGroundObject
): ):
if isinstance(tgo, IadsGroundObject): if isinstance(tgo, IadsGroundObject):
game.theater.iads_network.update_tgo(tgo) game.theater.iads_network.update_tgo(tgo, events)
conflict_heading = game.theater.heading_to_conflict_from(tgo.position) conflict_heading = game.theater.heading_to_conflict_from(tgo.position)
tgo.rotate(conflict_heading or tgo.heading) tgo.rotate(conflict_heading or tgo.heading)
if not tgo.is_control_point: if not tgo.is_control_point:

View File

@ -18,6 +18,7 @@ from game.theater.theatergroup import IadsGroundGroup
if TYPE_CHECKING: if TYPE_CHECKING:
from game.game import Game from game.game import Game
from game.sim import GameUpdateEvents
class IadsNetworkException(Exception): class IadsNetworkException(Exception):
@ -133,19 +134,21 @@ class IadsNetwork:
skynet_nodes.append(skynet_node) skynet_nodes.append(skynet_node)
return skynet_nodes return skynet_nodes
def update_tgo(self, tgo: TheaterGroundObject) -> None: def update_tgo(self, tgo: TheaterGroundObject, events: GameUpdateEvents) -> None:
"""Update the IADS Network for the given TGO""" """Update the IADS Network for the given TGO"""
# Remove existing nodes for the given tgo # Remove existing nodes for the given tgo
for cn in self.nodes: for cn in self.nodes:
if cn.group.ground_object == tgo: if cn.group.ground_object == tgo:
self.nodes.remove(cn) self.nodes.remove(cn)
for cID in cn.connections:
events.delete_iads_connection(cID)
# Create a new node for the tgo
node = self.node_for_tgo(tgo) node = self.node_for_tgo(tgo)
if node is None: if node is None:
# Not participating # Not participating
return return
# TODO Add the connections or calculate them.. # TODO Add the connections or calculate them..
events.update_iads_node(node)
def node_for_group(self, group: IadsGroundGroup) -> IadsNetworkNode: def node_for_group(self, group: IadsGroundGroup) -> IadsNetworkNode:
"""Get existing node from the iads network or create a new node""" """Get existing node from the iads network or create a new node"""

View File

@ -258,7 +258,7 @@ class QGroundObjectMenu(QDialog):
def update_game(self) -> None: def update_game(self) -> None:
events = GameUpdateEvents() events = GameUpdateEvents()
events.update_tgo(self.ground_object) events.update_tgo(self.ground_object)
self.game.theater.iads_network.update_tgo(self.ground_object) self.game.theater.iads_network.update_tgo(self.ground_object, events)
if any( if any(
package.target == self.ground_object package.target == self.ground_object
for package in self.game.ato_for(player=False).packages for package in self.game.ato_for(player=False).packages