use std::future::Future; use giterated_abi::{ callback::{Callback, CallbackPtr}, value_ex::FfiValueUntyped, vtable::{Object, Setting}, FfiValueMut, FfiValueRef, }; use giterated_models::{error::OperationError, object::GiteratedObject}; use crate::{ future::{RuntimeFuture, RuntimeFuturesExt}, new_stack::PluginState, state::State, }; use super::RuntimeState; pub struct SettingGetterCallback(FfiValueUntyped); impl Callback for SettingGetterCallback { type CallbackFunc = unsafe extern "C" fn( CallbackPtr, state: FfiValueMut, object: FfiValueRef, ) -> RuntimeFuture>; } impl SettingGetterCallback { // pub fn new>(callback: T) -> Self { // Self { // func: T::get_setting, // callback_ptr: callback.callback_ptr(), // } // } } pub trait IntoPluginSettingGetter { unsafe extern "C" fn get_setting( callback_ptr: CallbackPtr, state: FfiValueMut, object: FfiValueRef, ) -> RuntimeFuture>; fn callback_ptr(&self) -> CallbackPtr { // unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } todo!() } } impl IntoPluginSettingGetter for F where Fut: Future>> + Send + Sync + 'static, S: Clone + Send + Sync + 'static, O: GiteratedObject + Send + Sync + 'static, OS: giterated_models::settings::Setting + Send + Sync + 'static, F: Fn(S, O) -> Fut + Send + Sync + 'static, { unsafe extern "C" fn get_setting( callback: CallbackPtr, state: FfiValueMut, mut object: FfiValueRef, ) -> RuntimeFuture> { // let _guard = trace_span!( // "get_setting handler", // object = O::object_name(), // setting = OS::name() // ) // .entered(); // let state = unsafe { state.transmute_ref::() }; // let object = unsafe { object.transmute_owned::() }; // // Cast the callback ptr to ourselves // let callback: *const F = std::mem::transmute(callback.0); // let callback = callback.as_ref().unwrap(); // let state = state.clone(); // runtime_state.spawn_future(async move { // let result = callback(state, *object).await; // match result { // Ok(success) => unsafe { Ok(NewAnySetting::new(success)) }, // Err(err) => match err { // OperationError::Operation(_) => todo!(), // OperationError::Internal(_) => todo!(), // OperationError::Unhandled => todo!(), // }, // } todo!() // }) } } pub trait IntoPluginSettingSetter { unsafe extern "C" fn set_setting( callback_ptr: CallbackPtr, state: &PluginState, object: FfiValueRef, setting: Setting, ) -> RuntimeFuture>; fn callback_ptr(&self) -> CallbackPtr { // unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } todo!() } } impl IntoPluginSettingSetter for F where Fut: Future>>, S: Clone, O: GiteratedObject, OS: giterated_models::settings::Setting, F: Fn(S, O, OS) -> Fut, { unsafe extern "C" fn set_setting( callback: CallbackPtr, state: &PluginState, mut object: FfiValueRef, _setting: Setting, ) -> RuntimeFuture> { // let _guard = trace_span!( // "get_setting handler", // object = O::object_name(), // setting = OS::name() // ) // .entered(); // let _state = unsafe { state.transmute_ref::() }; // let _object = unsafe { object.transmute_owned::() }; // // Cast the callback ptr to ourselves // let callback: *const F = std::mem::transmute(callback.0); // let _callback = callback.as_ref().unwrap(); // let result = callback(state.clone(), *object); // match result { // Ok(setting) => Ok(NewAnySetting::new(setting)), // Err(_) => todo!(), // } todo!() } } pub struct SettingChangeCallback(FfiValueUntyped); impl Callback for SettingChangeCallback { type CallbackFunc = unsafe extern "C" fn( &PluginState, object: FfiValueRef, setting_name: &str, new_setting: Setting, ); } pub trait IntoSettingChangeCallback { unsafe extern "C" fn setting_changed( state: &PluginState, object: FfiValueRef, setting_name: &str, new_setting: Setting, ); } impl IntoSettingChangeCallback for F { unsafe extern "C" fn setting_changed( _state: &PluginState, _object: FfiValueRef, _setting_name: &str, _new_setting: Setting, ) { todo!() } } // impl SettingChangeCallback { // pub fn new>() -> Self { // Self { // func: T::setting_changed, // } // } // }