Merge pull request #80 from mf4633/feature/plugin-host

Add plugin host (Phase 1)
This commit is contained in:
Hakan Seven authored and GitHub committed 2026-06-10 00:37:37 +03:00
commit 6a70e99dd5
38 files changed
+1264 -20

No files matched your search

+11
View File
@@ -0,0 +1,11 @@
use crate::plugin::host::HostSession;
pub fn handle(host: &mut HostSession<'_>, cmd: &str) -> bool {
match cmd {
"DP_HELLO" => {
host.push_info("Hello from demo_plugin (plugin host OK).");
true
}
_ => false,
}
}
+14
View File
@@ -0,0 +1,14 @@
use crate::plugin::manifest::{ApiVersion, PluginManifest};
pub const PLUGIN_ID: &str = "opencad.demo_plugin";
pub static MANIFEST: PluginManifest = PluginManifest {
id: PLUGIN_ID,
name: "Demo Plugin",
version: "0.1.0",
description: "Minimal add-on for plugin-host integration tests",
api_version: ApiVersion::CURRENT,
ribbon_order: 99,
xdata_apps: &[],
command_prefixes: &["DP_"],
};
+47
View File
@@ -0,0 +1,47 @@
// Minimal in-tree add-on — validates plugin host on `feature/plugin-host`.
pub mod dispatch;
pub mod manifest;
pub mod plugin;
pub mod register;
use crate::modules::{CadModule, IconKind, ModuleEvent, RibbonGroup, RibbonItem, ToolDef};
inventory::submit!(crate::command::CommandRegistration {
names: &["DP_HELLO"]
});
pub struct DemoPluginModule;
impl CadModule for DemoPluginModule {
fn id(&self) -> &'static str {
"demo_plugin"
}
fn title(&self) -> &'static str {
"Demo Plugin"
}
fn ribbon_groups(&self) -> Vec<RibbonGroup> {
vec![RibbonGroup {
title: "Smoke",
tools: vec![RibbonItem::LargeTool(ToolDef {
id: "DP_HELLO",
label: "Hello",
icon: IconKind::Glyph("★"),
event: ModuleEvent::Command("DP_HELLO".to_string()),
})],
}]
}
}
#[cfg(test)]
mod tests {
use crate::plugin::all_ribbon_modules;
#[test]
fn ribbon_tab_is_registered() {
let titles: Vec<&str> = all_ribbon_modules().iter().map(|m| m.title()).collect();
assert!(titles.contains(&"Demo Plugin"), "tabs: {titles:?}");
}
}
+21
View File
@@ -0,0 +1,21 @@
use crate::plugin::host::{BuiltinPlugin, HostSession};
use crate::plugin::manifest::PluginManifest;
use super::dispatch;
use super::manifest;
pub struct DemoPlugin;
impl BuiltinPlugin for DemoPlugin {
fn manifest(&self) -> &'static PluginManifest {
&manifest::MANIFEST
}
fn ribbon(&self) -> Box<dyn crate::modules::CadModule> {
Box::new(super::DemoPluginModule)
}
fn dispatch(&self, host: &mut HostSession<'_>, cmd: &str) -> bool {
dispatch::handle(host, cmd)
}
}
+13
View File
@@ -0,0 +1,13 @@
[plugin]
id = "opencad.demo_plugin"
name = "Demo Plugin"
version = "0.1.0"
description = "Minimal add-on for plugin-host integration tests"
author = "Open CAD Studio contributors"
license = "GPL-3.0-only"
[opencad]
api_version = 1
ribbon_order = 99
command_prefixes = ["DP_"]
xdata_apps = []
+7
View File
@@ -0,0 +1,7 @@
use super::plugin::DemoPlugin;
inventory::submit! {
crate::plugin::registry::PluginRegistration {
construct: || Box::new(DemoPlugin),
}
}
+7 -3
View File
@@ -1,10 +1,13 @@
// Module system — CadModule, ToolDef, RibbonGroup.
//
// To add a new module:
// 1. Create `src/modules/my_name/` directory
// To add a **core** ribbon tab (Home, View, …):
// 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` — module appears in the ribbon automatically
// 4. `cargo build` — tab appears via build.rs registry
//
// To add an **add-on plugin** (Storm Sewer, …):
// See `docs/plugin-architecture.md` and copy `docs/plugin-template/`.
//
// Each module folder contains:
// - mod.rs : module definition (ribbon groups + tool layout)
@@ -136,6 +139,7 @@ pub mod home;
pub mod insert;
pub mod model;
pub mod layout;
pub mod demo_plugin;
pub mod manage;
pub mod view;