103 lines
3.9 KiB
Rust
103 lines
3.9 KiB
Rust
use std::sync::{Arc, Mutex};
|
||
use crate::data::repositories::project_repository::ProjectRepository;
|
||
use crate::data::repositories::material_repository::MaterialRepository;
|
||
use crate::data::repositories::model_repository::ModelRepository;
|
||
use crate::infrastructure::database::Database;
|
||
use crate::infrastructure::performance::PerformanceMonitor;
|
||
use crate::infrastructure::event_bus::EventBusManager;
|
||
|
||
/// 应用全局状态管理
|
||
/// 遵循 Tauri 开发规范的状态管理模式
|
||
pub struct AppState {
|
||
pub database: Mutex<Option<Arc<Database>>>,
|
||
pub project_repository: Mutex<Option<ProjectRepository>>,
|
||
pub material_repository: Mutex<Option<MaterialRepository>>,
|
||
pub model_repository: Mutex<Option<ModelRepository>>,
|
||
pub performance_monitor: Mutex<PerformanceMonitor>,
|
||
pub event_bus_manager: Arc<EventBusManager>,
|
||
}
|
||
|
||
impl AppState {
|
||
pub fn new() -> Self {
|
||
Self {
|
||
database: Mutex::new(None),
|
||
project_repository: Mutex::new(None),
|
||
material_repository: Mutex::new(None),
|
||
model_repository: Mutex::new(None),
|
||
performance_monitor: Mutex::new(PerformanceMonitor::new()),
|
||
event_bus_manager: Arc::new(EventBusManager::new()),
|
||
}
|
||
}
|
||
|
||
/// 初始化数据库连接
|
||
/// 遵循安全第一原则,确保数据库初始化的安全性
|
||
pub fn initialize_database(&self) -> anyhow::Result<()> {
|
||
let database = Arc::new(Database::new()?);
|
||
|
||
let project_repository = ProjectRepository::new(database.clone())?;
|
||
let material_repository = MaterialRepository::new(database.clone())?;
|
||
let model_repository = ModelRepository::new(database.clone());
|
||
|
||
*self.database.lock().unwrap() = Some(database.clone());
|
||
*self.project_repository.lock().unwrap() = Some(project_repository);
|
||
*self.material_repository.lock().unwrap() = Some(material_repository);
|
||
*self.model_repository.lock().unwrap() = Some(model_repository);
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 获取项目仓库实例
|
||
pub fn get_project_repository(&self) -> anyhow::Result<std::sync::MutexGuard<Option<ProjectRepository>>> {
|
||
Ok(self.project_repository.lock().unwrap())
|
||
}
|
||
|
||
/// 获取素材仓库实例
|
||
pub fn get_material_repository(&self) -> anyhow::Result<std::sync::MutexGuard<Option<MaterialRepository>>> {
|
||
Ok(self.material_repository.lock().unwrap())
|
||
}
|
||
|
||
/// 获取模特仓库实例
|
||
pub fn get_model_repository(&self) -> anyhow::Result<std::sync::MutexGuard<Option<ModelRepository>>> {
|
||
Ok(self.model_repository.lock().unwrap())
|
||
}
|
||
|
||
/// 获取数据库实例
|
||
pub fn get_database(&self) -> Arc<Database> {
|
||
// 使用全局静态数据库实例,确保整个应用只有一个数据库实例
|
||
use std::sync::OnceLock;
|
||
static DATABASE_INSTANCE: OnceLock<Arc<Database>> = OnceLock::new();
|
||
|
||
DATABASE_INSTANCE.get_or_init(|| {
|
||
// 只在第一次调用时初始化数据库
|
||
Arc::new(Database::new().unwrap())
|
||
}).clone()
|
||
}
|
||
|
||
/// 获取数据库连接
|
||
pub fn get_connection(&self) -> anyhow::Result<std::sync::Arc<std::sync::Mutex<rusqlite::Connection>>> {
|
||
let database = self.get_database();
|
||
Ok(database.get_connection())
|
||
}
|
||
|
||
/// 用于测试的构造函数
|
||
#[cfg(test)]
|
||
pub fn new_with_database(_database: Arc<Database>) -> Self {
|
||
let state = Self {
|
||
database: Mutex::new(None),
|
||
project_repository: Mutex::new(None),
|
||
material_repository: Mutex::new(None),
|
||
model_repository: Mutex::new(None),
|
||
performance_monitor: Mutex::new(PerformanceMonitor::new()),
|
||
event_bus_manager: Arc::new(EventBusManager::new()),
|
||
};
|
||
// 不直接存储database,而是在需要时返回传入的database
|
||
state
|
||
}
|
||
}
|
||
|
||
impl Default for AppState {
|
||
fn default() -> Self {
|
||
Self::new()
|
||
}
|
||
}
|