Skip to content

Commit a1dd9f9

Browse files
committed
refactor(examples): reorganize and consolidate async examples
- Rename 07_iosurface.rs -> 06_iosurface.rs - Rename 08_list_content.rs -> 07_list_content.rs - Consolidate async examples into single 08_async.rs - Remove redundant async_demo.rs and async_runtime_agnostic.rs
1 parent 138cd9c commit a1dd9f9

6 files changed

Lines changed: 209 additions & 414 deletions

File tree

examples/06_async.rs

Lines changed: 0 additions & 69 deletions
This file was deleted.

examples/08_async.rs

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
//! Async API Examples
2+
//!
3+
//! Demonstrates the async/await API (requires "async" feature).
4+
//! The async API is **executor-agnostic** and works with any runtime:
5+
//! Tokio, async-std, smol, or even a custom executor.
6+
//!
7+
//! Run with:
8+
//! ```bash
9+
//! cargo run --example 09_async --features async
10+
//! ```
11+
12+
#[cfg(not(feature = "async"))]
13+
fn main() {
14+
println!("⚠️ This example requires the 'async' feature");
15+
println!(" Run with: cargo run --example 09_async --features async");
16+
}
17+
18+
#[cfg(feature = "async")]
19+
#[tokio::main]
20+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
21+
println!("⚡ Async API Examples\n");
22+
println!("This API is executor-agnostic - works with Tokio, async-std, smol, etc.\n");
23+
println!("═══════════════════════════════════════════════════════════\n");
24+
25+
basic_async_capture().await?;
26+
println!();
27+
concurrent_operations().await?;
28+
println!();
29+
async_stream_iteration().await?;
30+
println!();
31+
runtime_agnostic_demo().await?;
32+
33+
println!("\n═══════════════════════════════════════════════════════════");
34+
println!("✨ All async examples complete!");
35+
println!("\n💡 Key Points:");
36+
println!(" • True async with callback-based Swift FFI");
37+
println!(" • No blocking - yields to executor while waiting");
38+
println!(" • Works with ANY async runtime");
39+
40+
Ok(())
41+
}
42+
43+
// ============================================================================
44+
// Example 1: Basic Async Capture
45+
// ============================================================================
46+
47+
#[cfg(feature = "async")]
48+
async fn basic_async_capture() -> Result<(), Box<dyn std::error::Error>> {
49+
use screencapturekit::async_api::AsyncSCShareableContent;
50+
51+
println!("📡 1. Basic Async Content Retrieval");
52+
println!(" ─────────────────────────────────");
53+
54+
// Get content asynchronously (true async - no blocking)
55+
let content = AsyncSCShareableContent::get().await?;
56+
57+
let displays = content.displays();
58+
let windows = content.windows();
59+
let apps = content.applications();
60+
61+
println!(" ✅ Found:");
62+
println!(" • {} displays", displays.len());
63+
println!(" • {} windows", windows.len());
64+
println!(" • {} applications", apps.len());
65+
66+
// Show display details
67+
for display in displays.iter().take(2) {
68+
println!(
69+
" Display {}: {}x{}",
70+
display.display_id(),
71+
display.width(),
72+
display.height()
73+
);
74+
}
75+
76+
Ok(())
77+
}
78+
79+
// ============================================================================
80+
// Example 2: Concurrent Operations
81+
// ============================================================================
82+
83+
#[cfg(feature = "async")]
84+
async fn concurrent_operations() -> Result<(), Box<dyn std::error::Error>> {
85+
use screencapturekit::async_api::AsyncSCShareableContent;
86+
87+
println!("⚡ 2. Concurrent Async Operations");
88+
println!(" ─────────────────────────────────");
89+
90+
let start = std::time::Instant::now();
91+
92+
// Run 3 async operations concurrently
93+
let (result1, result2, result3) = tokio::join!(
94+
AsyncSCShareableContent::get(),
95+
AsyncSCShareableContent::with_options()
96+
.on_screen_windows_only(true)
97+
.get_async(),
98+
AsyncSCShareableContent::with_options()
99+
.exclude_desktop_windows(true)
100+
.get_async(),
101+
);
102+
103+
let elapsed = start.elapsed();
104+
105+
println!(" ✅ 3 concurrent operations completed in {:?}", elapsed);
106+
107+
if let Ok(content) = result1 {
108+
println!(" • All content: {} windows", content.windows().len());
109+
}
110+
if let Ok(content) = result2 {
111+
println!(
112+
" • On-screen only: {} windows",
113+
content.windows().len()
114+
);
115+
}
116+
if let Ok(content) = result3 {
117+
println!(
118+
" • Excluding desktop: {} windows",
119+
content.windows().len()
120+
);
121+
}
122+
123+
Ok(())
124+
}
125+
126+
// ============================================================================
127+
// Example 3: Async Stream with Frame Iteration
128+
// ============================================================================
129+
130+
#[cfg(feature = "async")]
131+
async fn async_stream_iteration() -> Result<(), Box<dyn std::error::Error>> {
132+
use screencapturekit::async_api::{AsyncSCShareableContent, AsyncSCStream};
133+
use screencapturekit::stream::configuration::SCStreamConfiguration;
134+
use screencapturekit::stream::content_filter::SCContentFilter;
135+
use screencapturekit::stream::output_type::SCStreamOutputType;
136+
137+
println!("🎥 3. Async Stream Frame Iteration");
138+
println!(" ─────────────────────────────────");
139+
140+
let content = AsyncSCShareableContent::get().await?;
141+
let displays = content.displays();
142+
143+
if let Some(display) = displays.first() {
144+
let filter = SCContentFilter::build()
145+
.display(display)
146+
.exclude_windows(&[])
147+
.build();
148+
149+
let config = SCStreamConfiguration::build()
150+
.set_width(1920)?
151+
.set_height(1080)?;
152+
153+
// Create async stream with 30-frame buffer
154+
let stream = AsyncSCStream::new(&filter, &config, 30, SCStreamOutputType::Screen);
155+
stream.start_capture()?;
156+
157+
println!(" Capturing frames asynchronously...");
158+
159+
// Capture 10 frames using async iteration
160+
let mut count = 0;
161+
while count < 10 {
162+
if let Some(_frame) = stream.next().await {
163+
count += 1;
164+
if count % 5 == 0 {
165+
println!(" Frame {}", count);
166+
}
167+
}
168+
}
169+
170+
stream.stop_capture()?;
171+
println!(" ✅ Captured {} frames", count);
172+
} else {
173+
println!(" ⚠️ No displays available");
174+
}
175+
176+
Ok(())
177+
}
178+
179+
// ============================================================================
180+
// Example 4: Runtime-Agnostic Demo
181+
// ============================================================================
182+
183+
#[cfg(feature = "async")]
184+
async fn runtime_agnostic_demo() -> Result<(), Box<dyn std::error::Error>> {
185+
use screencapturekit::async_api::AsyncSCShareableContent;
186+
187+
println!("🌍 4. Runtime-Agnostic Demonstration");
188+
println!(" ─────────────────────────────────");
189+
println!(" This same code works with ANY async runtime:");
190+
println!(" • Tokio ✅");
191+
println!(" • async-std ✅");
192+
println!(" • smol ✅");
193+
println!(" • futures executor ✅");
194+
println!(" • Custom executors ✅");
195+
196+
// The async API uses only std types internally:
197+
// - std::future::Future
198+
// - std::task::{Poll, Waker, Context}
199+
// - std::sync::{Arc, Mutex}
200+
// - Callback-based Swift FFI
201+
202+
let content = AsyncSCShareableContent::get().await?;
203+
println!(
204+
"\n ✅ Retrieved {} displays using executor-agnostic async",
205+
content.displays().len()
206+
);
207+
208+
Ok(())
209+
}

0 commit comments

Comments
 (0)