121 lines
3.1 KiB
Rust
121 lines
3.1 KiB
Rust
use rmon_common::signal::{SignalId, SignalInfo, Sample};
|
|
use std::collections::{HashMap, VecDeque};
|
|
use std::sync::{Arc, Mutex};
|
|
use eframe::egui::ecolor::Color32;
|
|
|
|
pub struct SignalHistory {
|
|
pub info: SignalInfo,
|
|
pub samples: VecDeque<Sample>,
|
|
pub max_samples: usize,
|
|
}
|
|
|
|
impl SignalHistory {
|
|
pub fn new(info: SignalInfo) -> Self {
|
|
Self {
|
|
info,
|
|
samples: VecDeque::new(),
|
|
max_samples: 10000,
|
|
}
|
|
}
|
|
|
|
pub fn push(&mut self, sample: Sample) {
|
|
self.samples.push_back(sample);
|
|
if self.samples.len() > self.max_samples {
|
|
self.samples.pop_front();
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct SignalStyle {
|
|
pub color: Color32,
|
|
pub line_width: f32,
|
|
}
|
|
|
|
impl Default for SignalStyle {
|
|
fn default() -> Self {
|
|
Self {
|
|
color: Color32::WHITE,
|
|
line_width: 1.5,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Default)]
|
|
pub struct PlotCursor {
|
|
pub x: f64,
|
|
pub active: bool,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct PlotDefinition {
|
|
pub id: String,
|
|
pub title: String,
|
|
pub signal_ids: Vec<SignalId>,
|
|
pub cursors: [PlotCursor; 2],
|
|
pub show_legend: bool,
|
|
pub follow_mode: bool,
|
|
pub time_window: f64, // seconds
|
|
}
|
|
|
|
impl PlotDefinition {
|
|
pub fn new(title: String) -> Self {
|
|
Self {
|
|
id: uuid::Uuid::new_v4().to_string(),
|
|
title,
|
|
signal_ids: Vec::new(),
|
|
cursors: [PlotCursor::default(), PlotCursor::default()],
|
|
show_legend: true,
|
|
follow_mode: true,
|
|
time_window: 600.0, // Default to 10 minutes
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct SessionState {
|
|
pub connected: bool,
|
|
pub signals: HashMap<SignalId, Arc<Mutex<SignalHistory>>>,
|
|
pub tree: egui_tiles::Tree<PlotDefinition>,
|
|
pub signal_styles: HashMap<SignalId, SignalStyle>,
|
|
}
|
|
|
|
impl SessionState {
|
|
pub fn new() -> Self {
|
|
let mut tiles = egui_tiles::Tiles::default();
|
|
let root = tiles.insert_pane(PlotDefinition::new("Main Plot".to_string()));
|
|
let tree = egui_tiles::Tree::new("main_tree", root, tiles);
|
|
|
|
Self {
|
|
connected: false,
|
|
signals: HashMap::new(),
|
|
tree,
|
|
signal_styles: HashMap::new(),
|
|
}
|
|
}
|
|
|
|
pub fn get_style(&mut self, id: &SignalId) -> SignalStyle {
|
|
if let Some(style) = self.signal_styles.get(id) {
|
|
return style.clone();
|
|
}
|
|
|
|
let colors = [
|
|
Color32::from_rgb(255, 80, 80),
|
|
Color32::from_rgb(80, 255, 80),
|
|
Color32::from_rgb(80, 80, 255),
|
|
Color32::from_rgb(255, 255, 80),
|
|
Color32::from_rgb(255, 80, 255),
|
|
Color32::from_rgb(80, 255, 255),
|
|
Color32::from_rgb(255, 150, 50),
|
|
Color32::from_rgb(150, 80, 255),
|
|
];
|
|
|
|
let mut hash = 0u64;
|
|
for b in id.as_bytes() { hash = hash.wrapping_add(*b as u64); }
|
|
let color = colors[(hash % colors.len() as u64) as usize];
|
|
|
|
let style = SignalStyle { color, line_width: 1.5 };
|
|
self.signal_styles.insert(id.clone(), style.clone());
|
|
style
|
|
}
|
|
}
|