Files
ShowenV2/docs/PLUGIN_DEPENDENCY.md
showen becd200150 refactor: 整理项目文件夹结构 + 更新项目状态
- docs/: 团队流程文档 (10个md)
- .showen/: 管理状态文件 (CEO_BACKUP, RECOVERY, TEAM_CHAT, CEO_LOOP)
- 根目录只保留 README.md + PROGRESS.md
- 更新 RECOVERY.md/CEO_BACKUP.md/PROGRESS.md 反映自测机制完成
- 更新 souls/liu-jianguo.md 当前状态
2026-03-13 04:45:35 +08:00

12 KiB
Raw Permalink Blame History

ShowenV2 插件依赖模型

插件分类

独立插件Independent Plugins

定义: 只依赖 core不依赖其他插件可以独立运行

特点:

  • 自包含,功能完整
  • 只通过 core 的消息机制与其他插件通信
  • 可以单独测试和部署
  • 启动顺序无要求

示例:

  • screen - 屏幕管理(唤醒锁、光标控制)
  • wifi - WiFi 管理(扫描、连接、热点)
  • video - 视频播放(状态机、渲染)
  • ble - 蓝牙服务GATT、配网双架构:既可配置 WiFi也可独立提供网络功能

依赖插件Dependent Plugins

定义: 依赖其他插件的功能,需要特定插件先启动

特点:

  • 功能依赖其他插件
  • 需要声明依赖关系
  • 启动顺序有要求
  • 通过消息机制与依赖插件通信

示例:

  • http - 依赖 video通过 HTTP API 控制视频播放)

依赖关系图

独立插件层(多架构并存):
┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐
│ screen  │  │  wifi   │  │  video  │  │   ble   │  │ future  │
└─────────┘  └─────────┘  └─────────┘  └─────────┘  └─────────┘
     ↑            ↑            ↑            ↑            ↑
     │            │            │            │            │
     │            └────────────┼────────────┼────────────┘
     │                 ↕       │            ↕
     │            (多架构协作)  │       (可扩展)
     │                         │
     └─────────────────────────┘
                core
              
依赖插件层:
┌─────────┐
│  http   │
│ (依赖   │
│ video)  │
└─────────┘
     ↑
     │
   core

多架构说明

  • WiFi 架构:通过 WiFi 连接网络
  • BLE 架构:通过蓝牙连接网络
  • 未来架构可扩展任何通讯方式Zigbee、LoRa、NFC、红外、串口等
  • 架构协作:各架构可以互相配置和协作(通过消息)
  • 架构独立:每个架构都可以独立工作
  • 用户选择:用户可以选择使用任何一种或多种架构

插件依赖声明

Plugin Trait 扩展

pub trait Plugin: Send {
    fn info(&self) -> PluginInfo;
    
    // 新增:声明依赖的插件
    fn dependencies(&self) -> Vec<&'static str> {
        vec![]  // 默认无依赖
    }
    
    fn init(&mut self, ctx: PluginContext) -> Result<()>;
    fn start(&mut self) -> Result<()>;
    fn handle_message(&mut self, msg: Message) -> Result<()>;
    fn stop(&mut self) -> Result<()>;
}

依赖声明示例

impl Plugin for HttpPlugin {
    fn dependencies(&self) -> Vec<&'static str> {
        vec!["video"]  // HTTP 依赖 Video 插件
    }
}

impl Plugin for BlePlugin {
    fn dependencies(&self) -> Vec<&'static str> {
        vec![]  // BLE 是独立插件,通过消息与 WiFi 通信
    }
}

impl Plugin for WifiPlugin {
    fn dependencies(&self) -> Vec<&'static str> {
        vec![]  // WiFi 是独立插件
    }
}

impl Plugin for VideoPlugin {
    fn dependencies(&self) -> Vec<&'static str> {
        vec![]  // Video 是独立插件
    }
}

启动顺序管理

ServiceManager 职责

  1. 依赖检查: 启动前检查所有依赖是否满足
  2. 拓扑排序: 根据依赖关系计算启动顺序
  3. 顺序启动: 按照拓扑排序结果依次启动插件
  4. 错误处理: 依赖插件启动失败时,跳过依赖它的插件

启动流程

