compiles, no display

This commit is contained in:
geoffsee
2025-07-03 12:41:26 -04:00
parent 7a23e55894
commit b6f06b5e6c
6 changed files with 468 additions and 26 deletions

View File

@@ -17,3 +17,4 @@ bevy = { workspace = true, features = [
] }
rand = { version = "0.8.3" }
components = { path = "../components" }
datalink = { path = "../datalink" }

View File

@@ -1,20 +1,34 @@
use bevy::prelude::Time;
use components::VesselData;
use crate::{SystemInteraction, SystemStatus, VesselSystem};
use datalink::{DataLink, DataLinkConfig, DataLinkReceiver, DataMessage, SimulationDataLink};
use std::collections::HashMap;
/// AIS (Automatic Identification System) implementation
pub struct AisSystem {
status: SystemStatus,
own_mmsi: u32,
receiving: bool,
datalink: SimulationDataLink,
vessel_data: HashMap<String, DataMessage>,
}
impl AisSystem {
pub fn new() -> Self {
let mut datalink = SimulationDataLink::new();
let config = DataLinkConfig::new("simulation".to_string());
// Connect to the simulation datalink
if let Err(e) = datalink.connect(&config) {
eprintln!("Failed to connect AIS datalink: {}", e);
}
Self {
status: SystemStatus::Active,
own_mmsi: 123456789,
receiving: true,
datalink,
vessel_data: HashMap::new(),
}
}
}
@@ -29,38 +43,72 @@ impl VesselSystem for AisSystem {
}
fn update(&mut self, _yacht_data: &VesselData, _time: &Time) {
// AIS system is relatively static, but we could simulate
// vessel movements or signal strength variations here
// Receive new AIS messages from the datalink
if self.receiving && self.datalink.is_connected() {
if let Ok(messages) = self.datalink.receive_all_messages() {
for message in messages {
if message.message_type == "AIS_POSITION" {
// Store vessel data by MMSI
if let Some(mmsi) = message.get_data("mmsi") {
self.vessel_data.insert(mmsi.clone(), message);
}
}
}
}
}
}
fn render_display(&self, _yacht_data: &VesselData) -> String {
format!(
let mut display = format!(
"AIS - AUTOMATIC IDENTIFICATION SYSTEM\n\n\
Status: {}\n\
Own Ship MMSI: {}\n\
Datalink: {}\n\
\n\
NEARBY VESSELS:\n\
\n\
🛥️ M/Y SERENITY\n\
MMSI: 987654321\n\
Distance: 2.1 NM @ 045°\n\
Speed: 12.5 kts\n\
Course: 180°\n\
\n\
🚢 CARGO VESSEL ATLANTIS\n\
MMSI: 456789123\n\
Distance: 5.8 NM @ 270°\n\
Speed: 18.2 kts\n\
Course: 090°\n\
\n\
⛵ S/Y WIND DANCER\n\
MMSI: 789123456\n\
Distance: 1.3 NM @ 135°\n\
Speed: 6.8 kts\n\
Course: 225°",
NEARBY VESSELS:\n",
if self.receiving { "RECEIVING" } else { "STANDBY" },
self.own_mmsi
)
self.own_mmsi,
if self.datalink.is_connected() { "CONNECTED" } else { "DISCONNECTED" }
);
if self.vessel_data.is_empty() {
display.push_str("\nNo vessels detected");
} else {
for (mmsi, message) in &self.vessel_data {
let vessel_name = message.get_data("vessel_name").unwrap_or(mmsi);
let speed = message.get_data("speed").map(|s| s.as_str()).unwrap_or("N/A");
let course = message.get_data("course").map(|s| s.as_str()).unwrap_or("N/A");
let lat = message.get_data("latitude").map(|s| s.as_str()).unwrap_or("N/A");
let lon = message.get_data("longitude").map(|s| s.as_str()).unwrap_or("N/A");
// Determine vessel icon based on name
let icon = if vessel_name.contains("M/Y") || vessel_name.contains("YACHT") {
"🛥️"
} else if vessel_name.contains("CARGO") || vessel_name.contains("SHIP") {
"🚢"
} else if vessel_name.contains("S/Y") || vessel_name.contains("SAIL") {
""
} else {
"🚤"
};
display.push_str(&format!(
"\n{} {}\n\
MMSI: {}\n\
Position: {}°N, {}°W\n\
Speed: {} kts\n\
Course: {}°\n",
icon, vessel_name, mmsi, lat, lon, speed, course
));
if let Some(quality) = message.signal_quality {
display.push_str(&format!("Signal: {}%\n", quality));
}
display.push('\n');
}
}
display
}
fn handle_interaction(&mut self, interaction: SystemInteraction) -> bool {
@@ -104,4 +152,4 @@ impl VesselSystem for AisSystem {
fn status(&self) -> SystemStatus {
self.status.clone()
}
}
}