sim/runtime/reference_device/
two_rate.rs1use sim_kernel::{Expr, Result, Symbol};
2use sim_lib_stream_device::seq_is_monotone;
3use sim_lib_view_device::{
4 AdapterInput, AdapterLoop, FrameClock, GlanceAdapter, GlanceBudget, GlanceInput, GlanceState,
5 StalePolicy,
6};
7use sim_value::build;
8
9use super::{
10 ReferencePose, ReferenceRichAdapter, ReferenceSceneEncoder, reference_caps_source,
11 reference_glance_profile, reference_rich_profile,
12};
13
14#[derive(Clone, Debug, PartialEq, Eq)]
16pub struct TwoRateProof {
17 pub encoder_calls: u64,
19 pub rich_dropped: u32,
21 pub rich_stale: bool,
23 pub glance_cells: u8,
25 pub glance_ack: Symbol,
27 pub modeled_stream_monotone: bool,
29}
30
31impl TwoRateProof {
32 pub fn to_expr(&self) -> Expr {
34 build::map(vec![
35 ("kind", build::qsym("device/reference", "two-rate-proof")),
36 ("encoder-calls", build::uint(self.encoder_calls)),
37 ("rich-dropped", build::uint(u64::from(self.rich_dropped))),
38 ("rich-stale", Expr::Bool(self.rich_stale)),
39 ("glance-cells", build::uint(u64::from(self.glance_cells))),
40 ("glance-ack", Expr::Symbol(self.glance_ack.clone())),
41 (
42 "modeled-stream-monotone",
43 Expr::Bool(self.modeled_stream_monotone),
44 ),
45 ])
46 }
47}
48
49pub fn prove_two_rate() -> Result<TwoRateProof> {
51 let rich_profile = reference_rich_profile();
52 let glance_profile = reference_glance_profile();
53 let mut encoder = ReferenceSceneEncoder::new();
54 let encoded = encoder.encode();
55 let shared_scene = encoded.shared();
56
57 let mut rich_loop = AdapterLoop::new(ReferenceRichAdapter, StalePolicy::Predict);
58 rich_loop.offer(&ReferencePose::new(1, 100));
59 rich_loop.offer(&ReferencePose::new(2, 250));
60 rich_loop.offer(&ReferencePose::new(3, 500));
61 let rich_input = AdapterInput::new(encoded.clone(), 1, ReferencePose::new(3, 500), 3);
62 let fresh = rich_loop.step(
63 &FrameClock::new(3, rich_profile.rate),
64 &rich_input,
65 &rich_profile,
66 )?;
67
68 let stale_input =
69 AdapterInput::from_shared_scene(shared_scene, 1, ReferencePose::new(3, 500), 3);
70 let stale = rich_loop.step(
71 &FrameClock::new(200, rich_profile.rate),
72 &stale_input,
73 &rich_profile,
74 )?;
75
76 let budget = GlanceBudget::mono_hud();
77 let glance_adapter = GlanceAdapter::new(budget, 25);
78 let mut glance_loop = AdapterLoop::new(glance_adapter, StalePolicy::HoldLast);
79 glance_loop.offer(&GlanceState::with_input(GlanceInput::Tap, 4));
80 let glance_input =
81 AdapterInput::new(encoded, 1, GlanceState::with_input(GlanceInput::Tap, 4), 4);
82 let _glance = glance_loop.step(
83 &FrameClock::new(4, glance_profile.rate),
84 &glance_input,
85 &glance_profile,
86 )?;
87
88 Ok(TwoRateProof {
89 encoder_calls: encoder.calls(),
90 rich_dropped: fresh.dropped,
91 rich_stale: stale.stale,
92 glance_cells: budget.cells,
93 glance_ack: budget.ack.to_symbol(),
94 modeled_stream_monotone: seq_is_monotone(&reference_caps_source(), 0, 4),
95 })
96}