1. 注册所有插件
2. 构建依赖图
3. 检查循环依赖(报错)
4. 拓扑排序
5. 按顺序 init() 所有插件
6. 按顺序 start() 所有插件

示例启动顺序

Phase 1: 独立插件(并行启动)
  - screen.init() → screen.start()
  - wifi.init() → wifi.start()
  - video.init() → video.start()
  - ble.init() → ble.start()

Phase 2: 依赖插件
  - http.init() → http.start() (依赖 video)

消息通信模式

独立插件

  • 接收 Broadcast 消息
  • 发送消息给 core
  • 不直接与其他插件通信

依赖插件

  • 接收 Broadcast 消息
  • 发送消息给特定插件(通过 core 路由)
  • 等待依赖插件的响应消息

消息路由示例

// 场景1: BLE 配置 WiFi双架构协作
ble_plugin.send(Message::WifiCommand(WifiCommand::Connect { ssid, password }));
wifi_plugin.handle_message(Message::WifiCommand(...));
wifi_plugin.send(Message::WifiResult(result));  // Broadcast
ble_plugin.handle_message(Message::WifiResult(result));

// 场景2: BLE 独立提供网络功能(不依赖 WiFi
// 用户通过 BLE 直接与设备通信,不需要 WiFi
ble_plugin.handle_gatt_request(request);
ble_plugin.send_gatt_response(response);

// 场景3: HTTP 控制 Video强依赖
http_plugin.send(Message::PlayerCommand(PlayerCommand::Play));
video_plugin.handle_message(Message::PlayerCommand(...));
video_plugin.send(Message::PlayerStatus(status));  // Broadcast

