Skip to main content

bordstein_example/
lib.rs

1#![no_std]
2#![feature(impl_trait_in_assoc_type)]
3
4use futures::StreamExt as _;
5use heapless::CString;
6use pin_init::stack_pin_init;
7
8use bordstein::{
9    bindings::{GColor8, GTextAlignment, TimeUnits},
10    prelude::*,
11    shapes,
12};
13
14bordstein::main!(async_main);
15
16// #[embassy_executor::task]
17// async fn async_main(services: bordstein::PebbleServices, spawner: embassy_executor::Spawner) {
18//     window::with_window(async |mut h| {
19//         pin_init::stack_pin_init!(let layer = h
20//         .root_layer()
21//         .new_child::<Layer>(GRect::new(0, 0, 10, 10))
22//         .unwrap()
23//         .with_update_proc(|l, mut ctx| {
24//             let bounds = l.bounds();
25//             ctx.set_fill_colour(GColor::RED);
26//             ctx.fill_rect(bounds, 10, GCornerMask::GCornersAll);
27//         }));
28
29//         for i in 0..200 {
30//             layer.set_frame(GRect::new(i, i, 10, 10));
31//             Timer::after_millis(50).await;
32//         }
33//     })
34//     .await;
35// }
36
37#[embassy_executor::task]
38async fn async_main(services: bordstein::PebbleServices, spawner: embassy_executor::Spawner) {
39    async_main_(services, spawner).await;
40}
41
42async fn async_main_(mut services: bordstein::PebbleServices, _spawner: embassy_executor::Spawner) {
43    bordstein::info!("Async main called!");
44
45    with_window(async |mut h| {
46        let app_messages = services.app_messages.open(1024, 512);
47        stack_pin_init!(let _app_message_listener = app_messages.listen(
48            |_d| {},
49            |_| {},
50            |_| {},
51            |_, _| {},
52        ));
53        stack_pin_init!(let _app_message_listener = app_messages.listen(
54            |_d| {},
55            |_| {},
56            |_| {},
57            |_, _| {},
58        ));
59        stack_pin_init!(let _app_message_listener = app_messages.listen_received(
60            |_d| {},
61        ));
62
63        let _ = app_messages.send(|d| d.u8(10001, 123));
64
65        h.set_background_colour(GColor8::RED);
66
67        let window_bounds = h.root_layer().bounds();
68        bordstein::info!("Window bounds: {:?}", window_bounds);
69
70        stack_pin_init!(let timer_minutes = TickService::listen(TimeUnits::MINUTE_UNIT, |time, _| {
71            bordstein::info!("minute timer tick: {:?}", time);
72        }));
73
74        let mut foo = 123;
75
76        {
77            stack_pin_init!(let timer_seconds = TickService::listen(TimeUnits::SECOND_UNIT, |time, _| {
78                bordstein::info!("second timer tick: {:?}", time);
79            }));
80
81            let root_layer = h.root_layer();
82            let status_bar = root_layer.new_child::<StatusBarLayer>(()).unwrap();
83
84            let remaining_space =
85                window_bounds.shrink_to_avoid(status_bar.layer().bounds(), shapes::Edge::Top, 0);
86
87            stack_pin_init! {
88                let child_layer = root_layer
89                    .new_child::<Layer>(remaining_space)
90                    .unwrap()
91                    .with_update_proc(|_layer, _ctx| {
92                        bordstein::debug!("Hello from layer callback: {}", foo);
93                        foo += 1;
94                    })
95            };
96
97            let mut num_taps: u32 = 0;
98
99            let mut accelerometer_service = services.accelerometer.enable();
100            stack_pin_init!(let tap_events = accelerometer_service.subscribe_to_tap_service(|axis, dir| {
101                num_taps += 1;
102                bordstein::info!("Tap! {}, {:?}, {}", num_taps, axis, dir);
103            }));
104
105            let mut text_layer: TextLayer<'_> = child_layer
106                .new_child::<TextLayer>(child_layer.bounds())
107                .unwrap();
108            text_layer.set_text_alignment(GTextAlignment::GTextAlignmentCenter);
109
110            let mut text_content: CString<64>;
111            for i in 0..10 {
112                text_content = CString::<64>::new();
113                let _ = ufmt::uwrite!(&mut text_content, "{}", i);
114                let _guard = text_layer.set_text(&text_content);
115
116                embassy_time::Timer::after_secs(1).await;
117
118                app_messages
119                    .send(|d| {
120                        d.u16(10001, 1234)?;
121
122                        Ok(())
123                    })
124                    .unwrap();
125            }
126
127            bordstein::info!("Child bounds: {:?}", child_layer.bounds());
128        }
129
130        stack_pin_init!(let timer_seconds_stream = TickService::stream(TimeUnits::SECOND_UNIT));
131        while let Some(t) = timer_seconds_stream.next().await {
132            bordstein::info!("second tick stream: {}", t.0.secs);
133        }
134
135        // layers now destroyed, app should show just the window with its red background
136
137        // if you have nothing else to do, but want to wait until the system
138        // closes the window, you can use core::future::pending.
139        core::future::pending::<()>().await;
140    })
141    .await
142    .unwrap();
143}