feat: 实现动态插件系统 (6阶段完成)
- 阶段1: 消息类型序列化 (Serialize/Deserialize, &'static str → String) - 阶段2: FFI 边界类型 + Plugin SDK (plugin_abi, showen-plugin-sdk crate) - 阶段3: PluginLoader + DynamicPlugin (libloading 动态加载 .so) - 阶段4: 版本管理 + 错误策略 (VersionManager, PluginState, 自动回退) - 阶段5: 远程仓库客户端 (HTTP 下载 + tar.gz 安装) - 阶段6: 示例插件 + HTTP 管理 API + 全目录 README 文档 54/54 测试通过,0 warnings。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
41
src/main.rs
41
src/main.rs
@@ -1,5 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use showen_v2::core::config::AppConfig;
|
||||
use showen_v2::core::plugin_loader::PluginLoader;
|
||||
use showen_v2::core::service_manager::ServiceManager;
|
||||
use showen_v2::plugins::{
|
||||
ble::BlePlugin, http::HttpPlugin, screen::ScreenPlugin, video::VideoPlugin, wifi::WifiPlugin,
|
||||
@@ -64,6 +65,46 @@ fn main() -> Result<()> {
|
||||
manager.register(Box::new(HttpPlugin::new()));
|
||||
println!(" ✓ HttpPlugin");
|
||||
|
||||
// 加载动态插件
|
||||
let plugin_store = std::path::Path::new("plugin_store");
|
||||
if plugin_store.exists() {
|
||||
println!("扫描动态插件...");
|
||||
let loader = PluginLoader::new(plugin_store);
|
||||
match loader.load_registry() {
|
||||
Ok(registry) => {
|
||||
for (plugin_id, entry) in ®istry.plugins {
|
||||
if !entry.enabled {
|
||||
println!(" - {plugin_id} (禁用)");
|
||||
continue;
|
||||
}
|
||||
|
||||
match loader.load_plugin(plugin_id, Some(&entry.active_version)) {
|
||||
Ok((plugin, manifest)) => {
|
||||
manager.register_dynamic(
|
||||
Box::new(plugin),
|
||||
manifest.error_policy,
|
||||
entry.max_errors,
|
||||
);
|
||||
println!(
|
||||
" ✓ {} v{} (动态)",
|
||||
plugin_id, entry.active_version
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
" ✗ {} v{} 加载失败: {e}",
|
||||
plugin_id, entry.active_version
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("读取插件注册表失败: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置 Ctrl+C 信号处理
|
||||
let running = Arc::new(AtomicBool::new(true));
|
||||
let r = running.clone();
|
||||
|
||||
Reference in New Issue
Block a user