mixvideo-v2/apps/desktop/src-tauri/src/app_state.rs

103 lines
3.9 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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()
}
}