diff --git a/src-tauri/src/constants.rs b/src-tauri/src/constants.rs index 094604b37..f5f40d6f6 100644 --- a/src-tauri/src/constants.rs +++ b/src-tauri/src/constants.rs @@ -23,7 +23,6 @@ pub mod timing { use super::Duration; pub const CONFIG_UPDATE_DEBOUNCE: Duration = Duration::from_millis(300); - pub const EVENT_EMIT_DELAY: Duration = Duration::from_millis(20); pub const STARTUP_ERROR_DELAY: Duration = Duration::from_secs(2); #[cfg(target_os = "windows")] diff --git a/src-tauri/src/core/handle.rs b/src-tauri/src/core/handle.rs index 3f3a6ff7a..d58ec706e 100644 --- a/src-tauri/src/core/handle.rs +++ b/src-tauri/src/core/handle.rs @@ -1,10 +1,6 @@ -use crate::{APP_HANDLE, singleton, utils::window_manager::WindowManager}; -use parking_lot::RwLock; +use crate::{APP_HANDLE, singleton}; use smartstring::alias::String; -use std::sync::{ - Arc, - atomic::{AtomicBool, Ordering}, -}; +use std::sync::atomic::{AtomicBool, Ordering}; use tauri::AppHandle; use tauri_plugin_mihomo::{Mihomo, MihomoExt as _}; use tokio::sync::RwLockReadGuard; @@ -14,14 +10,12 @@ use super::notification::{FrontendEvent, NotificationSystem}; #[derive(Debug)] pub struct Handle { is_exiting: AtomicBool, - pub(crate) notification_system: Arc>>, } impl Default for Handle { fn default() -> Self { Self { is_exiting: AtomicBool::new(false), - notification_system: Arc::new(RwLock::new(Some(NotificationSystem::new()))), } } } @@ -33,19 +27,6 @@ impl Handle { Self::default() } - pub fn init(&self) { - if self.is_exiting() { - return; - } - - let mut system_opt = self.notification_system.write(); - if let Some(system) = system_opt.as_mut() - && !system.is_running() - { - system.start(); - } - } - pub fn app_handle() -> &'static AppHandle { #[allow(clippy::expect_used)] APP_HANDLE.get().expect("App handle not initialized") @@ -56,27 +37,11 @@ impl Handle { } pub fn refresh_clash() { - let handle = Self::global(); - if handle.is_exiting() { - return; - } - - let system_opt = handle.notification_system.read(); - if let Some(system) = system_opt.as_ref() { - system.send_event(FrontendEvent::RefreshClash); - } + Self::send_event(FrontendEvent::RefreshClash); } pub fn refresh_verge() { - let handle = Self::global(); - if handle.is_exiting() { - return; - } - - let system_opt = handle.notification_system.read(); - if let Some(system) = system_opt.as_ref() { - system.send_event(FrontendEvent::RefreshVerge); - } + Self::send_event(FrontendEvent::RefreshVerge); } pub fn notify_profile_changed(profile_id: String) { @@ -99,17 +64,6 @@ impl Handle { // TODO 利用 &str 等缩短 Clone pub fn notice_message, M: Into>(status: S, msg: M) { - let handle = Self::global(); - - if handle.is_exiting() { - return; - } - - // We only send notice when main window exists - if WindowManager::get_main_window().is_none() { - return; - } - let status_str = status.into(); let msg_str = msg.into(); @@ -119,29 +73,21 @@ impl Handle { }); } + pub fn set_is_exiting(&self) { + self.is_exiting.store(true, Ordering::Release); + } + + pub fn is_exiting(&self) -> bool { + self.is_exiting.load(Ordering::Acquire) + } + fn send_event(event: FrontendEvent) { let handle = Self::global(); if handle.is_exiting() { return; } - let system_opt = handle.notification_system.read(); - if let Some(system) = system_opt.as_ref() { - system.send_event(event); - } - } - - pub fn set_is_exiting(&self) { - self.is_exiting.store(true, Ordering::Release); - - let mut system_opt = self.notification_system.write(); - if let Some(system) = system_opt.as_mut() { - system.shutdown(); - } - } - - pub fn is_exiting(&self) -> bool { - self.is_exiting.load(Ordering::Acquire) + NotificationSystem::send_event(event); } } diff --git a/src-tauri/src/core/notification.rs b/src-tauri/src/core/notification.rs index fe4c9d5e1..b231ba703 100644 --- a/src-tauri/src/core/notification.rs +++ b/src-tauri/src/core/notification.rs @@ -1,8 +1,8 @@ -use super::handle::Handle; -use crate::{constants::timing, utils::window_manager::WindowManager}; +use crate::utils::window_manager::WindowManager; use clash_verge_logging::{Type, logging}; +use serde_json::json; use smartstring::alias::String; -use std::{sync::mpsc, thread}; + use tauri::{Emitter as _, WebviewWindow}; // TODO 重构或优化,避免 Clone 过多 @@ -18,83 +18,11 @@ pub enum FrontendEvent { } #[derive(Debug)] -pub struct NotificationSystem { - sender: Option>, - #[allow(clippy::type_complexity)] - worker_handle: Option>, -} - -impl Default for NotificationSystem { - fn default() -> Self { - Self::new() - } -} +pub struct NotificationSystem {} impl NotificationSystem { - pub const fn new() -> Self { - Self { - sender: None, - worker_handle: None, - } - } - - pub const fn is_running(&self) -> bool { - self.sender.is_some() && self.worker_handle.is_some() - } - - pub fn start(&mut self) { - if self.is_running() { - return; - } - - let (tx, rx) = mpsc::channel(); - self.sender = Some(tx); - - //? Do we have to create a new thread for this? - let result = thread::Builder::new() - .name("frontend-notifier".into()) - .spawn(move || Self::worker_loop(rx)); - - match result { - Ok(handle) => self.worker_handle = Some(handle), - Err(e) => logging!(error, Type::System, "Failed to start notification worker: {}", e), - } - } - - fn worker_loop(rx: mpsc::Receiver) { - let handle = Handle::global(); - loop { - if handle.is_exiting() { - break; - } - match rx.recv() { - Ok(event) => Self::process_event(handle, event), - Err(e) => { - logging!(error, Type::System, "Notification System will exit, recv error: {}", e); - break; - } - } - } - } - - fn process_event(handle: &super::handle::Handle, event: FrontendEvent) { - let binding = handle.notification_system.read(); - let system = match binding.as_ref() { - Some(s) => s, - None => return, - }; - - if let Some(window) = WindowManager::get_main_window() { - system.emit_to_window(&window, event); - drop(binding); - thread::sleep(timing::EVENT_EMIT_DELAY); - } - } - - fn emit_to_window(&self, window: &WebviewWindow, event: FrontendEvent) { - let (event_name, payload) = self.serialize_event(event); - - let Ok(payload) = payload else { + fn emit_to_window(window: &WebviewWindow, event: FrontendEvent) { + let (event_name, Ok(payload)) = Self::serialize_event(event) else { return; }; @@ -103,9 +31,7 @@ impl NotificationSystem { } } - fn serialize_event(&self, event: FrontendEvent) -> (&'static str, Result) { - use serde_json::json; - + fn serialize_event(event: FrontendEvent) -> (&'static str, Result) { match event { FrontendEvent::RefreshClash => ("verge://refresh-clash-config", Ok(json!("yes"))), FrontendEvent::RefreshVerge => ("verge://refresh-verge-config", Ok(json!("yes"))), @@ -119,25 +45,9 @@ impl NotificationSystem { } } - pub fn send_event(&self, event: FrontendEvent) -> bool { - if !self.is_running() { - return false; - } - - if let Some(sender) = &self.sender { - sender.send(event).is_ok() - } else { - false - } - } - - pub fn shutdown(&mut self) { - if let Some(sender) = self.sender.take() { - drop(sender); - } - - if let Some(handle) = self.worker_handle.take() { - let _ = handle.join(); + pub(crate) fn send_event(event: FrontendEvent) { + if let Some(window) = WindowManager::get_main_window() { + Self::emit_to_window(&window, event); } } } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index bd3fa20c7..26cbc91d5 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -250,7 +250,6 @@ pub fn run() { logging!(error, Type::Setup, "Failed to setup window state: {}", e); } - resolve::resolve_setup_handle(); resolve::resolve_setup_async(); resolve::resolve_setup_sync(); resolve::init_signal(); @@ -282,7 +281,6 @@ pub fn run() { } logging!(info, Type::System, "应用就绪"); - handle::Handle::global().init(); #[cfg(target_os = "macos")] if let Some(window) = _app_handle.get_webview_window("main") { @@ -292,8 +290,6 @@ pub fn run() { #[cfg(target_os = "macos")] pub async fn handle_reopen(has_visible_windows: bool) { - handle::Handle::global().init(); - if lightweight::is_in_lightweight_mode() { lightweight::exit_lightweight_mode().await; return; diff --git a/src-tauri/src/utils/resolve/mod.rs b/src-tauri/src/utils/resolve/mod.rs index 3971cba3c..844d030f8 100644 --- a/src-tauri/src/utils/resolve/mod.rs +++ b/src-tauri/src/utils/resolve/mod.rs @@ -5,7 +5,7 @@ use anyhow::Result; use crate::{ config::Config, core::{ - CoreManager, Timer, handle, + CoreManager, Timer, hotkey::Hotkey, logger::Logger, service::{SERVICE_MANAGER, ServiceManager, is_service_ipc_path_exists}, @@ -39,10 +39,6 @@ pub fn init_work_dir_and_logger() -> anyhow::Result<()> { }) } -pub fn resolve_setup_handle() { - init_handle(); -} - pub fn resolve_setup_sync() { AsyncHandler::spawn(|| async { AsyncHandler::spawn_blocking(init_scheme); @@ -95,10 +91,6 @@ pub async fn resolve_reset_async() -> Result<(), anyhow::Error> { Ok(()) } -pub fn init_handle() { - handle::Handle::global().init(); -} - pub(super) fn init_scheme() { logging_error!(Type::Setup, init::init_scheme()); }