diff --git a/build.rs b/build.rs index 611a726a..c7ed92a0 100644 --- a/build.rs +++ b/build.rs @@ -1,30 +1,11 @@ -// build.rs — auto-generates src/modules/registry.rs +// build.rs — Windows executable icon embedding. // -// Scans src/modules/ for subdirectories containing a mod.rs file. -// Each subdirectory name like "home" maps to a struct "HomeModule" -// defined in src/modules/home/mod.rs. -// -// Rules for a directory to be picked up: -// • Located directly in src/modules/ -// • Contains a mod.rs file -// • Does NOT contain plugin.toml (add-ons register via BuiltinPlugin::ribbon) -// • Defines a pub struct {PascalCase}Module implementing CadModule -// (unit struct — no ::new() needed) -// -// Tab display order: the PRIORITY list below controls order. -// Unlisted modules appear after priority modules, sorted alphabetically. -// -// Adding a new module: -// 1. Create src/modules/my_name/mod.rs (implement CadModule as MyNameModule) -// 2. Add `pub mod my_name;` to src/modules/mod.rs -// 3. cargo build → module appears in the ribbon +// The core ribbon module registry used to be generated here; it is now a +// hand-written static list in src/modules/registry.rs. -use std::fs; +#[cfg(windows)] use std::path::Path; -// Display order for known modules; unknown modules follow alphabetically. -const PRIORITY: &[&str] = &["draw", "model", "insert", "annotate", "view", "manage"]; - fn main() { // Windows: embed AppIcon.ico into the .exe so the executable carries its // own icon (Explorer, taskbar, Start-menu tile, file associations). The @@ -41,70 +22,4 @@ fn main() { } } } - - let mods_dir = Path::new("src/modules"); - println!("cargo:rerun-if-changed=src/modules"); - - // Collect subdirectories that contain mod.rs. - let mut modules: Vec = fs::read_dir(mods_dir) - .expect("src/modules/ not found") - .filter_map(|e| { - let entry = e.ok()?; - if !entry.file_type().ok()?.is_dir() { - return None; - } - let name = entry.file_name().into_string().ok()?; - let mod_file = mods_dir.join(&name).join("mod.rs"); - let plugin_toml = mods_dir.join(&name).join("plugin.toml"); - if mod_file.exists() && !plugin_toml.exists() { - Some(name) - } else { - None - } - }) - .collect(); - - // Sort: priority order first, then alphabetical for the rest. - modules.sort_by_key(|name| { - let pri = PRIORITY.iter().position(|p| *p == name.as_str()); - (pri.map(|i| i as u32).unwrap_or(u32::MAX), name.clone()) - }); - - // snake_case → PascalCase + "Module" - let to_struct = |s: &str| -> String { - s.split('_') - .map(|w| { - let mut c = w.chars(); - match c.next() { - None => String::new(), - Some(f) => f.to_uppercase().collect::() + c.as_str(), - } - }) - .collect::() - + "Module" - }; - - let mut out = String::from( - "// AUTO-GENERATED by build.rs — do not edit by hand.\n\ - // To add a module: create src/modules/my_name/mod.rs + add `pub mod my_name;` to modules/mod.rs.\n\n\ - use crate::modules::CadModule;\n\n\ - /// Returns one boxed instance of every registered CAD module.\n\ - /// Called once at startup by `Ribbon::new()`.\n\ - pub fn all_modules() -> Vec> {\n\ - \tvec![\n", - ); - - for module in &modules { - let s = to_struct(module); - out.push_str(&format!("\t\tBox::new(super::{module}::{s}),\n")); - } - - out.push_str("\t]\n}\n"); - - let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR not set"); - let out_path = Path::new(&out_dir).join("modules_registry.rs"); - let current = fs::read_to_string(&out_path).unwrap_or_default(); - if current != out { - fs::write(&out_path, &out).expect("failed to write modules_registry.rs"); - } } diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 6dfbe33e..e517bf80 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -4,7 +4,7 @@ // 1. Create `src/modules/my_name/` directory (no `plugin.toml`) // 2. Add `src/modules/my_name/mod.rs` implementing `CadModule` as `MyNameModule` // 3. Add `pub mod my_name;` below -// 4. `cargo build` — tab appears via build.rs registry +// 4. Add a `Box::new(my_name::MyNameModule)` line in `registry::all_modules()` // // To add an **add-on plugin** (Storm Sewer, …): // See `docs/plugin-architecture.md` and copy `docs/plugin-template/`. @@ -32,6 +32,6 @@ pub mod layout; pub mod manage; pub mod view; -// ── Auto-generated module registry ─────────────────────────────────────── -// build.rs writes this file; it contains only `all_modules()`. +// ── Core module registry ───────────────────────────────────────────────── +// Hand-written `all_modules()` listing the built-in ribbon tabs. pub mod registry; diff --git a/src/modules/registry.rs b/src/modules/registry.rs index 42e2421a..c9ff55f7 100644 --- a/src/modules/registry.rs +++ b/src/modules/registry.rs @@ -1,4 +1,24 @@ -// AUTO-GENERATED include — see build.rs for the actual generator. -// The generated registry is written to Cargo's OUT_DIR and included here so -// the source tree is not modified during build. -include!(concat!(env!("OUT_DIR"), "/modules_registry.rs")); +// Core ribbon module registry — one boxed instance of every built-in CAD +// module, in ribbon-tab display order. External add-ons are appended on top +// of this list at runtime by `plugin::registry`. +// +// To add a core module: +// 1. Create src/modules/my_name/mod.rs (implement CadModule as MyNameModule) +// 2. Add `pub mod my_name;` to src/modules/mod.rs +// 3. Add one `Box::new(super::my_name::MyNameModule)` line below, in the +// position you want its tab to appear. +use crate::modules::CadModule; + +/// Returns one boxed instance of every registered core CAD module. +/// Called once at startup by `Ribbon::new()`. +pub fn all_modules() -> Vec> { + vec![ + Box::new(super::draw::DrawModule), + Box::new(super::model::ModelModule), + Box::new(super::insert::InsertModule), + Box::new(super::annotate::AnnotateModule), + Box::new(super::view::ViewModule), + Box::new(super::manage::ManageModule), + Box::new(super::layout::LayoutModule), + ] +}