mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-03 18:45:55 +00:00
Profiler: the Profile operations preference switches recording at run time
- Graphics page: "Profile operations" (off by default) starts and stops the profiler when it changes; an agent's diagnostics.profile in between stands, and SOLIDCRAFT_PROFILE=1 is not undone by the default at start-up. - The desktop app reads SOLIDCRAFT_PROFILE at start-up. - Labels in en, ar, de, he, ja, ko, zh. The pending-messages test compares right-to-left pending text in display order, as the catalogs give it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -679,6 +679,8 @@ fn main() -> eframe::Result {
|
||||
#[cfg(target_os = "macos")]
|
||||
objc2_foundation::NSProcessInfo::processInfo().setProcessName(objc2_foundation::ns_string!("SolidCraft"));
|
||||
mark("main");
|
||||
// SOLIDCRAFT_PROFILE=1: the profiler records from the start (diagnostics.profile reads it).
|
||||
solidcraft_engine::timing::profile_from_env();
|
||||
// Validate before legacy adoption, crash markers or any user preference read.
|
||||
let settings = settings_dir().map_err(|error| eframe::Error::AppCreation(error.into()))?;
|
||||
if std::env::var_os("SOLIDCRAFT_SETTINGS_DIR").is_none() {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"en": {
|
||||
"cmd.diagnostics_profile": "Profile",
|
||||
"prefs.profile_operations": "Profile operations",
|
||||
"prefs.profile_operations_note": "Records how long SMLib calls, kernel operations, features, commands and imports take. Agents read it with diagnostics.profile."
|
||||
},
|
||||
"ar": {
|
||||
"cmd.diagnostics_profile": "التحليل الزمني",
|
||||
"prefs.profile_operations": "تحليل زمن العمليات",
|
||||
"prefs.profile_operations_note": "يسجّل المدة التي تستغرقها استدعاءات SMLib وعمليات النواة والميزات والأوامر وعمليات الاستيراد. يقرؤه الوكلاء عبر diagnostics.profile."
|
||||
},
|
||||
"de": {
|
||||
"cmd.diagnostics_profile": "Profil",
|
||||
"prefs.profile_operations": "Vorgänge profilieren",
|
||||
"prefs.profile_operations_note": "Zeichnet auf, wie lange SMLib-Aufrufe, Kernel-Vorgänge, Features, Befehle und Importe dauern. Agenten lesen es mit diagnostics.profile."
|
||||
},
|
||||
"he": {
|
||||
"cmd.diagnostics_profile": "פרופיל ביצועים",
|
||||
"prefs.profile_operations": "מדידת זמני פעולות",
|
||||
"prefs.profile_operations_note": "מתעד כמה זמן לוקחות קריאות SMLib, פעולות ליבה, תכונות, פקודות וייבוא. סוכנים קוראים זאת עם diagnostics.profile."
|
||||
},
|
||||
"ja": {
|
||||
"cmd.diagnostics_profile": "プロファイル",
|
||||
"prefs.profile_operations": "処理をプロファイル",
|
||||
"prefs.profile_operations_note": "SMLib の呼び出し、カーネル処理、フィーチャー、コマンド、インポートにかかる時間を記録します。エージェントは diagnostics.profile で読み取ります。"
|
||||
},
|
||||
"ko": {
|
||||
"cmd.diagnostics_profile": "프로파일",
|
||||
"prefs.profile_operations": "작업 프로파일링",
|
||||
"prefs.profile_operations_note": "SMLib 호출, 커널 작업, 피처, 명령, 가져오기에 걸리는 시간을 기록합니다. 에이전트는 diagnostics.profile로 읽습니다."
|
||||
},
|
||||
"zh": {
|
||||
"cmd.diagnostics_profile": "性能分析",
|
||||
"prefs.profile_operations": "分析操作耗时",
|
||||
"prefs.profile_operations_note": "记录 SMLib 调用、内核操作、特征、命令和导入所用的时间。智能体通过 diagnostics.profile 读取。"
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ nix = { workspace = true }
|
||||
winreg = "0.56"
|
||||
|
||||
[dev-dependencies]
|
||||
solidcraft-engine = { workspace = true, features = ["bundled-render-library"] }
|
||||
solidcraft-engine = { workspace = true, features = ["bundled-render-library", "profile"] }
|
||||
# Parse the source guard structurally, including code after inline test modules.
|
||||
syn = { workspace = true, features = ["visit"] }
|
||||
# The catalog guard reads every UI source file as Rust tokens; already in the tree through
|
||||
|
||||
@@ -602,6 +602,9 @@ preference_settings! {
|
||||
supersampling_adaptive: bool = true, PAGE_GRAPHICS => check_tr("ui.supersampling_adaptive");
|
||||
/// Show the frame rate in the view's corner (the view then redraws every frame).
|
||||
show_frame_rate: bool = false, PAGE_GRAPHICS => check_id("ui.frame_rate");
|
||||
/// Record where the time goes (SMLib's calls, kernel operations, features, commands, imports)
|
||||
/// for `diagnostics.profile` (docs/perf.md). Off by default: nothing is recorded.
|
||||
profile_operations: bool = false, PAGE_GRAPHICS => check_tr("prefs.profile_operations");
|
||||
/// With the frame rate: a frame-time graph, a histogram and what the GPU drew (#2548).
|
||||
frame_rate_details: bool = false, PAGE_GRAPHICS;
|
||||
/// Draw a wider rim under finished sketch curves to improve contrast on shaded faces.
|
||||
@@ -830,6 +833,9 @@ pub struct PrefsWindow {
|
||||
snapshot: Option<Snapshot>,
|
||||
/// The up axis preference the view follows now (applied when it changes, and at startup).
|
||||
applied_up: Option<String>,
|
||||
/// The Profile operations preference the profiler last followed: applied when it changes,
|
||||
/// so `diagnostics.profile` (an agent) and SOLIDCRAFT_PROFILE can switch it in between.
|
||||
applied_profile: Option<bool>,
|
||||
/// The search text of the interface font list.
|
||||
font_filter: String,
|
||||
/// Search text on the Plugins page.
|
||||
@@ -1096,6 +1102,15 @@ fn defaults(app: &mut SolveApp, page: usize) {
|
||||
/// the interface scale.
|
||||
pub fn apply(app: &mut SolveApp, ctx: &egui::Context) {
|
||||
apply_network(&app.preferences);
|
||||
// The profiler records while the preference is on (switched when it changes; at start-up only
|
||||
// when on, so SOLIDCRAFT_PROFILE=1 is not undone by the default).
|
||||
let profile = app.preferences.profile_operations;
|
||||
if app.prefs_window.applied_profile != Some(profile) {
|
||||
if profile || app.prefs_window.applied_profile.is_some() {
|
||||
solidcraft_engine::profile::set_enabled(profile);
|
||||
}
|
||||
app.prefs_window.applied_profile = Some(profile);
|
||||
}
|
||||
// The viewport's display quality (an unknown saved value draws at Normal).
|
||||
solidcraft_engine::doc::display_quality::set_current(
|
||||
solidcraft_engine::doc::display_quality::DisplayQuality::parse(&app.preferences.display_quality).unwrap_or_default(),
|
||||
@@ -2389,6 +2404,24 @@ pub(crate) fn reveal_preference(h: &mut crate::scenario::Harness, handle: &str)
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
/// Profile operations switches the profiler when it changes, and only then: an agent's
|
||||
/// diagnostics.profile in between is not undone next frame.
|
||||
#[test]
|
||||
fn the_profile_preference_switches_the_profiler_when_it_changes() {
|
||||
use serde_json::json;
|
||||
let mut h = crate::scenario::Harness::new();
|
||||
h.frames(1);
|
||||
h.call("ui.prefs", json!({"profile_operations": true}));
|
||||
h.frames(2);
|
||||
assert!(solidcraft_engine::profile::enabled());
|
||||
h.app.session.execute("diagnostics.profile", &json!({"enabled": false})).unwrap();
|
||||
h.frames(2);
|
||||
assert!(!solidcraft_engine::profile::enabled(), "the command's choice stands");
|
||||
h.call("ui.prefs", json!({"profile_operations": false}));
|
||||
h.frames(2);
|
||||
assert!(!solidcraft_engine::profile::enabled());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_ghost_position_defaults_round_trips_and_reads_tolerantly() {
|
||||
use super::SpaceMouseGhost::{LeftViewport as Current, LeftWindow as Left, RightViewport as Right};
|
||||
|
||||
@@ -163,6 +163,7 @@ pub(super) fn show(app: &mut SolveApp, ui: &mut egui::Ui) {
|
||||
ui_kit::checkbox(ui, app.tr("ui.frame_rate_details"), &mut app.preferences.frame_rate_details)
|
||||
.on_hover_text(app.tr("settings.frame_rate_details_note"));
|
||||
});
|
||||
setting::profile_operations(app, left).on_hover_text(app.tr("prefs.profile_operations_note"));
|
||||
setting::reference_geometry_through_bodies(app, left).on_hover_text(app.tr("settings.reference_geometry_through_bodies_help"));
|
||||
setting::sketch_halo(app, left);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user