27bf74389d
Take 6 measured render 35-41ms — WORSE than take 5's 25.5 — and the run could not be attributed to a binary: exe mtime != build contents (incremental builds serve stale exes; a source edit without rebuild is a silent old binary). Three takes of a perf saga had been judged against builds nobody could prove. - ytLive.csproj GenerateBuildStamp target: fresh GUID per compile (writes obj/BuildStamp.g.cs -> Helpers/BuildStamp.Id/BuiltLocal). Deliberately defeats incremental lies: every 'dotnet build' recompiles the app project. - Wordmark shows the id as a superscript (TopBar.xaml, x:Static, 9px grey BaselineAlignment=Superscript); startup.log records 'Build <id> (compiled <time>)' so every take is cross-readable with the visible UI. - FramePump stats split the tick: 'avg render Xms (resolve Y), avg submit Z' — the resolver is timed separately (wrapper resolver on per-tick paths; bake keeps the raw one) so take 7 names the hot half of 'render' with data. - Fixed a latent transition-clock bug found on the way: lastTick now restarts every frame (the branch rework had restarted it only during transitions, letting a transition begun after idle complete instantly on its first Tick). ONE integration test family: BuildStampTests (unit: shape) + BuildStampDisplayTests (RealApp, namescoped FindName on TopBar proves the wordmark SHOWS the id). 47/47 per-class green, clean build 0 warnings. Docs same commit. User's top-bar/session spec (re-sent twice) + settled Q&A decisions folded into HANDOFF Unit B — next work unit after take 7 verdict.
51 lines
1.6 KiB
C#
51 lines
1.6 KiB
C#
using System.Windows;
|
|
using System.Windows.Threading;
|
|
using Velopack;
|
|
using ytLive.Helpers;
|
|
|
|
namespace ytLive;
|
|
|
|
/// <summary>
|
|
/// Interaction logic for App.xaml
|
|
/// </summary>
|
|
public partial class App : Application
|
|
{
|
|
public App()
|
|
{
|
|
AppLog.Write("App ctor");
|
|
}
|
|
|
|
protected override void OnStartup(StartupEventArgs e)
|
|
{
|
|
AppDomain.CurrentDomain.UnhandledException += (_, args) =>
|
|
AppLog.Write(args.ExceptionObject is Exception ex
|
|
? "AppDomain unhandled exception: " + ex
|
|
: "AppDomain unhandled exception object: " + args.ExceptionObject);
|
|
|
|
DispatcherUnhandledException += (_, args) =>
|
|
AppLog.Write(args.Exception, "Dispatcher unhandled exception");
|
|
|
|
AppLog.Write("App OnStartup begin");
|
|
// Attribution (2026-09-04): every take must be traceable to the exact binary
|
|
// that produced it — the wordmark superscript shows this same id.
|
|
AppLog.Write($"Build {ytLive.Helpers.BuildStamp.Id} (compiled {ytLive.Helpers.BuildStamp.BuiltLocal})");
|
|
|
|
// Velopack auto-update bootstrap — checks for updates on startup and
|
|
// applies them (the app restarts automatically if an update is found).
|
|
// Update URL is configured per-deployment (self-hosted on DO droplet);
|
|
// when no URL is set, the check is a no-op.
|
|
try
|
|
{
|
|
VelopackApp.Build()
|
|
.Run();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AppLog.Write($"Velopack bootstrap failed (non-fatal): {ex.Message}");
|
|
}
|
|
|
|
base.OnStartup(e);
|
|
AppLog.Write("App OnStartup end");
|
|
}
|
|
}
|