sim_lib_view_device/
glance_adapter.rs1use std::rc::Rc;
4
5use sim_kernel::{Error, Expr, Result};
6use sim_value::build;
7
8use crate::{
9 DeviceProfile, EncodedScene, GlanceBudget, GlanceInput, GlanceState, LocalAdapter,
10 fit_to_budget,
11};
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq)]
26pub struct GlanceAdapter {
27 pub budget: GlanceBudget,
29 pub ack_ms: u64,
31}
32
33impl GlanceAdapter {
34 pub fn new(budget: GlanceBudget, ack_ms: u64) -> Self {
36 Self { budget, ack_ms }
37 }
38}
39
40impl LocalAdapter for GlanceAdapter {
41 type State = GlanceState;
42
43 fn adapt(
44 &self,
45 scene: &EncodedScene,
46 state: &Self::State,
47 _profile: &DeviceProfile,
48 ) -> Result<Rc<Expr>> {
49 if !crate::glance::is_glance(scene.expr()) {
50 return Err(Error::HostError(
51 "GlanceAdapter expects an encoded scene/glance card".to_owned(),
52 ));
53 }
54 let card = fit_to_budget(scene.expr(), &self.budget)?;
55 Ok(Rc::new(match state.pending_input {
56 Some(input) => with_ack(card, input, state.tick, self.budget, self.ack_ms),
57 None => card,
58 }))
59 }
60}
61
62fn with_ack(card: Expr, input: GlanceInput, tick: u64, budget: GlanceBudget, ack_ms: u64) -> Expr {
63 sim_value::access::set(
64 &sim_value::access::set(
65 &sim_value::access::set(
66 &sim_value::access::set(&card, "ack-channel", Expr::Symbol(budget.ack.to_symbol())),
67 "ack-input",
68 build::sym(input.token()),
69 ),
70 "ack-ms",
71 build::uint(ack_ms),
72 ),
73 "ack-tick",
74 build::uint(tick),
75 )
76}