1use super::*;
4use crate::abi;
5use crate::resolve;
6use core::ffi::c_void;
7use crate::mangle::{self, swift_type};
8
9pub(crate) unsafe fn alert_with_binding(
20 view: &ViewHandle,
21 title: &str, actions: &ViewHandle,
22 binding: &[u8],
23) -> ViewHandle {
24 unsafe {
25 let ss = abi::swift_string(title);
26 let s0 = u64::from_le_bytes(ss[..8].try_into().unwrap());
27 let s1 = u64::from_le_bytes(ss[8..].try_into().unwrap());
28 let (k0, k1, k2, k3) = localized_string_key(s0, s1);
29 let b0 = u64::from_le_bytes(binding[0..8].try_into().unwrap());
30 let b1 = u64::from_le_bytes(binding[8..16].try_into().unwrap());
31 let b2 = binding[16] as u64;
32
33 let ctx = Box::leak(Box::new(abi::ClosureCtx::new(
36 emit_tuple,
37 Child::leak(actions, Content::Concrete),
38 ))) as *mut abi::ClosureCtx;
39
40 let subst = [
41 view.meta, actions.meta, view.wt, actions.wt, ];
46 let (meta, wt, size) = opaque_result_type(resolve::alert_oret(), &subst);
47 let mut result = vec![0u8; size];
48 let this = view.value_ptr();
49 core::arch::asm!(
54 "sub sp, sp, #48",
55 "stp {cx}, {sm}, [sp]",
56 "stp {am}, {sw}, [sp, #16]",
57 "str {aw}, [sp, #32]",
58 "blr {f}",
59 "add sp, sp, #48",
60 f = in(reg) resolve::alert_fn(),
61 cx = in(reg) ctx,
62 sm = in(reg) view.meta,
63 am = in(reg) actions.meta,
64 sw = in(reg) view.wt,
65 aw = in(reg) actions.wt,
66 in("x0") k0, in("x1") k1, in("x2") k2, in("x3") k3,
67 in("x4") b0, in("x5") b1, in("x6") b2,
68 in("x7") abi::swift_closure_thunk as *const c_void,
69 in("x8") result.as_mut_ptr(),
70 in("x20") this,
71 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
72 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
73 lateout("x17") _, lateout("lr") _, lateout("x21") _, clobber_abi("C"),
74 );
75 wrap_owned(result, meta, wt)
76 }
77}
78
79pub(crate) unsafe fn alert_message_with_binding(
89 view: &ViewHandle,
90 title: &str,
91 actions: &ViewHandle,
92 message: &ViewHandle,
93 binding: &[u8],
94) -> ViewHandle {
95 unsafe {
96 let ss = abi::swift_string(title);
97 let s0 = u64::from_le_bytes(ss[..8].try_into().unwrap());
98 let s1 = u64::from_le_bytes(ss[8..].try_into().unwrap());
99 let (k0, k1, k2, k3) = localized_string_key(s0, s1);
100 let b0 = u64::from_le_bytes(binding[0..8].try_into().unwrap());
101 let b1 = u64::from_le_bytes(binding[8..16].try_into().unwrap());
102 let b2 = binding[16] as u64;
103
104 let actions_ctx = Box::leak(Box::new(abi::ClosureCtx::new(
106 emit_tuple,
107 Child::leak(actions, Content::Concrete),
108 ))) as *mut abi::ClosureCtx;
109 let message_ctx = Box::leak(Box::new(abi::ClosureCtx::new(
110 emit_tuple,
111 Child::leak(message, Content::Concrete),
112 ))) as *mut abi::ClosureCtx;
113
114 let subst = [
115 view.meta,
116 actions.meta,
117 message.meta,
118 view.wt,
119 actions.wt,
120 message.wt,
121 ];
122 let (meta, wt, size) = opaque_result_type(resolve::alert_msg_oret(), &subst);
123 let mut result = vec![0u8; size];
124 let this = view.value_ptr();
125 core::arch::asm!(
132 "sub sp, sp, #80",
133 "stp {ac}, {mf}, [sp]",
134 "stp {mc}, {sm}, [sp, #16]",
135 "stp {am}, {mm}, [sp, #32]",
136 "stp {sw}, {aw}, [sp, #48]",
137 "str {mw}, [sp, #64]",
138 "blr {f}",
139 "add sp, sp, #80",
140 f = in(reg) resolve::alert_msg_fn(),
141 ac = in(reg) actions_ctx,
142 mf = in(reg) abi::swift_closure_thunk as *const c_void,
143 mc = in(reg) message_ctx,
144 sm = in(reg) subst[0],
145 am = in(reg) subst[1],
146 mm = in(reg) subst[2],
147 sw = in(reg) subst[3],
148 aw = in(reg) subst[4],
149 mw = in(reg) subst[5],
150 in("x0") k0, in("x1") k1, in("x2") k2, in("x3") k3,
151 in("x4") b0, in("x5") b1, in("x6") b2,
152 in("x7") abi::swift_closure_thunk as *const c_void,
153 in("x8") result.as_mut_ptr(),
154 in("x20") this,
155 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
156 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
157 lateout("x17") _, lateout("lr") _, lateout("x21") _, clobber_abi("C"),
158 );
159 wrap_owned(result, meta, wt)
160 }
161}
162
163pub fn alert_message(
166 view: &ViewHandle,
167 title: &str,
168 actions: &ViewHandle,
169 message: &ViewHandle,
170 presented: bool,
171) -> ViewHandle {
172 unsafe {
173 let binding = constant_binding(
174 &[u8::from(presented)],
175 resolve::bool_meta(),
176 mangle::bound(&swift_type!(SwiftUI.Binding), &[mangle::BOOL]).as_bytes(),
177 );
178 alert_message_with_binding(view, title, actions, message, &binding)
179 }
180}
181
182pub fn alert_message_bound(
184 view: &ViewHandle,
185 title: &str,
186 actions: &ViewHandle,
187 message: &ViewHandle,
188 state: &BoundState<bool>,
189) -> ViewHandle {
190 unsafe {
191 let binding = bool_binding_of(state);
192 alert_message_with_binding(view, title, actions, message, &binding)
193 }
194}
195
196pub fn alert(view: &ViewHandle, title: &str, actions: &ViewHandle, presented: bool) -> ViewHandle {
200 unsafe {
201 let binding = constant_binding(
202 &[u8::from(presented)],
203 resolve::bool_meta(),
204 mangle::bound(&swift_type!(SwiftUI.Binding), &[mangle::BOOL]).as_bytes(),
205 );
206 alert_with_binding(view, title, actions, &binding)
207 }
208}
209
210pub fn alert_bound(view: &ViewHandle, title: &str, actions: &ViewHandle, state: &BoundState<bool>) -> ViewHandle {
212 unsafe {
213 let binding = bool_binding_of(state);
214 alert_with_binding(view, title, actions, &binding)
215 }
216}
217
218
219pub(crate) unsafe fn sheet_with_binding(
225 view: &ViewHandle,
226 content: &ViewHandle,
227 binding: &[u8],
228) -> ViewHandle {
229 unsafe { sheet_with_dismiss(view, content, binding, [0, 0]) }
230}
231
232pub(crate) unsafe fn sheet_with_dismiss(
242 view: &ViewHandle,
243 content: &ViewHandle,
244 binding: &[u8],
245 dismiss: [u64; 2],
246) -> ViewHandle {
247 unsafe {
248 presenting_with_dismiss(
249 view,
250 content,
251 binding,
252 dismiss,
253 resolve::sheet_fn(),
254 resolve::sheet_oret(),
255 )
256 }
257}
258
259pub(crate) unsafe fn presenting_with_dismiss(
267 view: &ViewHandle,
268 content: &ViewHandle,
269 binding: &[u8],
270 dismiss: [u64; 2],
271 f: *const c_void,
272 oret: *const c_void,
273) -> ViewHandle {
274 unsafe {
275 let b0 = u64::from_le_bytes(binding[0..8].try_into().unwrap());
276 let b1 = u64::from_le_bytes(binding[8..16].try_into().unwrap());
277 let b2 = binding[16] as u64;
278
279 let ctx = Box::leak(Box::new(abi::ClosureCtx::new(
284 emit_tuple,
285 Child::leak(content, Content::Concrete),
286 ))) as *mut abi::ClosureCtx;
287
288 let subst = [
289 view.meta, content.meta, view.wt, content.wt, ];
294 let (meta, wt, size) = opaque_result_type(oret, &subst);
295 let mut result = vec![0u8; size];
296 let this = view.value_ptr();
297 core::arch::asm!(
302 "sub sp, sp, #32",
303 "stp {cm}, {sw}, [sp]",
304 "str {cw}, [sp, #16]",
305 "blr {f}",
306 "add sp, sp, #32",
307 f = in(reg) f,
308 cm = in(reg) content.meta,
309 sw = in(reg) view.wt,
310 cw = in(reg) content.wt,
311 in("x0") b0, in("x1") b1, in("x2") b2,
312 in("x3") dismiss[0], in("x4") dismiss[1],
313 in("x5") abi::swift_closure_thunk as *const c_void,
314 in("x6") ctx,
315 in("x7") view.meta,
316 in("x8") result.as_mut_ptr(),
317 in("x20") this,
318 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
319 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
320 lateout("x17") _, lateout("lr") _, lateout("x21") _, clobber_abi("C"),
321 );
322 wrap_owned(result, meta, wt)
323 }
324}
325
326pub fn sheet_bound_dismiss(
333 view: &ViewHandle,
334 content: &ViewHandle,
335 state: &BoundState<bool>,
336 on_dismiss: impl Fn() + 'static,
337) -> ViewHandle {
338 unsafe {
339 let binding = bool_binding_of(state);
340 let words = super::closures::action_words(on_dismiss);
341 sheet_with_dismiss(view, content, &binding, words)
342 }
343}
344
345pub fn sheet(view: &ViewHandle, content: &ViewHandle, presented: bool) -> ViewHandle {
349 unsafe {
350 let binding = constant_binding(
351 &[u8::from(presented)],
352 resolve::bool_meta(),
353 mangle::bound(&swift_type!(SwiftUI.Binding), &[mangle::BOOL]).as_bytes(),
354 );
355 sheet_with_binding(view, content, &binding)
356 }
357}
358
359pub fn sheet_bound(view: &ViewHandle, content: &ViewHandle, state: &BoundState<bool>) -> ViewHandle {
361 unsafe {
362 let binding = bool_binding_of(state);
363 sheet_with_binding(view, content, &binding)
364 }
365}
366