Add websocket handling for selected flights.

This commit is contained in:
Dan Albert
2022-03-01 20:42:59 -08:00
parent 6d29bfdf65
commit 8e8bbe84f3
13 changed files with 190 additions and 13 deletions

View File

@@ -4,4 +4,6 @@ export const backend = axios.create({
baseURL: "http://[::1]:5000/",
});
export const WEBSOCKET_URL = "ws://[::1]:5000/eventstream";
export default backend;

View File

@@ -0,0 +1,36 @@
import { deselectFlight, selectFlight } from "./flightsSlice";
import { AppDispatch } from "../app/store";
import { Flight } from "./flight";
import { LatLng } from "leaflet";
// Placeholder. We don't use this yet. This is just here so we can flesh out the
// update events model.
interface FrozenCombat {}
interface GameUpdateEvents {
updated_flight_positions: { [id: string]: LatLng };
new_combats: FrozenCombat[];
updated_combats: FrozenCombat[];
ended_combats: string[];
navmesh_updates: boolean[];
unculled_zones_updated: boolean;
threat_zones_updated: boolean;
new_flights: Flight[];
updated_flights: string[];
deleted_flights: string[];
selected_flight: string | null;
deselected_flight: boolean;
}
export const handleStreamedEvents = (
dispatch: AppDispatch,
events: GameUpdateEvents
) => {
if (events.deselected_flight) {
dispatch(deselectFlight());
}
if (events.selected_flight != null) {
dispatch(selectFlight(events.selected_flight));
}
};

View File

@@ -6,11 +6,13 @@ import { RootState } from "../app/store";
interface FlightsState {
blue: { [id: string]: Flight };
red: { [id: string]: Flight };
selected: Flight | null;
}
const initialState: FlightsState = {
blue: {},
red: {},
selected: null,
};
export const flightsSlice = createSlice({
@@ -42,11 +44,23 @@ export const flightsSlice = createSlice({
);
}
},
deselectFlight: (state) => {
state.selected = null;
},
selectFlight: (state, action: PayloadAction<string>) => {
const id = action.payload;
state.selected = state.blue[id];
},
},
});
export const { clearFlights, registerFlight, unregisterFlight } =
flightsSlice.actions;
export const {
clearFlights,
registerFlight,
unregisterFlight,
deselectFlight,
selectFlight,
} = flightsSlice.actions;
export const selectFlights = (state: RootState) => state.flights;

View File

@@ -1,37 +0,0 @@
import { ControlPoint } from "./controlpoint";
import { Flight } from "./flight";
import backend from "./backend";
import { registerFlight } from "./flightsSlice";
import { setControlPoints } from "./controlPointsSlice";
import { useAppDispatch } from "../app/hooks";
import { useEffect } from "react";
// TODO: This should probably be distinct useControlPoints, useFlights, etc that
// are smart enough to only initialize once which get called in the components
// that use them rather than forcibly loading the whole game in the root
// component.
export const useInitialGameState = () => {
const dispatch = useAppDispatch();
useEffect(() => {
backend
.get("/control-points")
.catch((error) => console.log(`Error fetching control points: ${error}`))
.then((response) => {
if (response != null) {
dispatch(setControlPoints(response.data as ControlPoint[]));
}
});
backend
.get("/flights?with_waypoints=true")
.catch((error) => console.log(`Error fetching flights: ${error}`))
.then((response) => {
if (response != null) {
for (const flight of response.data) {
dispatch(registerFlight(flight as Flight));
}
}
});
});
};
export default useInitialGameState;