use std::marker::PhantomData;
use dart_sys::Dart_PersistentHandle;
use medea_macro::dart_bridge;
use crate::{
api::DartValue,
platform::{utils::dart_api, Callback},
};
#[dart_bridge("flutter/lib/src/native/ffi/function.g.dart")]
mod function {
use dart_sys::Dart_Handle;
use crate::{api::DartValue, platform::Error};
extern "C" {
pub fn caller(f: Dart_Handle, val: DartValue) -> Result<(), Error>;
}
}
impl<A: Into<DartValue>> Callback<A> {
pub fn call1<T: Into<A>>(&self, arg: T) {
if let Some(f) = self.0.borrow().as_ref() {
f.call1(arg.into());
}
}
}
#[derive(Debug)]
pub struct Function<T> {
dart_fn: Dart_PersistentHandle,
_arg: PhantomData<*const T>,
}
impl<T> Function<T> {
#[must_use]
pub const unsafe fn new(dart_fn: Dart_PersistentHandle) -> Self {
Self {
dart_fn,
_arg: PhantomData,
}
}
}
impl Function<()> {
pub fn call0(&self) {
self.call1(());
}
}
impl<T: Into<DartValue>> Function<T> {
pub fn call1(&self, arg: T) {
let fn_handle =
unsafe { dart_api::handle_from_persistent(self.dart_fn) };
unsafe { function::caller(fn_handle, arg.into()) }.unwrap();
}
}
impl<T> Drop for Function<T> {
fn drop(&mut self) {
unsafe {
dart_api::delete_persistent_handle(self.dart_fn);
}
}
}