Gate readiness on stable viewport frames
Some checks failed
CI / rust-skia (Rust only) (push) Has been cancelled
CI / required (push) Has been cancelled

This commit is contained in:
2026-08-23 13:48:06 +02:00
parent 33d1cf6827
commit 42f0c62b6b
2 changed files with 43 additions and 34 deletions

View File

@@ -343,6 +343,7 @@ async fn run_live(
{
live.vision.set_generation(status.generation);
record_session_observation(&live.observability, &event);
print_ready(&live, status.generation);
return Ok::<(), CliError>(());
}
Some(
@@ -529,32 +530,7 @@ async fn run_live(
status.agent_ready,
);
if status.agent_ready {
let world = live
.world_loop
.as_ref()
.and_then(metacrate_game_loop::LoopHandle::latest_world);
let world_sequence = world.as_ref().map_or(0, |world| world.sequence);
let primitives = world
.as_ref()
.map_or(0, |world| world.value.primitives.len());
let avatars = world.as_ref().map_or(0, |world| world.value.avatars.len());
let dropped_world_events = live
.world_loop
.as_ref()
.map_or(0, metacrate_game_loop::LoopHandle::dropped_world_events);
let frames = live
.vision
.viewport_stats()
.map_or(0, |stats| stats.completed_frames);
println!(
"READY generation={} world_sequence={} world_primitives={} world_avatars={} dropped_world_events={} viewport_frames={} viewport_target_fps=10",
status.generation,
world_sequence,
primitives,
avatars,
dropped_world_events,
frames
);
print_ready(&live, status.generation);
}
}
}
@@ -689,13 +665,20 @@ async fn prepare_live_framework(
generation,
libremetaverse_types::compat::CancellationToken::default(),
);
let mut stable_after_frame = 0;
let mut observed_missed_deadlines = 0;
loop {
if live
.vision
.viewport_stats()
.is_some_and(|stats| stats.completed_frames >= 2 && stats.render_errors == 0)
{
return;
if let Some(stats) = live.vision.viewport_stats() {
if stats.missed_frame_deadlines != observed_missed_deadlines {
observed_missed_deadlines = stats.missed_frame_deadlines;
stable_after_frame = stats.completed_frames;
}
if stats.completed_frames.saturating_sub(stable_after_frame) >= 2
&& stats.render_errors == 0
&& stats.last_render <= metacrate_game_loop::DEFAULT_VIEWPORT_FRAME_INTERVAL
{
return;
}
}
tokio::time::sleep(Duration::from_millis(20)).await;
}
@@ -705,7 +688,7 @@ async fn prepare_live_framework(
readiness.mark_ready(generation);
let stats = live.vision.viewport_stats().unwrap_or_default();
println!(
"INITIALIZED generation={} viewport_frames={} last_render_ms={} missed_deadlines={} world_state=stable",
"INITIALIZED generation={} viewport_frames={} last_render_ms={} warmup_missed_deadlines={} world_state=stable viewport_state=stable",
generation,
stats.completed_frames,
stats.last_render.as_millis(),
@@ -714,6 +697,30 @@ async fn prepare_live_framework(
Ok(())
}
#[cfg(feature = "live-grid")]
fn print_ready(live: &LiveInteractions, generation: u64) {
let world = live
.world_loop
.as_ref()
.and_then(metacrate_game_loop::LoopHandle::latest_world);
let world_sequence = world.as_ref().map_or(0, |world| world.sequence);
let primitives = world
.as_ref()
.map_or(0, |world| world.value.primitives.len());
let avatars = world.as_ref().map_or(0, |world| world.value.avatars.len());
let dropped_world_events = live
.world_loop
.as_ref()
.map_or(0, metacrate_game_loop::LoopHandle::dropped_world_events);
let frames = live
.vision
.viewport_stats()
.map_or(0, |stats| stats.completed_frames);
println!(
"READY generation={generation} world_sequence={world_sequence} world_primitives={primitives} world_avatars={avatars} dropped_world_events={dropped_world_events} viewport_frames={frames} viewport_target_fps=10"
);
}
#[cfg(feature = "live-grid")]
struct LiveInteractions {
interaction: metacrate_grid_agent::InteractionHandle,