1use std::{
2 future::Future,
3 ops::{Deref, DerefMut},
4 pin::Pin,
5 ptr::null_mut,
6 sync::{
7 atomic::{AtomicBool, Ordering},
8 Arc,
9 },
10 task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
11};
12
13pub mod audio;
14pub mod core;
15pub mod data;
16pub mod graphics;
17pub mod input;
18
19#[derive(Debug)]
20struct Promise {
21 index: i32,
22 resolved: AtomicBool,
23}
24
25impl From<i32> for Promise {
26 fn from(index: i32) -> Self {
27 Self {
28 index,
29 resolved: AtomicBool::new(false),
30 }
31 }
32}
33
34impl Promise {
35 fn resolve(&self) {
37 if !self.resolved.swap(true, Ordering::Relaxed) {
38 unsafe {
39 crate::core::resolve_promise(self.index);
40 }
41 }
42 }
43}
44
45mod vtable {
46 use crate::Promise;
47 use std::mem::ManuallyDrop;
48 use std::sync::Arc;
49 use std::task::RawWaker;
50
51 pub unsafe fn clone(data: *const ()) -> RawWaker {
52 Arc::increment_strong_count(data as *const Promise);
53 RawWaker::new(data, &crate::V_TABLE)
54 }
55 pub unsafe fn wake(data: *const ()) {
56 let data = Arc::from_raw(data as *const Promise);
57 data.resolve();
58 }
59 pub unsafe fn wake_by_ref(data: *const ()) {
60 let data = ManuallyDrop::new(Arc::from_raw(data as *const Promise));
61 data.resolve();
62 }
63 pub unsafe fn drop(data: *const ()) {
64 std::mem::drop(Arc::from_raw(data as *const Promise));
65 }
66}
67
68const V_TABLE: RawWakerVTable = RawWakerVTable::new(
69 vtable::clone,
70 vtable::wake,
71 vtable::wake_by_ref,
72 vtable::drop,
73);
74
75#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
77#[repr(transparent)]
78pub struct Buffer(Box<[u8]>);
79
80impl Buffer {
81 fn new(size: usize) -> Self {
82 let mut vec = Vec::new();
83 vec.reserve_exact(size);
84 vec.resize(size, 0);
85 Self(vec.into_boxed_slice())
86 }
87}
88
89impl Deref for Buffer {
90 type Target = [u8];
91
92 fn deref(&self) -> &Self::Target {
93 &self.0
94 }
95}
96
97impl DerefMut for Buffer {
98 fn deref_mut(&mut self) -> &mut Self::Target {
99 &mut self.0
100 }
101}
102
103impl From<Buffer> for Box<[u8]> {
104 fn from(value: Buffer) -> Self {
105 value.0
106 }
107}
108impl From<Buffer> for Vec<u8> {
109 fn from(value: Buffer) -> Self {
110 value.0.into_vec()
111 }
112}
113
114#[no_mangle]
115pub extern "C" fn qwac_buffer_create(size: i32) -> *mut Buffer {
116 let buffer = Buffer::new(size.try_into().expect("Out of range"));
117 Box::into_raw(Box::new(buffer))
118}
119
120#[no_mangle]
121pub extern "C" fn qwac_buffer_pointer(buffer: *mut Buffer) -> *mut u8 {
122 let buffer = unsafe { &mut *buffer };
123 buffer.as_mut_ptr()
124}
125
126#[no_mangle]
127pub extern "C" fn qwac_poll(
128 raw_future: *mut Pin<Box<dyn Future<Output = ()>>>,
129 promise: i32,
130) -> *mut Pin<Box<dyn Future<Output = ()>>> {
131 let future = unsafe { &mut *raw_future }.as_mut();
132 let data: Arc<Promise> = Arc::new(promise.into());
133 let data = Arc::into_raw(data) as *const ();
134 let raw_waker = RawWaker::new(data, &V_TABLE);
135 let waker = unsafe { Waker::from_raw(raw_waker) };
136 let mut context = Context::from_waker(&waker);
137 match future.poll(&mut context) {
138 Poll::Ready(()) => {
139 unsafe {
141 drop(Box::from_raw(raw_future));
142 }
143 null_mut()
144 }
145 Poll::Pending => raw_future,
146 }
147}