Added custom Message functionality

This commit is contained in:
Martino Ferrari
2026-03-04 10:08:43 +01:00
parent d3077e78ec
commit 7adbecdb6e
9 changed files with 330 additions and 31 deletions
+105
View File
@@ -186,6 +186,13 @@ struct MonitorDialog {
period_ms: String,
}
struct MessageDialog {
destination: String,
function: String,
payload: String,
expect_reply: bool,
}
struct LogFilters {
show_debug: bool,
show_info: bool,
@@ -232,6 +239,7 @@ struct MarteDebugApp {
telem_match_count: HashMap<u32, u64>,
forcing_dialog: Option<ForcingDialog>,
monitoring_dialog: Option<MonitorDialog>,
message_dialog: Option<MessageDialog>,
style_editor: Option<(usize, usize)>,
tx_cmd: Sender<String>,
rx_events: Receiver<InternalEvent>,
@@ -312,6 +320,7 @@ impl MarteDebugApp {
telem_match_count: HashMap::new(),
forcing_dialog: None,
monitoring_dialog: None,
message_dialog: None,
style_editor: None,
tx_cmd,
rx_events,
@@ -400,6 +409,34 @@ impl MarteDebugApp {
}
}
fn get_all_objects(&self) -> Vec<String> {
let mut objects = Vec::new();
if let Some(tree) = &self.app_tree {
fn collect(item: &TreeItem, path: String, objects: &mut Vec<String>) {
let current_path = if path.is_empty() {
if item.name == "Root" {
"".to_string()
} else {
item.name.clone()
}
} else {
format!("{}.{}", path, item.name)
};
if !current_path.is_empty() && !item.class.contains("Signal") {
objects.push(current_path.clone());
}
if let Some(children) = &item.children {
for child in children {
collect(child, current_path.clone(), objects);
}
}
}
collect(tree, "".to_string(), &mut objects);
}
objects.sort();
objects
}
fn render_tree(&mut self, ui: &mut egui::Ui, item: &TreeItem, path: String) {
let current_path = if path.is_empty() {
if item.name == "Root" {
@@ -1202,6 +1239,65 @@ impl eframe::App for MarteDebugApp {
}
}
if self.message_dialog.is_some() {
let mut dialog = self.message_dialog.take().unwrap();
let mut close = false;
let objects = self.get_all_objects();
egui::Window::new("Send MARTe Message").show(ctx, |ui| {
egui::Grid::new("msg_grid").num_columns(2).show(ui, |ui| {
ui.label("Destination:");
egui::ComboBox::from_id_salt("dest_combo")
.selected_text(&dialog.destination)
.width(200.0)
.show_ui(ui, |ui| {
for obj in objects {
ui.selectable_value(&mut dialog.destination, obj.clone(), obj);
}
});
ui.end_row();
ui.label("Function:");
ui.text_edit_singleline(&mut dialog.function);
ui.end_row();
ui.label("Payload:");
ui.vertical(|ui| {
ui.text_edit_multiline(&mut dialog.payload);
ui.label(egui::RichText::new("Format: Key = Value (one per line)").small().weak());
});
ui.end_row();
ui.label("Wait Reply:");
ui.checkbox(&mut dialog.expect_reply, "");
ui.end_row();
});
ui.horizontal(|ui| {
if ui.button("🚀 Send").clicked() {
let wait = if dialog.expect_reply { "1" } else { "0" };
// Replace actual newlines with literal '\n' for the server-side tokenizer if needed,
// or ensure the server handles the raw multi-line stream if the protocol allows it.
// Given HandleCommand reads line-by-line, we must send it carefully.
// Actually, our Server loop reads up to \n.
// So we should encode newlines in payload if we want to send them in one go.
let encoded_payload = dialog.payload.replace('\n', "\\n");
let cmd = format!(
"MSG {} {} {} {}",
dialog.destination, dialog.function, wait, encoded_payload
);
let _ = self.tx_cmd.send(cmd);
close = true;
}
if ui.button("Cancel").clicked() {
close = true;
}
});
});
if !close {
self.message_dialog = Some(dialog);
}
}
if let Some((p_idx, s_idx)) = self.style_editor {
let mut close = false;
egui::Window::new("Signal Style").show(ctx, |ui| {
@@ -1407,6 +1503,15 @@ impl eframe::App for MarteDebugApp {
}
});
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
if ui.button("✉ Send Msg").clicked() {
self.message_dialog = Some(MessageDialog {
destination: "".to_string(),
function: "".to_string(),
payload: "".to_string(),
expect_reply: false,
});
}
ui.separator();
ui.label(format!(
"UDP: OK[{}] DROP[{}]",
self.udp_packets, self.udp_dropped