Files
Unlucky-Launcher/crates/app/src/main.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

95 lines
4.1 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.
//! Unlucky-Launcher 桌面壳(`unlucky_app`):Slint UI + Metro 视觉。
//!
//! 边界(决策 D3 / D16):本 crate 是**唯一**允许依赖 UI 框架的 crate;
//! 它只经「快照 + 事件流 + 注入的显示服务」消费 core/agent,不直接触碰其内部类型
//! (P0 的 host 是 `mock` 假后端,`crate::dto` 是唯一跨界类型集合)。
//!
//! 渲染策略(`DevDocs/PlanDoc/01c-native-gui-options.md` §6):
//! GL 优先(femtovg),启动参数 `--software-renderer` 或 Win7 老机探测失败时切 CPU 软渲染。
//!
//! 主题与外观(D17 / 09 §101-113):
//! - 主题三态 `appearance.theme_mode ∈ {auto, light, dark}`(出厂 auto);
//! - 「外观(高级)」四件(背景图 / 面板半透明度 / 玻璃拟态 / 强调色)出厂全关;
//! - 全部走 `core::setting` 的 schema(`crate::settings_bridge`),AI 可写并且**热切**
//! (tick 里 1s 一次 mtime 比对);系统主题由 `core::platform::theme_probe` 对齐 + 兜底轮询。
//!
//! 架构分层(本文件只有一个职责:把窗口拉起来):
//! - `state.rs` / `prefs.rs` / `router.rs` / `dialogs.rs` / `toast.rs`:纯 Rust 状态(可单测,无 Slint)
//! - `dto/`:跨边界 DTO 与事件/指令
//! - `conv.rs`:状态 → Slint 视图模型
//! - `ui_bind.rs` + `callbacks.rs`:窗口/状态/后端缝合 + 回调接线
//! - `settings_bridge.rs`:`config/launcher.json` 的读写与热切(core::setting 的 schema API)
//! - `bg_image.rs` + `png.rs`:背景图/模糊层加工与截图编码(09 §101/§103 的预生成手法)
//! - `mock.rs` + `mock_data.rs`:P0 假后端(脚本化事件)
//!
//! 关于 unsafe:本 crate 不写 unsafe,workspace lint 已设 `unsafe_code = "deny"`。
//! 这里不能升级成 `#![forbid(unsafe_code)]`——Slint 生成的代码自带 `#[allow(unsafe_code)]`,
//! 而 forbid 无法被内层 allow 覆盖(会直接编译失败)。同理 Slint 生成类型不带文档注释,
//! 只能在 crate 级放开 `missing_docs`(库 crate 仍由 workspace lint 保持 warn)。
// 关于 dead_code:P0 骨架里有一批「已定义、等接线」的公共 API——事件通道 / 偏好键登记 /
// 诊断文案 / mock 数据构造器等,它们被单测覆盖但业务侧要 P1 才用到。逐条 `#[allow]`
// 会把噪音藏进实现细节,这里统一放开并在 P1 接线时逐个转正(届时删掉本行即可暴露真死码)。
#![allow(missing_docs, dead_code)]
mod appearance_bind;
mod bg_image;
mod callbacks;
mod conv;
mod dialogs;
mod dto;
mod mock;
mod mock_data;
mod png;
mod prefs;
mod router;
mod settings_bridge;
mod state;
mod theme_runtime;
mod toast;
mod ui_bind;
slint::include_modules!();
fn main() -> Result<(), slint::PlatformError> {
apply_renderer_flag();
let app = ui_bind::AppUi::new(MainWindow::new()?);
// 截图验收通道(M41 视觉验收;无交互桌面/无 GPU 环境下的唯一可靠取图方式:
// 不截屏幕,而是让 Slint 把当前场景渲染进内存像素缓冲再自己编码 PNG)。
if let Some(path) = screenshot_path() {
if std::env::args().any(|arg| arg == "--screenshot-settings") {
app.open_settings_appearance();
}
app.render_screenshot(&path)?;
return Ok(());
}
app.start_timer();
app.run()
}
/// Win7 老机 / 无可用 OpenGL 驱动时的软渲染兜底开关(01c §6 的 Slint 核心卖点)。
fn apply_renderer_flag() {
let software = std::env::args()
.skip(1)
.any(|arg| arg == "--software-renderer");
if software {
std::env::set_var("SLINT_BACKEND", "winit-software");
}
}
/// `--screenshot <path>` / `--screenshot=<path>`:渲染一帧并写 PNG 后退出。
fn screenshot_path() -> Option<String> {
let mut args = std::env::args().skip(1);
while let Some(arg) = args.next() {
if let Some(value) = arg.strip_prefix("--screenshot=") {
return Some(value.to_owned());
}
if arg == "--screenshot" {
return args.next();
}
}
None
}