From 33f6657978dd9fed699b53f20010dbe3922970b2 Mon Sep 17 00:00:00 2001 From: Saschl <19493808+Saschl@users.noreply.github.com> Date: Tue, 12 Sep 2023 15:12:08 +0200 Subject: [PATCH] feat: only redraw payload seat map when needed (#8199) * feat: less drawing on payload page * fix: initial page load being empty sometimes * fix: remove duplicate useEffect * cleanup * feat: make seat selection snappier --- .../Pages/Payload/Seating/SeatMapWidget.tsx | 48 +++++++------------ .../instruments/src/react/bitFlags.tsx | 17 +++---- 2 files changed, 27 insertions(+), 38 deletions(-) diff --git a/fbw-a32nx/src/systems/instruments/src/EFB/Ground/Pages/Payload/Seating/SeatMapWidget.tsx b/fbw-a32nx/src/systems/instruments/src/EFB/Ground/Pages/Payload/Seating/SeatMapWidget.tsx index d1050d5ba2e..8bf59d2b6bc 100644 --- a/fbw-a32nx/src/systems/instruments/src/EFB/Ground/Pages/Payload/Seating/SeatMapWidget.tsx +++ b/fbw-a32nx/src/systems/instruments/src/EFB/Ground/Pages/Payload/Seating/SeatMapWidget.tsx @@ -92,7 +92,7 @@ export const SeatMapWidget: React.FC = ({ seatMap, desiredFlags, a return yOff; }, [ctx]); - const draw = useMemo(() => () => { + const draw = () => { const currDeck = isMainDeck ? 0 : 1; if (ctx) { ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); @@ -114,9 +114,9 @@ export const SeatMapWidget: React.FC = ({ seatMap, desiredFlags, a } ctx.fill(); } - }, [ctx, ...activeFlags, ...desiredFlags]); + }; - const drawRow = useMemo(() => (x: number, deck: number, station: number, rowI: number, rowInfo: RowInfo, seatId: number) => { + const drawRow = (x: number, deck: number, station: number, rowI: number, rowInfo: RowInfo, seatId: number) => { const seatsInfo: SeatInfo[] = rowInfo.seats; for (let seat = 0, yOff = 0; seat < seatsInfo.length; seat++) { yOff = addYOffsetSeat(yOff, station, rowI, seat); @@ -127,9 +127,9 @@ export const SeatMapWidget: React.FC = ({ seatMap, desiredFlags, a setXYMap(xYMap); drawSeat(x, yOff, seatsInfo[seat].type, SeatConstants[seatsInfo[seat].type].imageX, SeatConstants[seatsInfo[seat].type].imageY, station, seatId++); } - }, [ctx, ...activeFlags, ...desiredFlags]); + }; - const drawSeat = useMemo(() => (x: number, y: number, seatType: number, imageX: number, imageY: number, station: number, seatId: number) => { + const drawSeat = (x: number, y: number, seatType: number, imageX: number, imageY: number, station: number, seatId: number) => { switch (seatType) { case SeatType.WidebodyBusinessFlatLeft: if (ctx && bizLeftSeatEmptyImg && bizLeftSeatMinusImg && bizLeftSeatAddImg && bizLeftSeatFilledImg) { @@ -197,9 +197,9 @@ export const SeatMapWidget: React.FC = ({ seatMap, desiredFlags, a } break; } - }, [ctx, ...desiredFlags, ...activeFlags]); + }; - const mouseEvent = useMemo(() => (e) => { + const mouseEvent = (e) => { let selectedStation = -1; let selectedSeat = -1; let shortestDistance = Number.POSITIVE_INFINITY; @@ -217,43 +217,31 @@ export const SeatMapWidget: React.FC = ({ seatMap, desiredFlags, a if (selectedStation !== -1 && selectedSeat !== -1) { onClickSeat(selectedStation, selectedSeat); } - }, [ctx, ...activeFlags, ...desiredFlags, isMainDeck]); + }; useCanvasEvent(canvasRef.current, 'click', mouseEvent); useEffect(() => { - setCtx(canvasRef.current.getContext('2d')); + const context = canvasRef.current.getContext('2d'); + const width = CanvasConst.width; const height = CanvasConst.height; let ratio = 1; ratio = window.devicePixelRatio; canvasRef.current.width = width * ratio; canvasRef.current.height = height * ratio; - ctx?.scale(ratio, ratio); + context.scale(ratio, ratio); + setCtx(context); }, []); useEffect(() => { - const canvas = canvasRef.current; - let frameId; - - if (!canvas) { - return undefined; - } + // work around rendering bug + setTimeout(() => draw(), 10); + }, [ctx]); - const render = () => { - draw(); - // workaround for rendering bug - if (!frameId || frameId < 10) { - frameId = window.requestAnimationFrame(render); - } - }; - render(); - return () => { - if (frameId) { - window.cancelAnimationFrame(frameId); - } - }; - }, [ctx, ...activeFlags, ...desiredFlags]); + useEffect(() => { + draw(); + }, [seatMap, desiredFlags, activeFlags, canvasX, canvasY]); const distSquared = useMemo(() => (x1: number, y1: number, x2: number, y2: number): number => { const diffX = x1 - x2; diff --git a/fbw-common/src/systems/instruments/src/react/bitFlags.tsx b/fbw-common/src/systems/instruments/src/react/bitFlags.tsx index cad6a9f4f0f..0c603e99a08 100644 --- a/fbw-common/src/systems/instruments/src/react/bitFlags.tsx +++ b/fbw-common/src/systems/instruments/src/react/bitFlags.tsx @@ -50,7 +50,7 @@ export const useSeatFlags = ( const lastUpdate = useRef(Date.now() - refreshInterval - 1); const [stateValue, setStateValue] = useState(() => SimVar.GetSimVarValue(name, 'number')); - // const [seatFlags] = useState(() => new SeatFlags(stateValue, totalSeats)); + const [seatFlags, setSeatFlags] = useState(() => new SeatFlags(stateValue, totalSeats)); const updateCallback = useCallback(() => { const delta = Date.now() - lastUpdate.current; @@ -59,13 +59,15 @@ export const useSeatFlags = ( lastUpdate.current = Date.now(); const newValue = SimVar.GetSimVarValue(name, 'number'); + if (newValue !== stateValue) { setStateValue(newValue); // TODO: Refactor to recycle object instead of generating new object - setter(new SeatFlags(newValue, totalSeats)); + // setter(new SeatFlags(newValue, totalSeats)); + setSeatFlags(new SeatFlags(newValue, totalSeats)); } } - }, [name, stateValue, refreshInterval]); + }, [name, refreshInterval, totalSeats, stateValue]); useUpdate(updateCallback); @@ -73,14 +75,13 @@ export const useSeatFlags = ( lastUpdate.current = Date.now(); // Note: as of SU XI 1.29.30.0 - Beyond (2^24) The BehaviourDebug window will incorrectly show this as its real value + 1. // console.log(`[SetSimVarValue] ${name} => ${value.toString()}`); - SimVar.SetSimVarValue(name, 'string', value.toString()).catch(console.error).then(); + SimVar.SetSimVarValue(name, 'string', value.toString()).catch(console.error); setStateValue(value.toNumber()); - // seatFlags.setFlags(value.toNumber()); - }, [name, stateValue]); + setSeatFlags(new SeatFlags(value.toNumber(), totalSeats)); + }, [name, totalSeats]); return [ - // TODO: Refactor to recycle object instead of generating new object - new SeatFlags(stateValue, totalSeats), + seatFlags, setter, ]; };