关键区别

  • 双架构WiFi + BLE:两套独立的网络方案,可以互相配置,也可以独立工作
    • BLE 可以配置 WiFi松耦合通过消息
    • BLE 可以独立提供网络功能(不依赖 WiFi
    • WiFi 可以独立工作(不依赖 BLE
  • 强依赖HTTP → VideoHTTP 必须在 Video 启动后才能工作

当前插件分类

独立插件

插件 功能 依赖 状态
screen 屏幕管理 core 完成
wifi WiFi 网络 core 完成
video 视频播放 core 完成
ble 蓝牙网络 core 完成

双架构说明

  • WiFi 架构:通过 WiFi 连接网络,支持扫描、连接、热点
  • BLE 架构:通过蓝牙连接网络,支持 GATT 服务、配网
  • 协作模式BLE 可以配置 WiFi通过消息通信
  • 独立模式BLE 和 WiFi 都可以独立提供网络功能

依赖插件

插件 功能 依赖 状态
http HTTP API core + video 完成

说明HTTP 必须依赖 Video因为 HTTP API 的核心功能是控制视频播放。


未来插件规划

Phase 2 独立插件(通讯和控制)

  • render - 3D 渲染引擎(独立)
  • ai_voice - AI 语音识别(独立)
  • ai_tts - AI 语音合成(独立)
  • zigbee - Zigbee 通讯(独立,智能家居)
  • lora - LoRa 远程通讯(独立,物联网)
  • nfc - NFC 近场通讯(独立,快速配对)
  • infrared - 红外遥控(独立,传统家电控制)
  • serial - 串口通讯(独立,硬件扩展)
  • mqtt - MQTT 协议(独立,物联网标准)

Phase 2 依赖插件

  • vr - VR 输出(依赖 render 或 video
  • ar - AR 输出(依赖 render 或 video
  • ai_assistant - AI 助手(依赖 ai_voice + ai_tts + video

Phase 3 依赖插件

  • cloud_sync - 云端同步(依赖 http 或任何网络插件)
  • social - 社交分享(依赖 http + cloud_sync
  • editor - 内容编辑器(依赖 video + render

通讯插件扩展性

ShowenV2 支持任何通讯方式作为独立插件:

  • 有线通讯: 以太网、USB、串口、CAN 总线
  • 无线通讯: WiFi、BLE、Zigbee、LoRa、NFC、红外
  • 网络协议: HTTP、WebSocket、MQTT、CoAP、gRPC
  • 专有协议: 自定义协议插件

所有通讯插件都是独立的,可以:

  • 独立工作(提供通讯能力)
  • 互相配置(通过消息协作)
  • 并存使用(多种通讯方式同时工作)

设计原则

1. 最小依赖原则

  • 尽量设计独立插件
  • 依赖关系要有明确的业务理由
  • 避免过度依赖

2. 单向依赖原则

  • 依赖关系必须是单向的
  • 禁止循环依赖
  • 依赖层级不超过 3层

3. 松耦合原则

  • 通过消息通信,不直接调用
  • 依赖插件可以缺失(降级运行)
  • 依赖插件可以替换(接口兼容)

4. 可测试原则

  • 依赖插件可以 mock
  • 独立插件可以单独测试
  • 依赖插件可以集成测试

5. 双架构原则(新增)

  • 支持多套独立架构并存(如 WiFi + BLE + Zigbee + ...
  • 架构之间可以协作(通过消息)
  • 架构之间可以独立工作(不强依赖)
  • 用户可以选择使用哪套架构

6. 动态扩展原则(新增)

  • 插件动态注册: 插件可以在运行时注册和卸载
  • 插件动态安装: 支持从插件市场下载安装新插件
  • 热插拔: 插件可以在不重启系统的情况下加载/卸载
  • 版本管理: 支持插件版本更新和回滚
  • 依赖检查: 动态安装时自动检查依赖关系

实现任务

架构团队任务

  1. 扩展 Plugin trait添加 dependencies() 方法
  2. 实现 ServiceManager 依赖检查和拓扑排序
  3. 设计插件动态注册机制
  4. 设计插件热加载/卸载机制
  5. 设计插件版本管理系统
  6. 编写技术设计文档

开发团队任务

  1. 为现有插件添加 dependencies() 实现
  2. 测试启动顺序是否正确
  3. 验证消息通信是否正常
  4. 实现插件动态注册 API
  5. 实现插件加载/卸载功能

产品团队任务

  1. 梳理 Phase 2/3 插件的依赖关系
  2. 确认依赖关系的业务合理性
  3. 编写插件依赖的 PRD
  4. 设计插件市场功能
  5. 设计插件安装/更新流程

插件动态管理

插件生命周期

未安装 → 下载 → 安装 → 注册 → 初始化 → 启动 → 运行
                                              ↓
                                            停止 → 卸载 → 删除

动态注册 API

// ServiceManager 新增方法
impl ServiceManager {
    // 动态注册插件
    pub fn register_plugin(&mut self, plugin: Box<dyn Plugin>) -> Result<()>;
    
    // 动态卸载插件
    pub fn unregister_plugin(&mut self, name: &str) -> Result<()>;
    
    // 重新加载插件
    pub fn reload_plugin(&mut self, name: &str) -> Result<()>;
    
    // 获取已注册插件列表
    pub fn list_plugins(&self) -> Vec<PluginInfo>;
    
    // 检查插件依赖
    pub fn check_dependencies(&self, plugin: &dyn Plugin) -> Result<()>;
}

插件安装流程

1. 用户从插件市场选择插件
2. 下载插件包(.so / .dll / .dylib
3. 验证插件签名和版本
4. 检查依赖关系
5. 安装到 plugins/ 目录
6. 动态加载插件
7. 注册到 ServiceManager
8. 初始化并启动插件

插件卸载流程

1. 检查是否有其他插件依赖
2. 停止插件运行
3. 从 ServiceManager 注销
4. 卸载插件模块
5. 删除插件文件(可选)

插件更新流程

1. 检查新版本
2. 下载新版本插件
3. 停止旧版本插件
4. 备份旧版本
5. 安装新版本
6. 启动新版本
7. 验证运行正常
8. 删除旧版本备份

插件市场

功能:
- 浏览插件列表
- 搜索插件
- 查看插件详情(功能、依赖、评分、评论)
- 下载/安装插件
- 更新插件
- 卸载插件
- 插件评分和评论

技术实现:
- HTTP API 获取插件列表
- 插件包托管在云端
- 版本管理和更新检查
- 插件签名验证

安全机制

1. 插件签名验证(防止恶意插件)
2. 沙箱隔离(限制插件权限)
3. 依赖检查(防止依赖冲突)
4. 版本兼容性检查
5. 插件审核机制(官方市场)

文档版本: v1.0
最后更新: 2026-03-12
负责人: 陈逸飞 (CEO)