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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
// SPDX-License-Identifier: MPL-2.0
//! Application lifecycle and main thread management.
//!
//! This module is the foundation of `app_window`, providing essential initialization and
//! platform-specific event loop management. It handles the complex threading requirements
//! across different platforms, ensuring UI operations execute correctly while maintaining
//! a consistent async-first API.
//!
//! # Overview
//!
//! The module provides three key capabilities:
//!
//! 1. **Application initialization** via [`application::main`] - Sets up the platform event loop
//! 2. **Main thread execution** via [`application::on_main_thread`] - Runs async operations on the UI thread
//! 3. **Direct submission** via [`application::submit_to_main_thread`] - Fire-and-forget main thread tasks
//!
//! # Platform Threading Models
//!
//! Different platforms have vastly different requirements for UI operations:
//!
//! | Platform | Main Thread Requirement | Event Loop Model |
//! |----------|------------------------|------------------|
//! | macOS | **Strict** - All UI operations must be on main thread | AppKit runs on main thread |
//! | Windows | **Flexible** - UI can be on any thread with proper setup | Message pump per thread |
//! | Linux | **Flexible** - Wayland allows multi-threaded operations | Event queue per connection |
//! | WASM | **Single** - Browser is single-threaded | Event callbacks only |
//!
//! This module abstracts these differences, providing a uniform API that works correctly
//! on all platforms.
//!
//! # Getting Started
//!
//! Every `app_window` application follows this pattern:
//!
//! ```no_run
//! # // ALLOW_NORUN_DOCTEST: Requires full application initialization which blocks the thread
//! use app_window::application;
//!
//! fn main() {
//! // Must be called from the program's first thread
//! application::main(|| {
//! // This closure runs once the event loop is ready
//! // On platforms with strict main thread requirements,
//! // this runs on a worker thread
//!
//! println!("Application initialized!");
//!
//! // You can spawn async tasks here using your preferred executor
//! // For example, with tokio:
//! // tokio::spawn(async { /* ... */ });
//! });
//! }
//! ```
//!
//! # Async Design
//!
//! This crate is async-first to handle platform threading differences uniformly.
//! All potentially blocking operations are async, allowing them to coordinate
//! with the main thread when necessary:
//!
//! ```
//! # async fn example() {
//! use app_window::application;
//!
//! // Can be called from any thread after initialization
//! let result = application::on_main_thread("calculation".to_owned(), || {
//! // This runs on the main thread
//! expensive_ui_calculation()
//! }).await;
//! # }
//! # fn expensive_ui_calculation() -> i32 { 42 }
//! ```
//!
//! # Integration with Executors
//!
//! When `some_executor` support is enabled, this module automatically installs
//! a [`MainThreadExecutor`](crate::some_executor::MainThreadExecutor) that can
//! spawn futures on the main thread. This integrates seamlessly with the
//! `some_executor` crate's executor-agnostic task spawning.
//!
//! # Performance Monitoring
//!
//! The module includes built-in performance monitoring for main thread operations.
//! Operations taking longer than 10ms will generate warnings via `logwise`,
//! helping identify UI responsiveness issues:
//!
//! ```text
//! WARN: Main thread operation took too long: 15.2ms
//! ```
//!
//! Keep main thread operations brief to maintain smooth UI performance.
//!
//! # Error Handling
//!
//! Most functions in this module will panic if [`application::main`] hasn't been called yet.
//! This is intentional as it represents a programming error. Always ensure
//! `main` is called at the start of your program.
use AtomicBool;
pub use time;
pub use web_time as time;
use cratesys;
pub static IS_MAIN_THREAD_RUNNING: AtomicBool = new;
/// Error message constant used when operations require initialization.
///
/// This message is used throughout the crate when operations fail because
/// [`main()`] hasn't been called yet. Provides a consistent error message
/// for users.
///
/// # Internal Use
///
/// This constant is `pub(crate)` and not part of the public API. It's used
/// internally by various modules to provide consistent error messages when
/// the application hasn't been properly initialized.
pub const CALL_MAIN: &str = "Call app_window::application::main";
/// Initializes and runs the application event loop.
///
/// This is the entry point for all `app_window` applications. It must be called
/// exactly once from the program's first thread (the thread that `main()` runs on).
/// This function transforms the calling thread into the platform's UI event loop.
///
/// # Arguments
///
/// * `closure` - A function or closure that executes once the event loop is initialized.
/// This closure is where you set up your application, spawn tasks, and create windows.
///
/// **Important**: On platforms with strict main thread requirements (macOS),
/// this closure runs on a secondary thread, allowing the main thread to process events.
///
/// # Platform Behavior
///
/// The function behaves differently based on the platform's threading model:
///
/// | Platform | Main Thread Behavior | Closure Execution | Function Returns |
/// |----------|---------------------|-------------------|------------------|
/// | macOS | Blocks processing AppKit events | Secondary thread | Never (unless app quits) |
/// | Windows | Blocks processing Win32 messages | Secondary thread | Never (unless app quits) |
/// | Linux | Blocks processing Wayland events | Secondary thread | Never (unless app quits) |
/// | WASM | Sets up event callbacks | Same thread | Immediately |
///
/// # Executor Integration
///
/// When the `some_executor` feature is enabled, this function automatically:
/// 1. Installs a [`MainThreadExecutor`](crate::some_executor::MainThreadExecutor)
/// 2. Sets it as both the thread-local and thread-static executor
/// 3. Enables spawning futures that run on the main thread
///
/// # Panics
///
/// This function will panic if:
/// - Called from any thread other than the first thread (checked via [`is_main_thread()`])
/// - Called more than once in the program's lifetime
///
/// # Examples
///
/// ## Basic Setup
///
/// ```no_run
/// # // ALLOW_NORUN_DOCTEST: Function blocks indefinitely running the event loop
/// app_window::application::main(|| {
/// println!("Application ready!");
/// // Your app initialization here
/// });
/// ```
pub
/// Checks if the main thread event loop has been started.
///
/// This internal function verifies that [`main`] has been called and the
/// event loop is running. Used by other modules to ensure proper initialization
/// before attempting window creation or other operations.
///
/// # Returns
///
/// - `true` if [`main`] has been called and the event loop is running
/// - `false` if the application hasn't been initialized yet
///
/// # Thread Safety
///
/// Uses `Acquire` ordering to ensure all threads see the initialization
/// state correctly after it's set by [`main`].
///
/// # Internal Use
///
/// This function is `pub(crate)` and not part of the public API.
/// It's used internally by:
/// - Window creation to ensure the event loop exists
/// - Executor initialization checks
/// - Platform-specific initialization verification
pub
/// Executes a closure on the main thread and returns its result.
///
/// This async function provides safe, cross-platform access to the main thread from
/// any thread in your application. It's essential for operations that must occur
/// on the UI thread, such as window creation, UI updates, or platform API calls.
///
/// # Type Parameters
///
/// * `R` - The return type of the closure. Must implement `Send` since the result
/// crosses thread boundaries.
/// * `F` - The closure type. Must be `FnOnce() -> R + Send + 'static`.
///
/// # Arguments
///
/// * `debug_label` - A descriptive label for this operation, used for debugging and
/// performance monitoring. This appears in log messages if the operation takes too long.
/// * `closure` - The function or closure to execute on the main thread.
///
/// # Returns
///
/// The value returned by the closure, delivered asynchronously.
///
/// # How It Works
///
/// 1. Creates a continuation channel using `r#continue::continuation()`
/// 2. Wraps your closure to send its result through the channel
/// 3. Submits the wrapped closure to the main thread queue
/// 4. Awaits the result from the receiver
///
/// # Performance Monitoring
///
/// Operations are automatically monitored for performance:
/// - Operations taking >10ms generate a warning via `logwise`
/// - The `debug_label` helps identify slow operations
/// - Each operation runs in a new `logwise` task context for tracing
///
/// # Thread Safety
///
/// This function is safe to call from any thread after [`main`] has been called.
/// Multiple threads can call this concurrently; operations are queued and executed
/// in order on the main thread.
///
/// # Examples
///
/// ## Basic Usage
///
/// ```
/// # async fn example() {
/// use app_window::application;
///
/// let result = application::on_main_thread(
/// "calculate_ui_size".to_owned(),
/// || {
/// // This runs on the main thread
/// let width = 800;
/// let height = 600;
/// width * height
/// }
/// ).await;
///
/// assert_eq!(result, 480000);
/// # }
/// ```
///
/// ## Platform-Specific Operations
///
/// ```
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// use app_window::application;
///
/// // Access platform APIs that require main thread
/// let display_count = application::on_main_thread(
/// "get_display_count".to_owned(),
/// || {
/// // Platform-specific code to count displays
/// # 1
/// }
/// ).await;
///
/// println!("Found {} displays", display_count);
/// # Ok(())
/// # }
/// ```
///
/// ## Coordinating with UI Updates
///
/// ```
/// # async fn example() {
/// # struct UIState { title: String }
/// # impl UIState {
/// # fn update_title(&mut self, title: String) {}
/// # fn needs_redraw(&self) -> bool { false }
/// # fn redraw(&mut self) {}
/// # }
/// use app_window::application;
/// use std::sync::{Arc, Mutex};
///
/// let ui_state = Arc::new(Mutex::new(UIState { title: String::new() }));
/// let ui_state_clone = ui_state.clone();
///
/// // Update UI state from a background thread
/// application::on_main_thread(
/// "update_ui_title".to_owned(),
/// move || {
/// let mut state = ui_state_clone.lock().unwrap();
/// state.update_title("New Title".to_string());
///
/// // Trigger UI redraw if needed
/// if state.needs_redraw() {
/// state.redraw();
/// }
/// }
/// ).await;
/// # }
/// ```
///
/// # Performance Best Practices
///
/// Keep main thread operations brief:
///
/// ```
/// # async fn example() {
/// use app_window::application;
///
/// // ❌ BAD: Long-running computation blocks UI
/// // Avoid doing this:
/// // application::on_main_thread("heavy_work".to_owned(), || {
/// // for i in 0..1_000_000 {
/// // // Heavy computation
/// // }
/// // }).await;
///
/// // ✅ GOOD: Quick UI operation
/// let label = "Clicked";
/// application::on_main_thread("quick_update".to_owned(), move || {
/// // Just update UI state quickly
/// // In a real app, this would update actual UI
/// println!("Button label updated to: {}", label);
/// }).await;
/// # }
/// ```
pub async
/// Submits a closure to be executed on the main thread without waiting.
///
/// This is the fire-and-forget variant of [`on_main_thread()`]. Use this when you
/// need to perform main thread operations but don't need the result or completion
/// notification.
///
/// # Arguments
///
/// * `debug_label` - A descriptive label for debugging and performance monitoring.
/// Shows up in logs if the operation takes >10ms.
/// * `closure` - A function or closure to execute on the main thread.
/// Must be `FnOnce() + Send + 'static`.
///
/// # Behavior
///
/// - The closure is queued for execution on the main thread
/// - This function returns immediately without waiting
/// - No way to get the result or know when execution completes
/// - Operations are executed in the order they're submitted
///
/// # Performance Monitoring
///
/// Like [`on_main_thread()`], this function includes automatic performance monitoring:
/// - Creates a new `logwise` task context for the operation
/// - Logs a warning if execution takes >10ms
/// - Preserves the calling context for tracing
///
/// # Use Cases
///
/// This function is ideal for:
/// - UI updates that don't need confirmation
/// - Cleanup operations
/// - Event notifications
/// - Any fire-and-forget main thread work
///
/// # Examples
///
/// ## Basic Fire-and-Forget
///
/// ```
/// #[cfg(target_arch = "wasm32")] {
/// wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
/// }
/// use app_window::test_support::doctest_main;
/// doctest_main(|| {
/// use app_window::application;
///
/// // Update UI without waiting
/// application::submit_to_main_thread(
/// "update_status".to_owned(),
/// || {
/// update_status_bar("Operation complete");
/// }
/// );
///
/// // Continue immediately without waiting
/// println!("Submitted UI update");
///
/// fn update_status_bar(_: &str) {}
/// });
/// ```
///
/// ## Periodic UI Updates
///
/// ```
/// # fn example() {
/// use app_window::application;
///
/// // Submit periodic UI updates from a background task
/// for progress in [0.25, 0.5, 0.75, 1.0] {
/// application::submit_to_main_thread(
/// format!("update_progress_{}", progress),
/// move || {
/// // In a real app, this would update a progress bar UI
/// println!("Progress: {}%", (progress * 100.0) as u32);
/// }
/// );
/// }
/// # }
/// ```
///
/// ## Event Handling
///
/// ```
/// #[cfg(target_arch = "wasm32")] {
/// wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
/// }
/// use app_window::test_support::doctest_main;
/// doctest_main(|| {
/// use app_window::application;
///
/// fn handle_user_input(input: String) {
/// // Process input on current thread
/// let processed = input.to_uppercase();
///
/// // Update UI on main thread
/// application::submit_to_main_thread(
/// format!("handle_input_{}", processed.clone()),
/// move || {
/// // In a real app, this would update UI elements
/// println!("Displaying result: {}", processed);
/// }
/// );
/// }
///
/// // Example usage
/// handle_user_input("hello".to_string());
/// });
/// ```
///
/// # Implementation Details
///
/// This function wraps the closure with performance monitoring before calling
/// the platform-specific `sys::on_main_thread()`. The wrapper:
/// 1. Records the start time
/// 2. Creates a new logwise task context
/// 3. Executes the closure
/// 4. Restores the previous context
/// 5. Logs if execution was slow (>10ms)
/// Checks if the current thread is the main thread.
///
/// Returns `true` if called from the main thread (the thread that called
/// [`main`]), `false` otherwise.
///
/// # Platform Implementation
///
/// This delegates to the platform-specific `sys::is_main_thread()`,
/// which uses:
/// - **macOS**: `pthread_main_np()` or Swift runtime checks
/// - **Windows**: Thread ID comparison with the initial thread
/// - **Linux**: Thread ID comparison
/// - **WASM**: Always returns `true` (single-threaded)
///
/// # Examples
///
/// ```
/// use app_window::application;
///
/// if application::is_main_thread() {
/// println!("Running on the main thread");
/// } else {
/// println!("Running on a background thread");
/// }
/// ```
///
/// ## Conditional Execution
///
/// ```
/// # async fn example() {
/// use app_window::application;
///
/// async fn do_ui_operation() {
/// if application::is_main_thread() {
/// // Already on main thread, execute directly
/// perform_ui_update();
/// } else {
/// // Need to switch to main thread
/// application::on_main_thread(
/// "ui_update".to_owned(),
/// || perform_ui_update()
/// ).await;
/// }
/// }
///
/// fn perform_ui_update() {
/// // In a real app, this would update UI elements
/// println!("UI updated");
/// }
/// # }
/// ```