diff --git a/dotbot/frontend/src/DotBots.js b/dotbot/frontend/src/DotBots.js
index ec85651..2ba35e6 100644
--- a/dotbot/frontend/src/DotBots.js
+++ b/dotbot/frontend/src/DotBots.js
@@ -55,35 +55,35 @@ const DotBots = ({ dotbots, areaSize, updateDotbots, publishCommand, publish })
}
if (dotbot.application === ApplicationType.SailBot) {
- let dotbotsTmp = dotbots.slice();
- for (let idx = 0; idx < dotbots.length; idx++) {
- if (dotbots[idx].address === dotbot.address) {
- if (dotbotsTmp[idx].waypoints.length === 0) {
- dotbotsTmp[idx].waypoints.push({
- latitude: dotbotsTmp[idx].gps_position.latitude,
- longitude: dotbotsTmp[idx].gps_position.longitude,
- });
- }
- dotbotsTmp[idx].waypoints.push({latitude: x, longitude: y});
- updateDotbots(dotbotsTmp);
+ const dotbotsTmp = dotbots.map(db => {
+ if (db.address !== dotbot.address) return db; // unchanged refs are fine
+
+ const newWaypoints = [...db.waypoints]; // new array, new ref
+ if (newWaypoints.length === 0) {
+ newWaypoints.push({
+ latitude: db.gps_position.latitude,
+ longitude: db.gps_position.longitude,
+ });
}
- }
+ newWaypoints.push({ latitude: x, longitude: y });
+
+ return { ...db, waypoints: newWaypoints }; // new object ref ✓
+ });
+ updateDotbots(dotbotsTmp);
}
if (dotbot.application === ApplicationType.DotBot) {
- let dotbotsTmp = dotbots.slice();
- for (let idx = 0; idx < dotbots.length; idx++) {
- if (dotbots[idx].address === dotbot.address) {
- if (dotbotsTmp[idx].waypoints.length === 0) {
- dotbotsTmp[idx].waypoints.push({
- x: dotbotsTmp[idx].lh2_position.x,
- y: dotbotsTmp[idx].lh2_position.y,
- z: 0
- });
- }
- dotbotsTmp[idx].waypoints.push({x: x, y: y, z: 0});
- updateDotbots(dotbotsTmp);
+ const dotbotsTmp = dotbots.map(db => {
+ if (db.address !== dotbot.address) return db;
+
+ const newWaypoints = [...db.waypoints];
+ if (newWaypoints.length === 0) {
+ newWaypoints.push({ x: db.lh2_position.x, y: db.lh2_position.y, z: 0 });
}
- }
+ newWaypoints.push({ x, y, z: 0 });
+
+ return { ...db, waypoints: newWaypoints }; // new object ref ✓
+ });
+ updateDotbots(dotbotsTmp);
}
}, [activeDotbot, dotbots, updateDotbots]
);
diff --git a/dotbot/frontend/src/DotBotsMap.js b/dotbot/frontend/src/DotBotsMap.js
index 73a4346..e601eb1 100644
--- a/dotbot/frontend/src/DotBotsMap.js
+++ b/dotbot/frontend/src/DotBotsMap.js
@@ -80,7 +80,7 @@ const DotBotsPosition = (props) => {
)
}
-const DotBotsMapPoint = (props) => {
+const DotBotsMapPoint = React.memo((props) => {
const [hovered, setHovered ] = useState(false);
let rgbColor = "rgb(0, 0, 0)"
@@ -122,7 +122,8 @@ const DotBotsMapPoint = (props) => {
opacity={waypointOpacity}
waypoints={props.dotbot.waypoints}
threshold={props.dotbot.waypoints_threshold}
- {...props}
+ areaSize={props.areaSize}
+ mapSize={props.mapSize}
/>
))
)}
@@ -152,7 +153,7 @@ const DotBotsMapPoint = (props) => {
>
)
-}
+})
export const DotBotsMap = (props) => {
@@ -197,7 +198,17 @@ export const DotBotsMap = (props) => {
props.dotbots && props.dotbots
.filter(dotbot => dotbot.status !== 2)
.filter(dotbot => dotbot.lh2_position)
- .map(dotbot => )
+ .map(dotbot => )
}
diff --git a/dotbot/frontend/src/QrKeyApp.js b/dotbot/frontend/src/QrKeyApp.js
index 319a556..47511e8 100644
--- a/dotbot/frontend/src/QrKeyApp.js
+++ b/dotbot/frontend/src/QrKeyApp.js
@@ -42,62 +42,90 @@ const QrKeyApp = () => {
setDotbots(dotbotsTmp);
}
if (payload.cmd === NotificationType.Update && dotbots && dotbots.length > 0) {
- let dotbotsTmp = dotbots.slice();
- for (let idx = 0; idx < dotbots.length; idx++) {
- if (dotbots[idx].address === payload.data.address) {
- if (payload.data.direction !== undefined && payload.data.direction !== null) {
- dotbotsTmp[idx].direction = payload.data.direction;
+ setDotbots(prev => {
+ let changed = false;
+ let next = prev.map(bot => {
+ if (bot.address !== payload.data.address) { return bot; }
+
+ let botChanged = false;
+ let updated = bot;
+
+ // direction
+ if (payload.data.direction != null && bot.direction !== payload.data.direction) {
+ updated = { ...updated, direction: payload.data.direction };
+ botChanged = true;
}
- if (payload.data.rgb_led !== undefined) {
- if (dotbotsTmp[idx].rgb_led === undefined) {
- dotbotsTmp[idx].rgb_led = {
- red: 0,
- green: 0,
- blue: 0
- }
+
+ // rgb_led
+ if (payload.data.rgb_led != null) {
+ const newLed = payload.data.rgb_led;
+ const oldLed = bot.rgb_led ?? { red: 0, green: 0, blue: 0 };
+
+ if (
+ oldLed.red !== newLed.red ||
+ oldLed.green !== newLed.green ||
+ oldLed.blue !== newLed.blue
+ ) {
+ updated = { ...updated, rgb_led: newLed };
+ botChanged = true;
}
- dotbotsTmp[idx].rgb_led.red = payload.data.rgb_led.red;
- dotbotsTmp[idx].rgb_led.green = payload.data.rgb_led.green;
- dotbotsTmp[idx].rgb_led.blue = payload.data.rgb_led.blue;
}
- if (payload.data.lh2_position !== undefined && payload.data.lh2_position !== null) {
- const newPosition = {
- x: payload.data.lh2_position.x,
- y: payload.data.lh2_position.y
- };
- console.log('distance threshold:', lh2_distance_threshold, lh2_distance(dotbotsTmp[idx].lh2_position, newPosition));
- if (dotbotsTmp[idx].lh2_position && (dotbotsTmp[idx].position_history.length === 0 || lh2_distance(dotbotsTmp[idx].lh2_position, newPosition) >= lh2_distance_threshold)) {
- console.log('Adding to position history');
- dotbotsTmp[idx].position_history.push(newPosition);
- }
- dotbotsTmp[idx].lh2_position = newPosition;
+
+ // wind_angle
+ if (payload.data.wind_angle != null && bot.wind_angle !== payload.data.wind_angle) {
+ updated = { ...updated, wind_angle: payload.data.wind_angle };
+ botChanged = true;
}
- if (payload.data.lh2_waypoints !== undefined) {
- dotbotsTmp[idx].lh2_waypoints = payload.data.lh2_waypoints;
+
+ // rudder_angle
+ if (payload.data.rudder_angle != null && bot.rudder_angle !== payload.data.rudder_angle) {
+ updated = { ...updated, rudder_angle: payload.data.rudder_angle };
+ botChanged = true;
}
- if (payload.data.gps_position !== undefined && payload.data.gps_position !== null) {
- const newPosition = {
- latitude: payload.data.gps_position.latitude,
- longitude: payload.data.gps_position.longitude
- };
- if (dotbotsTmp[idx].gps_position !== undefined && dotbotsTmp[idx].gps_position !== null && (dotbotsTmp[idx].position_history.length === 0 || gps_distance(dotbotsTmp[idx].gps_position, newPosition) > gps_distance_threshold)) {
- dotbotsTmp[idx].position_history.push(newPosition);
- }
- dotbotsTmp[idx].gps_position = newPosition;
+
+ // sail_angle
+ if (payload.data.sail_angle != null && bot.sail_angle !== payload.data.sail_angle) {
+ updated = { ...updated, sail_angle: payload.data.sail_angle };
+ botChanged = true;
}
- if (payload.data.gps_waypoints !== undefined) {
- dotbotsTmp[idx].gps_waypoints = payload.data.gps_waypoints;
+
+ // lh2_position + position_history
+ if (payload.data.lh2_position != null && lh2_distance(bot.lh2_position, payload.data.lh2_position) > lh2_distance_threshold) {
+ let newHistory = [...bot.position_history, payload.data.lh2_position];
+ updated = { ...updated, lh2_position: payload.data.lh2_position, position_history: newHistory };
+ botChanged = true;
}
- if (payload.data.position_history !== undefined) {
- dotbotsTmp[idx].position_history = payload.data.position_history;
+
+ // lh2_waypoints
+ if (payload.data.lh2_waypoints != null) {
+ updated = { ...updated, lh2_waypoints: payload.data.lh2_waypoints };
+ botChanged = true;
}
- if (payload.data.battery !== undefined) {
- dotbotsTmp[idx].battery = payload.data.battery ;
+
+ // gps_position + position_history
+ if (payload.data.gps_position != null && gps_distance(bot.gps_position, payload.data.gps_position) > gps_distance_threshold) {
+ let newHistory = [...bot.position_history, payload.data.gps_position];
+ updated = { ...updated, gps_position: payload.data.gps_position, position_history: newHistory };
+ botChanged = true;
}
- setDotbots(dotbotsTmp);
- break;
- }
- }
+
+ // gps_waypoints
+ if (payload.data.gps_waypoints != null) {
+ updated = { ...updated, gps_waypoints: payload.data.gps_waypoints };
+ botChanged = true;
+ }
+
+ // battery
+ if (payload.data.battery != null && Math.abs(bot.battery - payload.data.battery) > 0.1) {
+ updated = { ...updated, battery: payload.data.battery };
+ botChanged = true;
+ }
+
+ if (botChanged) {changed = true;}
+ return botChanged ? updated : bot;
+ });
+ return changed ? next : prev;
+ });
} else if (payload.cmd === NotificationType.Reload) {
log.info("Reload notification");
sendRequest({request: RequestType.DotBots, reply: `${clientId}`});
diff --git a/dotbot/frontend/src/RestApp.js b/dotbot/frontend/src/RestApp.js
index e164576..90b2cb9 100644
--- a/dotbot/frontend/src/RestApp.js
+++ b/dotbot/frontend/src/RestApp.js
@@ -60,69 +60,90 @@ const RestApp = () => {
setDotbots(dotbotsTmp);
}
if (message.cmd === NotificationType.Update && dotbots && dotbots.length > 0) {
- let dotbotsTmp = dotbots.slice();
- for (let idx = 0; idx < dotbots.length; idx++) {
- if (dotbots[idx].address === message.data.address) {
- if (message.data.direction !== undefined && message.data.direction !== null) {
- dotbotsTmp[idx].direction = message.data.direction;
+ setDotbots(prev => {
+ let changed = false;
+ let next = prev.map(bot => {
+ if (bot.address !== message.data.address) { return bot; }
+
+ let botChanged = false;
+ let updated = bot;
+
+ // direction
+ if (message.data.direction != null && bot.direction !== message.data.direction) {
+ updated = { ...updated, direction: message.data.direction };
+ botChanged = true;
}
- if (message.data.rgb_led !== undefined) {
- if (dotbotsTmp[idx].rgb_led === undefined) {
- dotbotsTmp[idx].rgb_led = {
- red: 0,
- green: 0,
- blue: 0
- }
+
+ // rgb_led
+ if (message.data.rgb_led != null) {
+ const newLed = message.data.rgb_led;
+ const oldLed = bot.rgb_led ?? { red: 0, green: 0, blue: 0 };
+
+ if (
+ oldLed.red !== newLed.red ||
+ oldLed.green !== newLed.green ||
+ oldLed.blue !== newLed.blue
+ ) {
+ updated = { ...updated, rgb_led: newLed };
+ botChanged = true;
}
- dotbotsTmp[idx].rgb_led.red = message.data.rgb_led.red;
- dotbotsTmp[idx].rgb_led.green = message.data.rgb_led.green;
- dotbotsTmp[idx].rgb_led.blue = message.data.rgb_led.blue;
}
- if (message.data.wind_angle !== undefined && message.data.wind_angle !== null) {
- dotbotsTmp[idx].wind_angle = message.data.wind_angle;
- }
- if (message.data.rudder_angle !== undefined && message.data.rudder_angle !== null) {
- dotbotsTmp[idx].rudder_angle = message.data.rudder_angle;
+
+ // wind_angle
+ if (message.data.wind_angle != null && bot.wind_angle !== message.data.wind_angle) {
+ updated = { ...updated, wind_angle: message.data.wind_angle };
+ botChanged = true;
}
- if (message.data.sail_angle !== undefined && message.data.sail_angle !== null) {
- dotbotsTmp[idx].sail_angle = message.data.sail_angle;
+
+ // rudder_angle
+ if (message.data.rudder_angle != null && bot.rudder_angle !== message.data.rudder_angle) {
+ updated = { ...updated, rudder_angle: message.data.rudder_angle };
+ botChanged = true;
}
- if (message.data.lh2_position !== undefined && message.data.lh2_position !== null) {
- const newPosition = {
- x: message.data.lh2_position.x,
- y: message.data.lh2_position.y
- };
- if (dotbotsTmp[idx].lh2_position !== undefined && dotbotsTmp[idx].lh2_position !== null && (dotbotsTmp[idx].position_history.length === 0 || lh2_distance(dotbotsTmp[idx].lh2_position, newPosition) > lh2_distance_threshold)) {
- dotbotsTmp[idx].position_history.push(newPosition);
- }
- dotbotsTmp[idx].lh2_position = newPosition;
+
+ // sail_angle
+ if (message.data.sail_angle != null && bot.sail_angle !== message.data.sail_angle) {
+ updated = { ...updated, sail_angle: message.data.sail_angle };
+ botChanged = true;
}
- if (message.data.lh2_waypoints !== undefined) {
- dotbotsTmp[idx].lh2_waypoints = message.data.lh2_waypoints;
+
+ // lh2_position + position_history
+ if (message.data.lh2_position != null && lh2_distance(bot.lh2_position, message.data.lh2_position) > lh2_distance_threshold) {
+ let newHistory = [...bot.position_history, message.data.lh2_position];
+ updated = { ...updated, lh2_position: message.data.lh2_position, position_history: newHistory };
+ botChanged = true;
}
- if (message.data.gps_position !== undefined && message.data.gps_position !== null) {
- const newPosition = {
- latitude: message.data.gps_position.latitude,
- longitude: message.data.gps_position.longitude
- };
- if (dotbotsTmp[idx].gps_position !== undefined && dotbotsTmp[idx].gps_position !== null && (dotbotsTmp[idx].position_history.length === 0 || gps_distance(dotbotsTmp[idx].gps_position, newPosition) > gps_distance_threshold)) {
- dotbotsTmp[idx].position_history.push(newPosition);
- }
- dotbotsTmp[idx].gps_position = newPosition;
+
+ // lh2_waypoints
+ if (message.data.lh2_waypoints != null) {
+ updated = { ...updated, lh2_waypoints: message.data.lh2_waypoints };
+ botChanged = true;
}
- if (message.data.gps_waypoints !== undefined) {
- dotbotsTmp[idx].gps_waypoints = message.data.gps_waypoints;
+
+ // gps_position + position_history
+ if (message.data.gps_position != null && gps_distance(bot.gps_position, message.data.gps_position) > gps_distance_threshold) {
+ let newHistory = [...bot.position_history, message.data.gps_position];
+ updated = { ...updated, gps_position: message.data.gps_position, position_history: newHistory };
+ botChanged = true;
}
- if (message.data.position_history !== undefined) {
- dotbotsTmp[idx].position_history = message.data.position_history;
+
+ // gps_waypoints
+ if (message.data.gps_waypoints != null) {
+ updated = { ...updated, gps_waypoints: message.data.gps_waypoints };
+ botChanged = true;
}
- if (message.data.battery !== undefined) {
- dotbotsTmp[idx].battery = message.data.battery;
+
+ // battery
+ if (message.data.battery != null && Math.abs(bot.battery - message.data.battery) > 0.1) {
+ updated = { ...updated, battery: message.data.battery };
+ botChanged = true;
}
- setDotbots(dotbotsTmp);
- break;
- }
- }
+
+ if (botChanged) {changed = true;}
+ return botChanged ? updated : bot;
+ });
+ return changed ? next : prev;
+ });
}
};