fix BLE wifi status delivery and websocket compile issues
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
use crate::core::config::AppConfig;
|
||||
use crate::core::message::{Destination, Envelope, Message};
|
||||
use crate::core::plugin::{Plugin, PluginContext};
|
||||
use anyhow::Result;
|
||||
use anyhow::{anyhow, Result};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::{mpsc, Arc};
|
||||
|
||||
/// 中央调度器:插件注册、生命周期管理、消息路由
|
||||
@@ -33,6 +34,8 @@ impl ServiceManager {
|
||||
|
||||
/// 按注册顺序 init() + start() 所有插件
|
||||
pub fn start_all(&mut self) -> Result<()> {
|
||||
self.validate_and_sort_plugins()?;
|
||||
|
||||
// init
|
||||
for plugin in &mut self.plugins {
|
||||
let ctx = PluginContext {
|
||||
@@ -105,18 +108,120 @@ impl ServiceManager {
|
||||
println!("[ServiceManager] 收到 Shutdown 指令");
|
||||
self.broadcast_message(Message::Shutdown);
|
||||
}
|
||||
Message::WifiResult(payload) => {
|
||||
self.broadcast_message(Message::WifiResult(payload));
|
||||
}
|
||||
Message::PlayerStatus(status) => {
|
||||
self.broadcast_message(Message::PlayerStatus(status));
|
||||
}
|
||||
Message::StateChanged {
|
||||
old_state,
|
||||
new_state,
|
||||
} => {
|
||||
self.broadcast_message(Message::StateChanged {
|
||||
old_state,
|
||||
new_state,
|
||||
});
|
||||
}
|
||||
Message::WifiProvisioned { ssid, ip } => {
|
||||
self.broadcast_message(Message::WifiProvisioned { ssid, ip });
|
||||
}
|
||||
Message::ConfigReloadRequest => {
|
||||
println!("[ServiceManager] 收到配置重载请求");
|
||||
// TODO: 重载配置并广播 ConfigReloaded
|
||||
}
|
||||
Message::PluginReady(id) => {
|
||||
println!("[ServiceManager] 插件 '{}' 就绪", id);
|
||||
self.broadcast_message(Message::PluginReady(id));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_and_sort_plugins(&mut self) -> Result<()> {
|
||||
let mut plugin_ids = Vec::with_capacity(self.plugins.len());
|
||||
let mut plugin_set = HashSet::with_capacity(self.plugins.len());
|
||||
let mut dependency_map = HashMap::with_capacity(self.plugins.len());
|
||||
|
||||
for plugin in &self.plugins {
|
||||
let id = plugin.id();
|
||||
if !plugin_set.insert(id) {
|
||||
return Err(anyhow!("duplicate plugin id registered: '{id}'"));
|
||||
}
|
||||
|
||||
plugin_ids.push(id);
|
||||
dependency_map.insert(id, plugin.dependencies());
|
||||
}
|
||||
|
||||
for (plugin_id, dependencies) in &dependency_map {
|
||||
for dependency in dependencies {
|
||||
if dependency == plugin_id {
|
||||
return Err(anyhow!("plugin '{plugin_id}' cannot depend on itself"));
|
||||
}
|
||||
|
||||
if !plugin_set.contains(dependency) {
|
||||
return Err(anyhow!(
|
||||
"plugin '{plugin_id}' depends on missing plugin '{dependency}'"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut resolved = HashSet::with_capacity(plugin_ids.len());
|
||||
let mut sorted_ids = Vec::with_capacity(plugin_ids.len());
|
||||
|
||||
while sorted_ids.len() < plugin_ids.len() {
|
||||
let mut progressed = false;
|
||||
|
||||
for plugin_id in &plugin_ids {
|
||||
if resolved.contains(plugin_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let dependencies = dependency_map
|
||||
.get(plugin_id)
|
||||
.expect("plugin dependency map must contain all registered ids");
|
||||
|
||||
if dependencies
|
||||
.iter()
|
||||
.all(|dependency| resolved.contains(dependency))
|
||||
{
|
||||
resolved.insert(*plugin_id);
|
||||
sorted_ids.push(*plugin_id);
|
||||
progressed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if !progressed {
|
||||
let unresolved = plugin_ids
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|plugin_id| !resolved.contains(plugin_id))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
||||
return Err(anyhow!(
|
||||
"plugin dependency cycle detected among: {unresolved}"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let mut remaining_plugins = std::mem::take(&mut self.plugins);
|
||||
let mut ordered_plugins = Vec::with_capacity(remaining_plugins.len());
|
||||
|
||||
for plugin_id in sorted_ids {
|
||||
let index = remaining_plugins
|
||||
.iter()
|
||||
.position(|plugin| plugin.id() == plugin_id)
|
||||
.ok_or_else(|| anyhow!("plugin '{plugin_id}' disappeared during sorting"))?;
|
||||
ordered_plugins.push(remaining_plugins.remove(index));
|
||||
}
|
||||
|
||||
self.plugins = ordered_plugins;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn broadcast_message(&mut self, msg: Message) {
|
||||
let should_shutdown = matches!(&msg, Message::Shutdown);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user