Skip to main content

OpenAppMessages

Struct OpenAppMessages 

Source
pub struct OpenAppMessages<'handle> { /* private fields */ }

Implementations§

Source§

impl<'open> OpenAppMessages<'open>

Source

pub fn send( &self, f: impl for<'dictionary> FnOnce(&mut DictionaryWriter<'dictionary>) -> Result<(), DictionaryResult>, ) -> Result<(), AppMessageSendResult>

Examples found in repository?
example/src/lib.rs (line 63)
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}
Source

pub fn listen<'env, 'this, FInboxReceived, FInboxDropped, FOutboxSent, FOutboxFailed>( &'this self, inbox_received: FInboxReceived, inbox_dropped: FInboxDropped, outbox_sent: FOutboxSent, outbox_failed: FOutboxFailed, ) -> impl PinInit<Handle<'this, AppMessageListener<'open, FInboxReceived, FInboxDropped, FOutboxSent, FOutboxFailed>>>
where FInboxReceived: for<'message> FnMut(DictionaryRef<'message>) + 'env, FInboxDropped: FnMut(AppMessageResult) + 'env, FOutboxSent: for<'message> FnMut(DictionaryRef<'message>) + 'env, FOutboxFailed: for<'message> FnMut(DictionaryRef<'message>, AppMessageResult) + 'env,

Register callbacks to listen on app message events.

These closures are capable of borrowing references to local variables.

NOTE: You can create multiple app message event listeners from multiple locations, the library handles this elegantly using an intrusive linked list of stack-allocated nodes.

This returns a [PinInit] as we need to pass the pebble SDK a pointer to the stack allocated closures passed in. If Handle could move, it would invalidate this reference.

Use [pin_init::stack_pin_init] to allocate the result of this method in your stack frame.

Examples found in repository?
src/app_message.rs (lines 243-248)
225    pub fn listen_received<'this, 'env, FInboxReceived>(
226        &'this self,
227        inbox_received: FInboxReceived,
228    ) -> impl PinInit<
229        Handle<
230            'this,
231            AppMessageListener<
232                'open,
233                FInboxReceived,
234                EmptyInboxDroppedHandler<'env>,
235                EmptyOutboxSentHandler<'env>,
236                EmptyOutboxFailedHandler<'env>,
237            >,
238        >,
239    >
240    where
241        FInboxReceived: for<'message> FnMut(DictionaryRef<'message>) + 'env,
242    {
243        self.listen(
244            inbox_received,
245            empty_inbox_dropped_handler(),
246            empty_outbox_sent_handler(),
247            empty_outbox_failed_handler(),
248        )
249    }
More examples
Hide additional examples
example/src/lib.rs (lines 47-52)
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}
Source

pub fn listen_received<'this, 'env, FInboxReceived>( &'this self, inbox_received: FInboxReceived, ) -> impl PinInit<Handle<'this, AppMessageListener<'open, FInboxReceived, EmptyInboxDroppedHandler<'env>, EmptyOutboxSentHandler<'env>, EmptyOutboxFailedHandler<'env>>>>
where FInboxReceived: for<'message> FnMut(DictionaryRef<'message>) + 'env,

Register callbacks to listen on app message receive events.

These closures are capable of borrowing references to local variables.

NOTE: You can create multiple app message event listeners from multiple locations, the library handles this elegantly using an intrusive linked list of stack-allocated nodes.

This returns a [PinInit] as we need to pass the pebble SDK a pointer to the stack allocated closures passed in. If Handle could move, it would invalidate this reference.

Use [pin_init::stack_pin_init] to allocate the result of this method in your stack frame.

Examples found in repository?
example/src/lib.rs (lines 59-61)
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}

Trait Implementations§

Source§

impl Drop for OpenAppMessages<'_>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl<'open> MultiRegistrationService for OpenAppMessages<'open>

Source§

type CallbackData = AppMessagesPointers

Source§

fn list(&self) -> &SingleCoreCell<List<Entry<Self::CallbackData>>>

Retrieve the intrusive list root for this service.

Auto Trait Implementations§

§

impl<'handle> !UnwindSafe for OpenAppMessages<'handle>

§

impl<'handle> Freeze for OpenAppMessages<'handle>

§

impl<'handle> RefUnwindSafe for OpenAppMessages<'handle>

§

impl<'handle> Send for OpenAppMessages<'handle>

§

impl<'handle> Sync for OpenAppMessages<'handle>

§

impl<'handle> Unpin for OpenAppMessages<'handle>

§

impl<'handle> UnsafeUnpin for OpenAppMessages<'handle>

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Init<T> for T

§

unsafe fn __init(self, slot: *mut T) -> Result<(), Infallible>

Initializes slot. Read more
§

fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>
where F: FnOnce(&mut T) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

§

impl<T> PinInit<T> for T

§

unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), Infallible>

Initializes slot. Read more
§

fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>
where F: FnOnce(Pin<&mut T>) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.