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
122
123
124
125
126
127
128
129
130
131
132
133
134
//! Launch hooks for environments where the application entry point is not under the
//! interface developer's control.
//!
//! Some renderers and runtimes own program startup. For example, a web renderer may need
//! to initialize its runtime, bind to the host environment, and only then hand control
//! to application code. In those cases the platform integrator calls `cotis_launch()`
//! or `cotis_launch_async()`, and Cotis forwards execution to the developer's entry
//! through exported hook symbols.
//!
//! Application developers mark their entry function with the `cotis-macros` attributes
//! `#[cotis_start]` or `#[cotis_start_async]`. Those macros generate the `extern "Rust"`
//! hook symbols expected by this module.
//!
//! Enable the `app_launch` feature on the `cotis` crate when using this launch path.
//!
//! # Application developer
//!
//! Depend on `cotis-macros`, annotate your entry function, and implement your UI setup
//! as you would for a normal `main`:
//!
//! ```rust,ignore
//! use cotis_macros::cotis_start;
//!
//! #[cotis_start]
//! fn start() {
//! // Create CotisApp, then run your frame loop.
//! }
//! ```
//!
//! For async entry points:
//!
//! ```rust,ignore
//! use cotis_macros::cotis_start_async;
//!
//! #[cotis_start_async]
//! async fn start() {
//! // Create CotisApp, then await async frame computation.
//! }
//! ```
//!
//! `#[cotis_start]` and `#[cotis_start_async]` require a parameterless function. Async
//! functions must use `#[cotis_start_async]`, not `#[cotis_start]`.
//!
//! # Platform integrator
//!
//! After your renderer/runtime setup is complete, call the matching launch function:
//!
//! ```rust,ignore
//! // Synchronous host startup (for apps using #[cotis_start])
//! unsafe { cotis::launch::cotis_launch() };
//! ```
//!
//! ```rust,ignore
//! // Asynchronous host startup (for apps using #[cotis_start_async])
//! cotis::launch::cotis_launch_async().await;
//! ```
//!
//! Without the `app_launch` feature, both launch functions compile but do nothing.
use Pin;
/// Dispatches to the application entry hook registered by `#[cotis_start]`.
///
/// This is intended for platform integrators that control startup, not for application
/// developers writing UI code directly.
///
/// When the `app_launch` feature is enabled, this calls `hooks::__cotis_launch_hook`,
/// which is typically generated by `#[cotis_start]` in the `cotis-macros` crate on the
/// developer's entry function.
///
/// Without the `app_launch` feature this function is a no-op.
///
/// # Safety
///
/// This forwards to an externally provided `extern "Rust"` hook that must be correctly
/// defined and safe to invoke. Calling this is only sound when that hook was exported
/// by a trusted `#[cotis_start]` entry in the linked application.
///
/// # Examples
///
/// ```rust,ignore
/// // Called by a renderer host after runtime initialization.
/// unsafe { cotis::launch::cotis_launch() };
/// ```
pub unsafe
/// Dispatches to the application entry hook registered by `#[cotis_start_async]`.
///
/// This is intended for platform integrators that control async startup, not for
/// application developers writing UI code directly.
///
/// When the `app_launch` feature is enabled, this awaits `hooks::__cotis_launch_async_hook`,
/// which is typically generated by `#[cotis_start_async]` in the `cotis-macros` crate.
///
/// Without the `app_launch` feature this function is a no-op.
///
/// # Examples
///
/// ```rust,ignore
/// // Called by a renderer host after async runtime initialization.
/// cotis::launch::cotis_launch_async().await;
/// ```
pub async
/// Symbols exported by `#[cotis_start]` / `#[cotis_start_async]` and invoked by the
/// launch functions in this module.
///
/// Platform code should call [`cotis_launch`] or [`cotis_launch_async`] instead of
/// calling these hooks directly.