1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//! A safe Rust SDK for Pebble watchapps and watchfaces, built on [`gneiss_sys`].
//!
//! Applications on PebbleOS do not have "bare-metal" hardware control, the OS owns the hardware and
//! the main event loop. The firmware loads and calls into your application binary at launch, where
//! you build your first window and register handlers, then return, yielding control back to the OS
//! event loop.
//!
//! # Getting started
//!
//! `cargo gneiss new` generates an app, `cargo gneiss build` builds its `.pbw` bundle, and
//! `cargo gneiss install` puts it on a watch. Every app has one
//! [`#[gneiss::entry]`](macro@entry) function:
//!
//! ```ignore
//! #![no_std]
//! #![no_main]
//! use gneiss::ui::{Nav, StaticWindow, UiGuard, Window};
//!
//! static HOME: StaticWindow<Home, ()> = StaticWindow::new();
//!
//! #[gneiss::entry]
//! fn main(ui: &mut UiGuard) {
//! HOME.set(Window::new(None).expect("home window"));
//! Nav::new(ui).push(&HOME, false);
//! }
//! ```
//!
//! `main` builds the first window and returns; the macro then subscribes your services and hands
//! over to the event loop. An app with no window on the stack exits.
//!
//! # Platforms
//!
//! Each watch model is a platform: `emery` (Pebble Time 2), `basalt`, `chalk`, `diorite`,
//! `flint`, `gabbro` and `aplite`. An app declares the ones it supports as features forwarding to
//! gneiss, e.g. `emery = ["gneiss/emery"]`, and `cargo gneiss build` builds it once for each. Code
//! can check the current platform's traits with cfgs the build sets, such as `cfg(pbl_round)` and
//! `cfg(pbl_touch)`.
//!
//! # Features
//!
//! - One per platform, as above. Exactly one is enabled in each build.
//! - `debug-logs` (default): [`debug!`](log::debug) and [`verbose!`](log::verbose) log. Without it
//! they compile to nothing, gneiss's own included.
//!
//! # Concurrency & Cross-Task Sync
//!
//! All app code runs on a single task, so there's no concurrency to guard against, only reentrancy
//! (see [`UiGuard`](ui::UiGuard)).
//! Read-modify-write atomics never complete on the Pebble Time 2, so the app target leaves them
//! out entirely: there is no `Arc`, and no `fetch_add` or `compare_exchange`; Where you would reach
//! for Arc/Mutex, instead use the single-threaded versions behind `unsafe impl Sync` wrappers.
//!
//! # Panics
//!
//! A panic logs its message and location to the app log, and the firmware closes the app.
//! Building with `-Cpanic=immediate-abort` drops the panic machinery, a few KiB, at the cost of
//! silent panics; it also makes `gneiss::ufmt` available, for formatting without `core::fmt`.
pub use ;
pub use gneiss_sys as sys;
pub use linkme;
/// Present when building with `-Cpanic=immediate-abort`. `use gneiss::ufmt;` puts it in scope for
/// `ufmt`'s macros.
pub use ufmt;
// Typed Resources
// Strong type wrappers for sys types
pub use ;
!
static __DOCTEST_ALLOC: PebbleAlloc = PebbleAlloc;