use super::*;
use crate::abi;
use crate::resolve;
use core::ffi::c_void;
use crate::mangle::{self, swift_type};
pub(crate) unsafe fn alert_with_binding(
view: &ViewHandle,
title: &str, actions: &ViewHandle,
binding: &[u8],
) -> ViewHandle {
unsafe {
let ss = abi::swift_string(title);
let s0 = u64::from_le_bytes(ss[..8].try_into().unwrap());
let s1 = u64::from_le_bytes(ss[8..].try_into().unwrap());
let (k0, k1, k2, k3) = localized_string_key(s0, s1);
let b0 = u64::from_le_bytes(binding[0..8].try_into().unwrap());
let b1 = u64::from_le_bytes(binding[8..16].try_into().unwrap());
let b2 = binding[16] as u64;
let ctx = Box::leak(Box::new(abi::ClosureCtx::new(
emit_tuple,
Child::leak(actions, Content::Concrete),
))) as *mut abi::ClosureCtx;
let subst = [
view.meta, actions.meta, view.wt, actions.wt, ];
let (meta, wt, size) = opaque_result_type(resolve::alert_oret(), &subst);
let mut result = vec![0u8; size];
let this = view.value_ptr();
core::arch::asm!(
"sub sp, sp, #48",
"stp {cx}, {sm}, [sp]",
"stp {am}, {sw}, [sp, #16]",
"str {aw}, [sp, #32]",
"blr {f}",
"add sp, sp, #48",
f = in(reg) resolve::alert_fn(),
cx = in(reg) ctx,
sm = in(reg) view.meta,
am = in(reg) actions.meta,
sw = in(reg) view.wt,
aw = in(reg) actions.wt,
in("x0") k0, in("x1") k1, in("x2") k2, in("x3") k3,
in("x4") b0, in("x5") b1, in("x6") b2,
in("x7") abi::swift_closure_thunk as *const c_void,
in("x8") result.as_mut_ptr(),
in("x20") this,
lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
lateout("x17") _, lateout("lr") _, lateout("x21") _, clobber_abi("C"),
);
wrap_owned(result, meta, wt)
}
}
pub(crate) unsafe fn alert_message_with_binding(
view: &ViewHandle,
title: &str,
actions: &ViewHandle,
message: &ViewHandle,
binding: &[u8],
) -> ViewHandle {
unsafe {
let ss = abi::swift_string(title);
let s0 = u64::from_le_bytes(ss[..8].try_into().unwrap());
let s1 = u64::from_le_bytes(ss[8..].try_into().unwrap());
let (k0, k1, k2, k3) = localized_string_key(s0, s1);
let b0 = u64::from_le_bytes(binding[0..8].try_into().unwrap());
let b1 = u64::from_le_bytes(binding[8..16].try_into().unwrap());
let b2 = binding[16] as u64;
let actions_ctx = Box::leak(Box::new(abi::ClosureCtx::new(
emit_tuple,
Child::leak(actions, Content::Concrete),
))) as *mut abi::ClosureCtx;
let message_ctx = Box::leak(Box::new(abi::ClosureCtx::new(
emit_tuple,
Child::leak(message, Content::Concrete),
))) as *mut abi::ClosureCtx;
let subst = [
view.meta,
actions.meta,
message.meta,
view.wt,
actions.wt,
message.wt,
];
let (meta, wt, size) = opaque_result_type(resolve::alert_msg_oret(), &subst);
let mut result = vec![0u8; size];
let this = view.value_ptr();
core::arch::asm!(
"sub sp, sp, #80",
"stp {ac}, {mf}, [sp]",
"stp {mc}, {sm}, [sp, #16]",
"stp {am}, {mm}, [sp, #32]",
"stp {sw}, {aw}, [sp, #48]",
"str {mw}, [sp, #64]",
"blr {f}",
"add sp, sp, #80",
f = in(reg) resolve::alert_msg_fn(),
ac = in(reg) actions_ctx,
mf = in(reg) abi::swift_closure_thunk as *const c_void,
mc = in(reg) message_ctx,
sm = in(reg) subst[0],
am = in(reg) subst[1],
mm = in(reg) subst[2],
sw = in(reg) subst[3],
aw = in(reg) subst[4],
mw = in(reg) subst[5],
in("x0") k0, in("x1") k1, in("x2") k2, in("x3") k3,
in("x4") b0, in("x5") b1, in("x6") b2,
in("x7") abi::swift_closure_thunk as *const c_void,
in("x8") result.as_mut_ptr(),
in("x20") this,
lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
lateout("x17") _, lateout("lr") _, lateout("x21") _, clobber_abi("C"),
);
wrap_owned(result, meta, wt)
}
}
pub fn alert_message(
view: &ViewHandle,
title: &str,
actions: &ViewHandle,
message: &ViewHandle,
presented: bool,
) -> ViewHandle {
unsafe {
let binding = constant_binding(
&[u8::from(presented)],
resolve::bool_meta(),
mangle::bound(&swift_type!(SwiftUI.Binding), &[mangle::BOOL]).as_bytes(),
);
alert_message_with_binding(view, title, actions, message, &binding)
}
}
pub fn alert_message_bound(
view: &ViewHandle,
title: &str,
actions: &ViewHandle,
message: &ViewHandle,
state: &BoundState<bool>,
) -> ViewHandle {
unsafe {
let binding = bool_binding_of(state);
alert_message_with_binding(view, title, actions, message, &binding)
}
}
pub fn alert(view: &ViewHandle, title: &str, actions: &ViewHandle, presented: bool) -> ViewHandle {
unsafe {
let binding = constant_binding(
&[u8::from(presented)],
resolve::bool_meta(),
mangle::bound(&swift_type!(SwiftUI.Binding), &[mangle::BOOL]).as_bytes(),
);
alert_with_binding(view, title, actions, &binding)
}
}
pub fn alert_bound(view: &ViewHandle, title: &str, actions: &ViewHandle, state: &BoundState<bool>) -> ViewHandle {
unsafe {
let binding = bool_binding_of(state);
alert_with_binding(view, title, actions, &binding)
}
}
pub(crate) unsafe fn sheet_with_binding(
view: &ViewHandle,
content: &ViewHandle,
binding: &[u8],
) -> ViewHandle {
unsafe { sheet_with_dismiss(view, content, binding, [0, 0]) }
}
pub(crate) unsafe fn sheet_with_dismiss(
view: &ViewHandle,
content: &ViewHandle,
binding: &[u8],
dismiss: [u64; 2],
) -> ViewHandle {
unsafe {
presenting_with_dismiss(
view,
content,
binding,
dismiss,
resolve::sheet_fn(),
resolve::sheet_oret(),
)
}
}
pub(crate) unsafe fn presenting_with_dismiss(
view: &ViewHandle,
content: &ViewHandle,
binding: &[u8],
dismiss: [u64; 2],
f: *const c_void,
oret: *const c_void,
) -> ViewHandle {
unsafe {
let b0 = u64::from_le_bytes(binding[0..8].try_into().unwrap());
let b1 = u64::from_le_bytes(binding[8..16].try_into().unwrap());
let b2 = binding[16] as u64;
let ctx = Box::leak(Box::new(abi::ClosureCtx::new(
emit_tuple,
Child::leak(content, Content::Concrete),
))) as *mut abi::ClosureCtx;
let subst = [
view.meta, content.meta, view.wt, content.wt, ];
let (meta, wt, size) = opaque_result_type(oret, &subst);
let mut result = vec![0u8; size];
let this = view.value_ptr();
core::arch::asm!(
"sub sp, sp, #32",
"stp {cm}, {sw}, [sp]",
"str {cw}, [sp, #16]",
"blr {f}",
"add sp, sp, #32",
f = in(reg) f,
cm = in(reg) content.meta,
sw = in(reg) view.wt,
cw = in(reg) content.wt,
in("x0") b0, in("x1") b1, in("x2") b2,
in("x3") dismiss[0], in("x4") dismiss[1],
in("x5") abi::swift_closure_thunk as *const c_void,
in("x6") ctx,
in("x7") view.meta,
in("x8") result.as_mut_ptr(),
in("x20") this,
lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
lateout("x17") _, lateout("lr") _, lateout("x21") _, clobber_abi("C"),
);
wrap_owned(result, meta, wt)
}
}
pub fn sheet_bound_dismiss(
view: &ViewHandle,
content: &ViewHandle,
state: &BoundState<bool>,
on_dismiss: impl Fn() + 'static,
) -> ViewHandle {
unsafe {
let binding = bool_binding_of(state);
let words = super::closures::action_words(on_dismiss);
sheet_with_dismiss(view, content, &binding, words)
}
}
pub fn sheet(view: &ViewHandle, content: &ViewHandle, presented: bool) -> ViewHandle {
unsafe {
let binding = constant_binding(
&[u8::from(presented)],
resolve::bool_meta(),
mangle::bound(&swift_type!(SwiftUI.Binding), &[mangle::BOOL]).as_bytes(),
);
sheet_with_binding(view, content, &binding)
}
}
pub fn sheet_bound(view: &ViewHandle, content: &ViewHandle, state: &BoundState<bool>) -> ViewHandle {
unsafe {
let binding = bool_binding_of(state);
sheet_with_binding(view, content, &binding)
}
}