reflect
This commit is contained in:
+130
-185
@@ -10,92 +10,15 @@ use std::{
|
||||
use anyhow::anyhow;
|
||||
use anyhow::Result;
|
||||
use connector::{Connector, UdpConnector};
|
||||
use egui::Ui;
|
||||
use log::*;
|
||||
use msg::DsTlmSet;
|
||||
use msg::{DsTlmSet, Msg, TargetMsg, TlmSetItem};
|
||||
use reflect::*;
|
||||
use rfe::macros::Reflect;
|
||||
use rfe::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
extern crate alloc;
|
||||
use simple_logger::SimpleLogger;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct TreeNode {
|
||||
name: String,
|
||||
children: Vec<TreeNode>,
|
||||
}
|
||||
|
||||
impl TreeNode {
|
||||
pub fn new<T: ToString>(name: T, children: Vec<TreeNode>) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
children,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_child<T: ToString>(&mut self, name: T) -> &mut TreeNode {
|
||||
self.children.push(TreeNode::new(name, Vec::new()));
|
||||
let i = self.children.len() - 1;
|
||||
return &mut self.children[i];
|
||||
}
|
||||
|
||||
pub fn get_add_path(&mut self, path: &str) -> &mut TreeNode {
|
||||
if !path.starts_with(&format!("{}.", self.name)) {
|
||||
return self;
|
||||
}
|
||||
let path = path.replace(&format!("{}.", self.name), "");
|
||||
let names = path.split(".");
|
||||
let mut working_tree = self;
|
||||
|
||||
for name in names {
|
||||
let mut index = None;
|
||||
for (i, child) in &mut working_tree.children.iter().enumerate() {
|
||||
if child.name == name {
|
||||
index = Some(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Some(index) = index {
|
||||
working_tree = &mut working_tree.children[index];
|
||||
} else {
|
||||
working_tree = working_tree.add_child(name);
|
||||
}
|
||||
}
|
||||
|
||||
working_tree
|
||||
}
|
||||
|
||||
pub fn is_last(&self) -> bool {
|
||||
self.children.len() == 0
|
||||
}
|
||||
}
|
||||
|
||||
fn to_tree(msg_enum: Vec<String>) -> TreeNode {
|
||||
let mut t = TreeNode::new("Msg", Vec::new());
|
||||
for p in msg_enum {
|
||||
let mut x = p
|
||||
.split(" = ")
|
||||
.map(|x| x.split("."))
|
||||
.flatten()
|
||||
.collect::<Vec<_>>()
|
||||
.join(".");
|
||||
|
||||
if x.starts_with(".") {
|
||||
x.remove(0);
|
||||
} else {
|
||||
x = format!("Msg.{}", x);
|
||||
}
|
||||
let s = x.rsplitn(2, ".").collect::<Vec<_>>();
|
||||
|
||||
if s.len() == 2 {
|
||||
t.get_add_path(s[1]).add_child(s[0]);
|
||||
} else {
|
||||
t.add_child(s[0]);
|
||||
}
|
||||
}
|
||||
|
||||
t
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Reflect)]
|
||||
struct TestStruct {
|
||||
counter: i8,
|
||||
@@ -114,116 +37,138 @@ fn main() -> Result<()> {
|
||||
.init()
|
||||
.unwrap();
|
||||
|
||||
info!(
|
||||
"{:?}",
|
||||
msg::Msg::DsCmd(msg::DsCmd::AddTlmSet(DsTlmSet::default()))
|
||||
);
|
||||
info!(
|
||||
"json {}",
|
||||
serde_json::to_string(&msg::Msg::DsCmd(msg::DsCmd::Noop)).unwrap()
|
||||
);
|
||||
spawn(|| {
|
||||
let mut udp = UdpConnector::new("127.0.0.1", 7011, "127.0.0.1", 7010).unwrap();
|
||||
|
||||
let mut test = TestStruct::default();
|
||||
info!("{:?}", test.fields());
|
||||
reflect::path_set(&mut test, "counter", ReflectValue::I64(1));
|
||||
info!("{:?}", test.fields());
|
||||
let mut next_time = Instant::now() + Duration::from_millis(10);
|
||||
loop {
|
||||
sleep(next_time - Instant::now());
|
||||
|
||||
let mut test2 = EnumTest::None;
|
||||
while let Some(msgs) = udp.recv() {
|
||||
for msg in msgs {
|
||||
info!("got msg {:?}", msg);
|
||||
}
|
||||
}
|
||||
next_time += Duration::from_millis(10);
|
||||
}
|
||||
});
|
||||
|
||||
// info!("{:?}", test2);
|
||||
|
||||
// let testref = test2.as_variant(1).unwrap();
|
||||
|
||||
// test2.as_variant(1).unwrap().fields()[0]
|
||||
// .1
|
||||
// .set_value(ReflectValue::I64(3));
|
||||
// info!("{:?}", test2);
|
||||
|
||||
// spawn(|| {
|
||||
// let mut udp = UdpConnector::new("127.0.0.1", 7011, "127.0.0.1", 7010).unwrap();
|
||||
|
||||
// let mut next_time = Instant::now() + Duration::from_millis(10);
|
||||
// loop {
|
||||
// sleep(next_time - Instant::now());
|
||||
|
||||
// while let Some(msgs) = udp.recv() {
|
||||
// for msg in msgs {
|
||||
// info!("got msg {:?}", msg);
|
||||
// }
|
||||
// }
|
||||
// next_time += Duration::from_millis(10);
|
||||
// }
|
||||
// });
|
||||
|
||||
// let options = eframe::NativeOptions {
|
||||
// viewport: egui::ViewportBuilder::default().with_inner_size([560.0, 480.0]),
|
||||
// ..Default::default()
|
||||
// };
|
||||
// eframe::run_native(
|
||||
// "RFE Ground",
|
||||
// options,
|
||||
// Box::new(|_cc| Ok(Box::<MyApp>::default())),
|
||||
// )
|
||||
// .or(Err(anyhow!("eframe failed")))?;
|
||||
let options = eframe::NativeOptions {
|
||||
viewport: egui::ViewportBuilder::default().with_inner_size([560.0, 480.0]),
|
||||
..Default::default()
|
||||
};
|
||||
eframe::run_native(
|
||||
"RFE Ground",
|
||||
options,
|
||||
Box::new(|_cc| Ok(Box::<MyApp>::default())),
|
||||
)
|
||||
.or(Err(anyhow!("eframe failed")))?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// struct MyApp {
|
||||
// command_path: String,
|
||||
// tree: TreeNode,
|
||||
// values: HashMap<String, String>,
|
||||
// }
|
||||
struct MyApp {
|
||||
command: Msg,
|
||||
values: HashMap<String, String>,
|
||||
}
|
||||
|
||||
// impl Default for MyApp {
|
||||
// fn default() -> Self {
|
||||
// let tree = to_tree(msg::Msg::None.enumerate_clean());
|
||||
// Self {
|
||||
// command_path: "Msg".to_string(),
|
||||
// tree,
|
||||
// values: HashMap::new(),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
impl Default for MyApp {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
command: Msg::None,
|
||||
values: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// impl eframe::App for MyApp {
|
||||
// fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||
// egui::CentralPanel::default().show(ctx, |ui| {
|
||||
// ui.heading(format!("Commands: {}", self.command_path));
|
||||
// if ui.button("X").clicked() {
|
||||
// self.command_path = "Msg".to_string();
|
||||
// }
|
||||
// if self
|
||||
// .command_path
|
||||
// .as_bytes()
|
||||
// .iter()
|
||||
// .filter(|x| **x == b'.')
|
||||
// .count()
|
||||
// >= 2
|
||||
// {
|
||||
// for item in &self.tree.get_add_path(&self.command_path).children {
|
||||
// for c in &item.children {
|
||||
// if c.is_last() {
|
||||
// if !self.values.contains_key(&c.name) {
|
||||
// self.values.insert(c.name.clone(), String::new());
|
||||
// }
|
||||
// let sref = self.values.get_mut(&c.name).unwrap();
|
||||
// ui.horizontal(|ui| {
|
||||
// ui.label(format!("{} : {}", item.name, c.name.clone()));
|
||||
// ui.text_edit_singleline(sref);
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if ui.button("send").clicked() {
|
||||
// info!("sending {}", self.command_path);
|
||||
// }
|
||||
// } else {
|
||||
// for item in &self.tree.get_add_path(&self.command_path).children {
|
||||
// if ui.button(item.name.clone()).clicked() {
|
||||
// self.command_path = format!("{}.{}", self.command_path, item.name);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
fn build_command_ui_value_number(ui: &mut Ui, name: &str, cmd: &mut dyn Reflect) {
|
||||
let mut r = cmd.get_value().str();
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(name);
|
||||
ui.text_edit_singleline(&mut r);
|
||||
cmd.set_value(ReflectValue::Str(r));
|
||||
});
|
||||
}
|
||||
|
||||
fn build_command_ui(ui: &mut Ui, name: &str, cmd: &mut dyn Reflect) {
|
||||
match cmd.reflect_type() {
|
||||
ReflectType::Value => match cmd.get_value() {
|
||||
ReflectValue::None => {}
|
||||
ReflectValue::U8(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::U16(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::U32(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::U64(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::I8(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::I16(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::I32(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::I64(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::Vec(_vec) => {}
|
||||
ReflectValue::Str(_) => {}
|
||||
ReflectValue::Bool(_) => {}
|
||||
},
|
||||
ReflectType::Enumeration => {
|
||||
// variants
|
||||
|
||||
for (i, (name, _v)) in cmd.variants().into_iter().enumerate() {
|
||||
if ui.button(name).clicked() {
|
||||
cmd.convert_variant(i);
|
||||
}
|
||||
}
|
||||
|
||||
// values
|
||||
if let Some((name, cmd)) = cmd.unwrap_variant() {
|
||||
build_command_ui(ui, name, cmd);
|
||||
}
|
||||
}
|
||||
ReflectType::Structure => {
|
||||
for (name, cmd) in cmd.fields().into_iter() {
|
||||
build_command_ui(ui, name, cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl eframe::App for MyApp {
|
||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.heading(format!("Command: {:?}", self.command));
|
||||
if ui.button("X").clicked() {
|
||||
self.command = Msg::None;
|
||||
}
|
||||
|
||||
build_command_ui(ui, "Msg", &mut self.command);
|
||||
|
||||
// if self
|
||||
// .command_path
|
||||
// .as_bytes()
|
||||
// .iter()
|
||||
// .filter(|x| **x == b'.')
|
||||
// .count()
|
||||
// >= 2
|
||||
// {
|
||||
// for item in &self.tree.get_add_path(&self.command_path).children {
|
||||
// for c in &item.children {
|
||||
// if c.is_last() {
|
||||
// if !self.values.contains_key(&c.name) {
|
||||
// self.values.insert(c.name.clone(), String::new());
|
||||
// }
|
||||
// let sref = self.values.get_mut(&c.name).unwrap();
|
||||
// ui.horizontal(|ui| {
|
||||
// ui.label(format!("{} : {}", item.name, c.name.clone()));
|
||||
// ui.text_edit_singleline(sref);
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if ui.button("send").clicked() {
|
||||
// info!("sending {}", self.command_path);
|
||||
// }
|
||||
// } else {
|
||||
// for item in &self.tree.get_add_path(&self.command_path).children {
|
||||
// if ui.button(item.name.clone()).clicked() {
|
||||
// self.command_path = format!("{}.{}", self.command_path, item.name);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user