JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

More progress :)

Amber - ⁨1⁩ year ago

parent: tbd commit: ⁨92c3f32

⁨giterated-plugin/src/callback/value.rs⁩ - ⁨3620⁩ bytes
Raw
1 use std::future::Future;
2
3 use giterated_models::{
4 error::OperationError, object::GiteratedObject, value::GiteratedObjectValue,
5 };
6
7 use crate::{
8 future::{RuntimeFuture, RuntimeFuturesExt},
9 new_stack::PluginState,
10 vtable::{AnyObject, NewAnyValue},
11 };
12
13 use super::{CallbackPtr, RuntimeState};
14
15 #[derive(Copy, Clone)]
16 pub struct ValueGetterCallback {
17 pub callback_ptr: CallbackPtr,
18 pub func: unsafe extern "C" fn(
19 CallbackPtr,
20 runtime_state: &RuntimeState,
21 &PluginState,
22 object: AnyObject,
23 ) -> RuntimeFuture<Result<NewAnyValue, ()>>,
24 }
25
26 impl ValueGetterCallback {
27 pub fn new<S, O, V, T: IntoPluginValueGetter<S, O, V>>(handler: T) -> Self {
28 Self {
29 func: T::get_value,
30 callback_ptr: handler.callback_ptr(),
31 }
32 }
33 }
34
35 pub trait IntoPluginValueGetter<S, O, V> {
36 unsafe extern "C" fn get_value(
37 callback: CallbackPtr,
38 runtime_state: &RuntimeState,
39 state: &PluginState,
40 object: AnyObject,
41 ) -> RuntimeFuture<Result<NewAnyValue, ()>>;
42
43 fn callback_ptr(&self) -> CallbackPtr;
44 }
45
46 impl<F, S, O, V, Fut> IntoPluginValueGetter<S, O, V> for F
47 where
48 Fut: Future<Output = Result<V, OperationError<anyhow::Error>>> + Send + Sync,
49 S: Clone + Send + Sync + 'static,
50 O: GiteratedObject + 'static,
51 V: GiteratedObjectValue<Object = O> + Send + Sync + 'static,
52 F: Fn(S, O) -> Fut + Send + Sync + 'static,
53 {
54 unsafe extern "C" fn get_value(
55 callback: CallbackPtr,
56 runtime_state: &RuntimeState,
57 state: &PluginState,
58 mut object: AnyObject,
59 ) -> RuntimeFuture<Result<NewAnyValue, ()>> {
60 let _guard = trace_span!(
61 "get_value handler",
62 object = O::object_name(),
63 value = V::value_name()
64 )
65 .entered();
66 let state = unsafe { state.transmute_ref::<S>() };
67
68 let object = unsafe { object.transmute_owned::<O>() };
69
70 // Cast the callback ptr to ourselves
71 let callback: *const F = std::mem::transmute(callback.0);
72 let callback = callback.as_ref().unwrap();
73
74 let state = state.clone();
75 runtime_state.spawn_future(async move {
76 let result = callback(state, *object).await;
77
78 match result {
79 Ok(success) => unsafe { Ok(NewAnyValue::new(success)) },
80 Err(err) => match err {
81 OperationError::Operation(_) => todo!(),
82 OperationError::Internal(_) => todo!(),
83 OperationError::Unhandled => todo!(),
84 },
85 }
86 })
87 }
88
89 fn callback_ptr(&self) -> CallbackPtr {
90 unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) }
91 }
92 }
93
94 pub struct ValueChangeCallback {
95 func: unsafe extern "C" fn(
96 &PluginState,
97 object: AnyObject,
98 value_name: &str,
99 new_value: NewAnyValue,
100 ) -> RuntimeFuture<()>,
101 }
102
103 pub trait IntoValueChangeCallback<S, O> {
104 unsafe extern "C" fn value_changed(
105 state: &PluginState,
106 object: AnyObject,
107 value_name: &str,
108 new_value: NewAnyValue,
109 ) -> RuntimeFuture<()>;
110 }
111
112 impl<F, S, O> IntoValueChangeCallback<S, O> for F {
113 unsafe extern "C" fn value_changed(
114 _state: &PluginState,
115 _object: AnyObject,
116 _value_name: &str,
117 _new_value: NewAnyValue,
118 ) -> RuntimeFuture<()> {
119 todo!()
120 }
121 }
122
123 impl ValueChangeCallback {
124 pub fn new<S, O, T: IntoValueChangeCallback<S, O>>() -> Self {
125 Self {
126 func: T::value_changed,
127 }
128 }
129 }
130