cad-editor/src/modules/layout/mod.rs
Karim Jerbi 73b05e1dec perf(core): cache ribbon_groups() with OnceLock, avoid per-frame tree allocations
Change CadModule::ribbon_groups() from -> Vec<RibbonGroup> to -> &[RibbonGroup],
backed by a per-module OnceLock cache. The ribbon group tree is static data
(&'static str, Copy enums) that was being fully reconstructed — Vecs, String
clones, enum discriminants — on every call, including all three per-frame
call sites (view(), dropdown_overlay(), style_combo_overlay()).

- 7 built-in modules + 2 plugin templates cache via function-local OnceLock.
  Safe because each is a unit struct with exactly one instance per process
  (plugins run in isolated child processes; see PluginProcess::spawn()).
- SharedCadModule avoids the static pattern entirely, storing groups in an
  instance field (owned.rs).
- IPC runner converts &RibbonGroup -> OwnedRibbonGroup directly via new
  From<&T> impls, avoiding an intermediate clone.
- render_small/render_large and the two make_tool_row closures now borrow
  (&RibbonItem, &[ToolDef]) instead of taking ownership, so the view loop
  doesn't need to clone items to satisfy the old by-value signatures.
- Various match-ergonomics deref fixes (*id, *default, *icon, etc.) from
  the &RibbonItem pattern change.
2026-07-02 21:00:57 +01:00

71 lines
2.4 KiB
Rust

// Layout module — paper space tools (viewports, scale, plot settings).
// This tab is only shown when the active layout is not "Model".
pub mod mview;
pub mod vplayer;
use crate::modules::{CadModule, IconKind, ModuleEvent, RibbonGroup, ToolDef};
/// Paper-space context tools, as a flat list for the right-edge side toolbar
/// (the contextual ribbon tab is no longer shown). Viewport + plot actions.
pub fn paper_space_tools() -> Vec<ToolDef> {
vec![
mview::tool(),
ToolDef {
id: "PAGESETUP",
label: "Page Setup",
icon: IconKind::Svg(include_bytes!("../../../assets/icons/pagesetup.svg")),
event: ModuleEvent::Command("PAGESETUP".to_string()),
},
ToolDef {
id: "PLOT",
label: "Export PDF",
icon: IconKind::Svg(include_bytes!("../../../assets/icons/plot.svg")),
event: ModuleEvent::Command("PLOT".to_string()),
},
]
}
pub struct LayoutModule;
impl CadModule for LayoutModule {
fn id(&self) -> &'static str {
"layout"
}
fn title(&self) -> &'static str {
"Layout"
}
fn ribbon_groups(&self) -> &[RibbonGroup] {
static GROUPS: std::sync::OnceLock<Vec<RibbonGroup>> = std::sync::OnceLock::new();
GROUPS.get_or_init(|| {
vec![
RibbonGroup {
title: "Viewport",
tools: vec![mview::tool().into()],
},
RibbonGroup {
title: "Plot",
tools: vec![
ToolDef {
id: "PAGESETUP",
label: "Page Setup",
icon: IconKind::Svg(include_bytes!(
"../../../assets/icons/pagesetup.svg"
)),
event: ModuleEvent::Command("PAGESETUP".to_string()),
}
.into(),
ToolDef {
id: "PLOT",
label: "Export PDF",
icon: IconKind::Svg(include_bytes!("../../../assets/icons/plot.svg")),
event: ModuleEvent::Command("PLOT".to_string()),
}
.into(),
],
},
]
})
}
}