Files
Unlucky-Launcher/crates/core/src/launch/session_sink.rs
T
AskaEth bc41dfcf7d
CI / fmt (rustfmt --check) (push) Canceled after 0s
CI / clippy (ubuntu-latest) (push) Canceled after 0s
CI / clippy (windows-latest) (push) Canceled after 0s
CI / test (ubuntu-latest) (push) Canceled after 0s
CI / test (windows-latest) (push) Canceled after 0s
CI / build release (ubuntu-latest) (push) Canceled after 0s
CI / build release (windows-latest) (push) Canceled after 0s
Guards / core 零 UI 守门 (push) Canceled after 0s
Guards / 文件行数 ≤400 守门 (push) Canceled after 0s
Guards / 依赖许可与来源(cargo-deny) (push) Canceled after 0s
Unlucky Launcher v0.0.1-alpha
Rust 原生单文件 Minecraft 启动器:CLI 完整可用(install/launch/accounts/java/diagnose/agent),
MCP server 接入外部 Agent 工具,GUI 开发中。
2026-10-31 21:54:10 +08:00

65 lines
2.0 KiB
Rust

//! 把会话事件流接到日志泵上:逐行落盘 + 自动窗口出现检测。
//!
//! 放在单独文件是为了让 [`crate::launch::session`] 保持“只写事件、只管索引”的单一职责,
//! 也避免单文件超过 400 行的硬约束。
use std::sync::Mutex;
use crate::launch::pump::{LineSink, LogLine};
use crate::launch::session::SessionWriter;
use crate::launch::window_detect::WindowDetector;
/// 会话日志 sink。
#[derive(Debug)]
pub struct SessionSink {
writer: Mutex<SessionWriter>,
detector: Mutex<WindowDetector>,
}
impl SessionSink {
/// 以进程启动时刻为窗口检测起点。
pub fn new(writer: SessionWriter) -> Self {
Self {
writer: Mutex::new(writer),
detector: Mutex::new(WindowDetector::new()),
}
}
/// 指定窗口检测计时起点(进程 spawn 时刻)。
pub fn with_start(writer: SessionWriter, started_at: std::time::Instant) -> Self {
Self {
writer: Mutex::new(writer),
detector: Mutex::new(WindowDetector::with_start(started_at)),
}
}
/// 借用写入器(退出分析、结束会话等需要可变访问的场合)。
pub fn with_writer<R>(&self, action: impl FnOnce(&mut SessionWriter) -> R) -> Option<R> {
self.writer.lock().ok().map(|mut guard| action(&mut guard))
}
/// 是否已检测到游戏窗口。
pub fn window_detected(&self) -> bool {
match self.writer.lock() {
Ok(writer) => writer.is_window_detected(),
Err(_) => false,
}
}
}
impl LineSink for SessionSink {
fn on_line(&self, line: &LogLine) {
let detection = match self.detector.lock() {
Ok(mut detector) => detector.observe(&line.text),
Err(_) => None,
};
let Ok(mut writer) = self.writer.lock() else {
return;
};
if let Some(detection) = detection {
let _ = writer.window_detected(&detection);
}
let _ = writer.line(line);
}
}