pub struct Frame { /* private fields */ }Expand description
One frame callback.
Implementations§
Source§impl Frame
impl Frame
Sourcepub fn new(now_ms: u64, interval_ms: u32, power: Power) -> Self
pub fn new(now_ms: u64, interval_ms: u32, power: Power) -> Self
A frame at now_ms (for tests; the runtime makes the real ones).
Sourcepub fn elapsed(&self) -> u64
pub fn elapsed(&self) -> u64
Milliseconds since the previous frame; zero on the first frame, and on the first frame after the plugin’s surfaces were all hidden (a hidden period is not play time).
Sourcepub fn now_ms(&self) -> u64
pub fn now_ms(&self) -> u64
The viewer’s monotonic clock, in milliseconds.
Examples found in repository?
examples/clock_card.rs (line 33)
32 fn frame(&mut self, frame: &Frame) {
33 let second = frame.now_ms() / 1000;
34 if self.shown != Some(second) {
35 self.shown = Some(second);
36 let (cols, _) = self.card.size();
37 let time = format!(
38 "{:02}:{:02}:{:02}",
39 second / 3600 % 24,
40 second / 60 % 60,
41 second % 60
42 );
43 self.card.text(0, 0, &time, Style::fg(Colour::FG).bold());
44 let fraction = (second % 60) as f32 / 60.0;
45 let track = Style::fg(Colour::RECEDE_FG);
46 self.card.bar(
47 Area::new(0, 1, cols, 1),
48 fraction,
49 Style::fg(Colour::ACCENT),
50 track,
51 );
52 // Publishes only the cells that changed.
53 let _ = self.card.commit();
54 }
55 // The next second boundary: an idle viewer wakes once a second.
56 frame.wake_at((second + 1) * 1000);
57 }More examples
examples/shapes_stage.rs (line 36)
24 fn frame(&mut self, frame: &Frame) {
25 let (w, h) = self.stage.size();
26 if w == 0 || h == 0 {
27 // No pixel geometry yet: a resize will follow.
28 return;
29 }
30 let theme = view::theme();
31 let (fg, bg, accent) = (
32 Rgba::hex(theme.fg),
33 Rgba::hex(theme.bg),
34 Rgba::hex(theme.accent),
35 );
36 let t = (frame.now_ms() % 4000) as f32 / 4000.0;
37
38 // A full repaint: nothing is carried forward from the last frame.
39 self.stage.clear(bg);
40 let panel = Area::new(8, 8, w.saturating_sub(16), h.saturating_sub(16));
41 self.stage
42 .fill_rounded_rect(panel, 12, Rgba::hex(theme.recede_bg));
43 self.stage
44 .rounded_rect(panel, 12, Rgba::hex(theme.recede_fg));
45
46 let (cx, cy) = (w as f32 / 2.0, h as f32 / 2.0);
47 let radius = (w.min(h) / 4) as f32;
48 let angle = t * core::f32::consts::TAU;
49 // `no_std` has no `f32::sin`: the SDK re-exports `libm`. The dot
50 // moves between pixels; the shapes antialias it there.
51 let dot = (
52 cx + radius * libm::cosf(angle),
53 cy + radius * libm::sinf(angle),
54 );
55 self.stage
56 .circle((cx, cy), radius, Rgba::hex(theme.recede_fg));
57 self.stage
58 .line((cx as i32, cy as i32), (dot.0 as i32, dot.1 as i32), accent);
59 self.stage.fill_circle(dot, 6.0, accent);
60
61 let bar = Area::new(24, h as i32 - 40, w.saturating_sub(48), 8);
62 self.stage
63 .bar(bar, t, accent, Rgba::hex(theme.recede_fg).with_alpha(96));
64 self.stage.label(24, 24, "shapes", fg);
65 let _ = self.stage.commit();
66
67 match frame.power() {
68 Power::Mains => frame.request_frame(),
69 Power::SavePower => frame.wake_after(1000),
70 }
71 }Sourcepub fn interval_ms(&self) -> u32
pub fn interval_ms(&self) -> u32
The paced frame interval.
Sourcepub fn power(&self) -> Power
pub fn power(&self) -> Power
Examples found in repository?
examples/shapes_stage.rs (line 67)
24 fn frame(&mut self, frame: &Frame) {
25 let (w, h) = self.stage.size();
26 if w == 0 || h == 0 {
27 // No pixel geometry yet: a resize will follow.
28 return;
29 }
30 let theme = view::theme();
31 let (fg, bg, accent) = (
32 Rgba::hex(theme.fg),
33 Rgba::hex(theme.bg),
34 Rgba::hex(theme.accent),
35 );
36 let t = (frame.now_ms() % 4000) as f32 / 4000.0;
37
38 // A full repaint: nothing is carried forward from the last frame.
39 self.stage.clear(bg);
40 let panel = Area::new(8, 8, w.saturating_sub(16), h.saturating_sub(16));
41 self.stage
42 .fill_rounded_rect(panel, 12, Rgba::hex(theme.recede_bg));
43 self.stage
44 .rounded_rect(panel, 12, Rgba::hex(theme.recede_fg));
45
46 let (cx, cy) = (w as f32 / 2.0, h as f32 / 2.0);
47 let radius = (w.min(h) / 4) as f32;
48 let angle = t * core::f32::consts::TAU;
49 // `no_std` has no `f32::sin`: the SDK re-exports `libm`. The dot
50 // moves between pixels; the shapes antialias it there.
51 let dot = (
52 cx + radius * libm::cosf(angle),
53 cy + radius * libm::sinf(angle),
54 );
55 self.stage
56 .circle((cx, cy), radius, Rgba::hex(theme.recede_fg));
57 self.stage
58 .line((cx as i32, cy as i32), (dot.0 as i32, dot.1 as i32), accent);
59 self.stage.fill_circle(dot, 6.0, accent);
60
61 let bar = Area::new(24, h as i32 - 40, w.saturating_sub(48), 8);
62 self.stage
63 .bar(bar, t, accent, Rgba::hex(theme.recede_fg).with_alpha(96));
64 self.stage.label(24, 24, "shapes", fg);
65 let _ = self.stage.commit();
66
67 match frame.power() {
68 Power::Mains => frame.request_frame(),
69 Power::SavePower => frame.wake_after(1000),
70 }
71 }Sourcepub fn request_frame(&self)
pub fn request_frame(&self)
Asks for the next paced frame (an animation).
Examples found in repository?
examples/shapes_stage.rs (line 68)
24 fn frame(&mut self, frame: &Frame) {
25 let (w, h) = self.stage.size();
26 if w == 0 || h == 0 {
27 // No pixel geometry yet: a resize will follow.
28 return;
29 }
30 let theme = view::theme();
31 let (fg, bg, accent) = (
32 Rgba::hex(theme.fg),
33 Rgba::hex(theme.bg),
34 Rgba::hex(theme.accent),
35 );
36 let t = (frame.now_ms() % 4000) as f32 / 4000.0;
37
38 // A full repaint: nothing is carried forward from the last frame.
39 self.stage.clear(bg);
40 let panel = Area::new(8, 8, w.saturating_sub(16), h.saturating_sub(16));
41 self.stage
42 .fill_rounded_rect(panel, 12, Rgba::hex(theme.recede_bg));
43 self.stage
44 .rounded_rect(panel, 12, Rgba::hex(theme.recede_fg));
45
46 let (cx, cy) = (w as f32 / 2.0, h as f32 / 2.0);
47 let radius = (w.min(h) / 4) as f32;
48 let angle = t * core::f32::consts::TAU;
49 // `no_std` has no `f32::sin`: the SDK re-exports `libm`. The dot
50 // moves between pixels; the shapes antialias it there.
51 let dot = (
52 cx + radius * libm::cosf(angle),
53 cy + radius * libm::sinf(angle),
54 );
55 self.stage
56 .circle((cx, cy), radius, Rgba::hex(theme.recede_fg));
57 self.stage
58 .line((cx as i32, cy as i32), (dot.0 as i32, dot.1 as i32), accent);
59 self.stage.fill_circle(dot, 6.0, accent);
60
61 let bar = Area::new(24, h as i32 - 40, w.saturating_sub(48), 8);
62 self.stage
63 .bar(bar, t, accent, Rgba::hex(theme.recede_fg).with_alpha(96));
64 self.stage.label(24, 24, "shapes", fg);
65 let _ = self.stage.commit();
66
67 match frame.power() {
68 Power::Mains => frame.request_frame(),
69 Power::SavePower => frame.wake_after(1000),
70 }
71 }Sourcepub fn wake_at(&self, at_ms: u64)
pub fn wake_at(&self, at_ms: u64)
Asks for a frame at at_ms on the viewer’s clock (a clock asks for
the next second). The earliest request wins.
Examples found in repository?
examples/clock_card.rs (line 56)
32 fn frame(&mut self, frame: &Frame) {
33 let second = frame.now_ms() / 1000;
34 if self.shown != Some(second) {
35 self.shown = Some(second);
36 let (cols, _) = self.card.size();
37 let time = format!(
38 "{:02}:{:02}:{:02}",
39 second / 3600 % 24,
40 second / 60 % 60,
41 second % 60
42 );
43 self.card.text(0, 0, &time, Style::fg(Colour::FG).bold());
44 let fraction = (second % 60) as f32 / 60.0;
45 let track = Style::fg(Colour::RECEDE_FG);
46 self.card.bar(
47 Area::new(0, 1, cols, 1),
48 fraction,
49 Style::fg(Colour::ACCENT),
50 track,
51 );
52 // Publishes only the cells that changed.
53 let _ = self.card.commit();
54 }
55 // The next second boundary: an idle viewer wakes once a second.
56 frame.wake_at((second + 1) * 1000);
57 }Sourcepub fn wake_after(&self, after_ms: u64)
pub fn wake_after(&self, after_ms: u64)
Asks for a frame after_ms from now.
Examples found in repository?
examples/shapes_stage.rs (line 69)
24 fn frame(&mut self, frame: &Frame) {
25 let (w, h) = self.stage.size();
26 if w == 0 || h == 0 {
27 // No pixel geometry yet: a resize will follow.
28 return;
29 }
30 let theme = view::theme();
31 let (fg, bg, accent) = (
32 Rgba::hex(theme.fg),
33 Rgba::hex(theme.bg),
34 Rgba::hex(theme.accent),
35 );
36 let t = (frame.now_ms() % 4000) as f32 / 4000.0;
37
38 // A full repaint: nothing is carried forward from the last frame.
39 self.stage.clear(bg);
40 let panel = Area::new(8, 8, w.saturating_sub(16), h.saturating_sub(16));
41 self.stage
42 .fill_rounded_rect(panel, 12, Rgba::hex(theme.recede_bg));
43 self.stage
44 .rounded_rect(panel, 12, Rgba::hex(theme.recede_fg));
45
46 let (cx, cy) = (w as f32 / 2.0, h as f32 / 2.0);
47 let radius = (w.min(h) / 4) as f32;
48 let angle = t * core::f32::consts::TAU;
49 // `no_std` has no `f32::sin`: the SDK re-exports `libm`. The dot
50 // moves between pixels; the shapes antialias it there.
51 let dot = (
52 cx + radius * libm::cosf(angle),
53 cy + radius * libm::sinf(angle),
54 );
55 self.stage
56 .circle((cx, cy), radius, Rgba::hex(theme.recede_fg));
57 self.stage
58 .line((cx as i32, cy as i32), (dot.0 as i32, dot.1 as i32), accent);
59 self.stage.fill_circle(dot, 6.0, accent);
60
61 let bar = Area::new(24, h as i32 - 40, w.saturating_sub(48), 8);
62 self.stage
63 .bar(bar, t, accent, Rgba::hex(theme.recede_fg).with_alpha(96));
64 self.stage.label(24, 24, "shapes", fg);
65 let _ = self.stage.commit();
66
67 match frame.power() {
68 Power::Mains => frame.request_frame(),
69 Power::SavePower => frame.wake_after(1000),
70 }
71 }Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Frame
impl !RefUnwindSafe for Frame
impl !Sync for Frame
impl Send for Frame
impl Unpin for Frame
impl UnsafeUnpin for Frame
impl UnwindSafe for Frame
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more