feat(launch): M157 实例级启动参数(五项回落 + graphicsBackend 三态)
core: 新增 game/launch_overrides(LaunchOverrides 五项 All-Option + 三级回落 + 文本补丁校验)与 launch/overrides(拼装落位:全局 java.extra_args 进 user.jvm、实例 jvmArgs 进 override_jvm、gameArgs 进 user.game、memory 进 -Xmx、backend 进 --graphicsBackend 并复用既有版本门槛告警);实例 schema 登记 launch.* 五键。 presenter: dto/LaunchArgsView+LaunchArgsPatch,主机侧读/写与门槛判定(backend_allowed),AppCommand::SetInstanceLaunchArgs。 cli: 新命令 instances launch-args(读/写/--clear),launch 装配链消费回落值。 app-iced: 实例详情页「启动参数」区(JVM/游戏参数、内存、Java、三态后端 chips + 灰化提示 + 保存/恢复),表单状态归 App、i18n 中英文案同步。
This commit is contained in:
1 parent
d68523b02a
commit
e2021645d7
56 files changed
+3776
-607
No files matched your search
@@ -4,9 +4,11 @@
|
||||
//! 两份数据源喂同一个渲染函数,这是 [`crate::pages::model`] 存在的理由。
|
||||
|
||||
use unlucky_i18n::{Catalog, Key, Lang};
|
||||
use unlucky_presenter::dto::LaunchArgsView;
|
||||
|
||||
use super::super::model::{Detail, Instances, Meta, Row};
|
||||
use super::super::model::{Detail, Instances, LaunchFacts, Meta, Row};
|
||||
use super::data::{DEMO, NOTE, SELECTED};
|
||||
use super::state::LaunchForm;
|
||||
|
||||
/// 演示路径的目录:**恒英文**。
|
||||
///
|
||||
@@ -51,6 +53,7 @@ pub(crate) fn demo() -> Instances {
|
||||
status: None,
|
||||
can_launch: true,
|
||||
can_stop: false,
|
||||
launch: launch_facts(),
|
||||
};
|
||||
|
||||
Instances {
|
||||
@@ -65,3 +68,60 @@ fn meta(label: &str, value: &str) -> Meta {
|
||||
value: value.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 启动参数区的演示事实(M157 的 D30 出图夹具)。
|
||||
///
|
||||
/// `ULL_LAUNCH_ARGS_FIXTURE=gated` 出「版本不够、三态灰化」那一屏;缺省(`open`)是
|
||||
/// 「26.2 实例 + Vulkan 可选」的正常态。**这是出图夹具,不是产品逻辑**:产品路径的门槛
|
||||
/// 来自 presenter 快照(core 的 `graphics_backend_allowed`),与这个环境变量无关。
|
||||
pub(crate) fn launch_facts() -> LaunchFacts {
|
||||
let gated = gated_fixture();
|
||||
LaunchFacts {
|
||||
allowed: !gated,
|
||||
mc_version: if gated { "1.20.4" } else { "26.2-snapshot-2" }.to_string(),
|
||||
min_version: "26.2-snapshot-2".to_string(),
|
||||
memory_effective_mb: if gated { 2048 } else { 4096 },
|
||||
java_effective: "C:/Java/temurin-21/bin/java.exe".to_string(),
|
||||
backend_effective: if gated { "default" } else { "vulkan" }.to_string(),
|
||||
options: ["default", "opengl", "vulkan"]
|
||||
.iter()
|
||||
.map(|id| (*id).to_string())
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 演示用的表单初值(页面状态的所有者是 `App`;harness 没有 `App`,自己持有一份)。
|
||||
///
|
||||
/// 返回**拥有**的表单而不是 `&'static`:`text_editor::Content` 内含 `RefCell`,不满足
|
||||
/// `Sync`,做不成 `static`;harness/测试各自持有即可(一帧借用一次)。
|
||||
pub(crate) fn demo_form() -> LaunchForm {
|
||||
LaunchForm::from_view(Some(DEMO[SELECTED].name), &demo_view())
|
||||
}
|
||||
|
||||
fn demo_view() -> LaunchArgsView {
|
||||
let gated = gated_fixture();
|
||||
LaunchArgsView {
|
||||
instance_id: DEMO[SELECTED].name.to_string(),
|
||||
jvm_args: "-XX:+UseG1GC".to_string(),
|
||||
game_args: String::new(),
|
||||
memory_mb: (!gated).then_some(4096),
|
||||
memory_effective_mb: if gated { 2048 } else { 4096 },
|
||||
java_path: String::new(),
|
||||
java_effective: "C:/Java/temurin-21/bin/java.exe".to_string(),
|
||||
graphics_backend: if gated { "default" } else { "vulkan" }.to_string(),
|
||||
graphics_backend_effective: if gated { "default" } else { "vulkan" }.to_string(),
|
||||
graphics_backend_allowed: !gated,
|
||||
mc_version: if gated { "1.20.4" } else { "26.2-snapshot-2" }.to_string(),
|
||||
graphics_backend_min_version: "26.2-snapshot-2".to_string(),
|
||||
graphics_backend_options: ["default", "opengl", "vulkan"]
|
||||
.iter()
|
||||
.map(|id| (*id).to_string())
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn gated_fixture() -> bool {
|
||||
std::env::var("ULL_LAUNCH_ARGS_FIXTURE")
|
||||
.map(|value| value.trim().eq_ignore_ascii_case("gated"))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
Reference in new issue
Block a user