#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ProbeDebugConfig {
pub marker_radius: f32,
pub show_influence: bool,
pub max_markers: usize,
}
#[derive(Debug, Clone)]
pub struct ProbeDebugMarker {
pub id: u32,
pub position: [f32; 3],
pub influence: [f32; 3],
pub label: String,
}
#[derive(Debug, Clone)]
pub struct ProbeDebugView {
pub markers: Vec<ProbeDebugMarker>,
pub visible: bool,
next_id: u32,
}
pub fn default_probe_debug_config() -> ProbeDebugConfig {
ProbeDebugConfig {
marker_radius: 0.25,
show_influence: true,
max_markers: 64,
}
}
pub fn new_probe_debug_view() -> ProbeDebugView {
ProbeDebugView {
markers: Vec::new(),
visible: true,
next_id: 1,
}
}
pub fn probe_debug_add_marker(
view: &mut ProbeDebugView,
cfg: &ProbeDebugConfig,
position: [f32; 3],
influence: [f32; 3],
label: &str,
) -> u32 {
if view.markers.len() >= cfg.max_markers {
return 0;
}
let id = view.next_id;
view.next_id += 1;
view.markers.push(ProbeDebugMarker {
id,
position,
influence,
label: label.to_string(),
});
id
}
pub fn probe_debug_remove_marker(view: &mut ProbeDebugView, id: u32) -> bool {
if let Some(pos) = view.markers.iter().position(|m| m.id == id) {
view.markers.remove(pos);
true
} else {
false
}
}
pub fn probe_debug_marker_count(view: &ProbeDebugView) -> usize {
view.markers.len()
}
pub fn probe_debug_set_visible(view: &mut ProbeDebugView, visible: bool) {
view.visible = visible;
}
pub fn probe_debug_is_visible(view: &ProbeDebugView) -> bool {
view.visible
}
pub fn probe_debug_to_json(view: &ProbeDebugView, cfg: &ProbeDebugConfig) -> String {
let mut out = format!(
"{{\"visible\":{},\"marker_radius\":{:.4},\"show_influence\":{},\"markers\":[",
view.visible, cfg.marker_radius, cfg.show_influence
);
let len = view.markers.len();
for (i, m) in view.markers.iter().enumerate() {
let comma = if i + 1 < len { "," } else { "" };
out.push_str(&format!(
"{{\"id\":{},\"pos\":[{:.4},{:.4},{:.4}],\
\"influence\":[{:.4},{:.4},{:.4}],\"label\":\"{}\"}}{comma}",
m.id,
m.position[0], m.position[1], m.position[2],
m.influence[0], m.influence[1], m.influence[2],
m.label
));
}
out.push_str("]}");
out
}
pub fn probe_debug_clear(view: &mut ProbeDebugView) {
view.markers.clear();
view.next_id = 1;
}
pub fn probe_debug_toggle(view: &mut ProbeDebugView) {
view.visible = !view.visible;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_config_values() {
let cfg = default_probe_debug_config();
assert!((cfg.marker_radius - 0.25).abs() < 1e-6);
assert!(cfg.show_influence);
assert_eq!(cfg.max_markers, 64);
}
#[test]
fn new_view_is_empty() {
let v = new_probe_debug_view();
assert_eq!(probe_debug_marker_count(&v), 0);
assert!(probe_debug_is_visible(&v));
}
#[test]
fn add_marker_increments_count() {
let mut v = new_probe_debug_view();
let cfg = default_probe_debug_config();
probe_debug_add_marker(&mut v, &cfg, [1.0, 2.0, 3.0], [2.0, 2.0, 2.0], "probe_0");
assert_eq!(probe_debug_marker_count(&v), 1);
}
#[test]
fn add_marker_returns_unique_ids() {
let mut v = new_probe_debug_view();
let cfg = default_probe_debug_config();
let id1 = probe_debug_add_marker(&mut v, &cfg, [0.0; 3], [1.0; 3], "a");
let id2 = probe_debug_add_marker(&mut v, &cfg, [0.0; 3], [1.0; 3], "b");
assert_ne!(id1, id2);
assert!(id1 > 0);
assert!(id2 > 0);
}
#[test]
fn remove_marker_decrements_count() {
let mut v = new_probe_debug_view();
let cfg = default_probe_debug_config();
let id = probe_debug_add_marker(&mut v, &cfg, [0.0; 3], [1.0; 3], "p");
assert!(probe_debug_remove_marker(&mut v, id));
assert_eq!(probe_debug_marker_count(&v), 0);
}
#[test]
fn remove_nonexistent_returns_false() {
let mut v = new_probe_debug_view();
assert!(!probe_debug_remove_marker(&mut v, 999));
}
#[test]
fn set_visible_false() {
let mut v = new_probe_debug_view();
probe_debug_set_visible(&mut v, false);
assert!(!probe_debug_is_visible(&v));
}
#[test]
fn toggle_visibility() {
let mut v = new_probe_debug_view();
assert!(probe_debug_is_visible(&v));
probe_debug_toggle(&mut v);
assert!(!probe_debug_is_visible(&v));
probe_debug_toggle(&mut v);
assert!(probe_debug_is_visible(&v));
}
#[test]
fn json_contains_markers_key() {
let mut v = new_probe_debug_view();
let cfg = default_probe_debug_config();
probe_debug_add_marker(&mut v, &cfg, [1.0, 0.0, 0.0], [1.0, 1.0, 1.0], "env_probe");
let json = probe_debug_to_json(&v, &cfg);
assert!(json.contains("\"markers\""));
assert!(json.contains("env_probe"));
}
#[test]
fn max_markers_cap() {
let mut v = new_probe_debug_view();
let mut cfg = default_probe_debug_config();
cfg.max_markers = 2;
probe_debug_add_marker(&mut v, &cfg, [0.0; 3], [1.0; 3], "a");
probe_debug_add_marker(&mut v, &cfg, [0.0; 3], [1.0; 3], "b");
let id = probe_debug_add_marker(&mut v, &cfg, [0.0; 3], [1.0; 3], "c");
assert_eq!(id, 0);
assert_eq!(probe_debug_marker_count(&v), 2);
}
#[test]
fn clear_resets_state() {
let mut v = new_probe_debug_view();
let cfg = default_probe_debug_config();
probe_debug_add_marker(&mut v, &cfg, [0.0; 3], [1.0; 3], "x");
probe_debug_clear(&mut v);
assert_eq!(probe_debug_marker_count(&v), 0);
}
}