forked from 1b-agent/opencadstudio-upstream
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.
80 lines
2.3 KiB
Rust
80 lines
2.3 KiB
Rust
//! API v2 compatibility fixture.
|
|
//!
|
|
//! Mimics an old plugin compiled against `ocs_plugin_api` v2: it reports API
|
|
//! major 2 from `ocs_plugin_api_version()` and implements only the v2 surface
|
|
//! (`HostApi` methods up to `start_interactive`). The current host must still
|
|
//! be able to load and dispatch it.
|
|
|
|
use ocs_plugin_api::host::{BuiltinPlugin, HostApi};
|
|
use ocs_plugin_api::manifest::{ApiVersion, PluginManifest};
|
|
use ocs_plugin_api::ribbon::{CadModule, IconKind, ModuleEvent, RibbonGroup, RibbonItem, ToolDef};
|
|
|
|
static MANIFEST: PluginManifest = PluginManifest {
|
|
id: "opencad.my_plugin",
|
|
name: "My Plugin",
|
|
version: env!("CARGO_PKG_VERSION"),
|
|
description: "API v2 fixture plugin.",
|
|
api_version: ApiVersion { major: 2 },
|
|
ribbon_order: 60,
|
|
xdata_apps: &[],
|
|
command_prefixes: &["MP_"],
|
|
};
|
|
|
|
struct MyModule;
|
|
|
|
impl CadModule for MyModule {
|
|
fn id(&self) -> &'static str {
|
|
"my_plugin"
|
|
}
|
|
fn title(&self) -> &'static str {
|
|
"My Plugin"
|
|
}
|
|
fn ribbon_groups(&self) -> &[RibbonGroup] {
|
|
static GROUPS: std::sync::OnceLock<Vec<RibbonGroup>> = std::sync::OnceLock::new();
|
|
GROUPS.get_or_init(|| {
|
|
vec![RibbonGroup {
|
|
title: "Tools",
|
|
tools: vec![RibbonItem::LargeTool(ToolDef {
|
|
id: "MP_HELLO",
|
|
label: "Hello",
|
|
icon: IconKind::Glyph("*"),
|
|
event: ModuleEvent::Command("MP_HELLO".to_string()),
|
|
})],
|
|
}]
|
|
})
|
|
}
|
|
}
|
|
|
|
struct MyPlugin;
|
|
|
|
impl BuiltinPlugin for MyPlugin {
|
|
fn manifest(&self) -> &'static PluginManifest {
|
|
&MANIFEST
|
|
}
|
|
fn ribbon(&self) -> Box<dyn CadModule> {
|
|
Box::new(MyModule)
|
|
}
|
|
fn dispatch(&self, host: &mut dyn HostApi, cmd: &str) -> bool {
|
|
match cmd {
|
|
"MP_HELLO" => {
|
|
host.push_info("Hello from API v2 plugin");
|
|
true
|
|
}
|
|
_ => false,
|
|
}
|
|
}
|
|
}
|
|
|
|
// Custom C-ABI export that reports API v2, emulating an older build of
|
|
// `ocs_plugin_api::export_plugin!`.
|
|
#[no_mangle]
|
|
pub extern "C" fn ocs_plugin_api_version() -> u32 {
|
|
2
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn ocs_plugin_register() -> *mut Box<dyn BuiltinPlugin> {
|
|
let plugin: Box<dyn BuiltinPlugin> = Box::new(MyPlugin);
|
|
Box::into_raw(Box::new(plugin))
|
|
}
|