insanity
parent: tbd commit: 6ea28ab
Showing 29 changed files with 801 insertions and 542 deletions
Cargo.lock
@@ -688,6 +688,7 @@ dependencies = [ | ||
688 | 688 | name = "giterated-abi" |
689 | 689 | version = "0.1.0" |
690 | 690 | dependencies = [ |
691 | "anyhow", | |
691 | 692 | "giterated-models", |
692 | 693 | ] |
693 | 694 |
giterated-abi/Cargo.toml
@@ -6,4 +6,5 @@ edition = "2021" | ||
6 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
7 | 7 | |
8 | 8 | [dependencies] |
9 | giterated-models = { path = "../giterated-models"} | |
9 | \ No newline at end of file | |
9 | giterated-models = { path = "../giterated-models"} | |
10 | anyhow = "1" |
giterated-abi/src/callback/mod.rs
@@ -0,0 +1,27 @@ | ||
1 | pub mod operation; | |
2 | pub mod setting; | |
3 | pub mod value; | |
4 | ||
5 | use std::marker::PhantomData; | |
6 | ||
7 | pub trait Callback { | |
8 | type CallbackFunc; | |
9 | } | |
10 | ||
11 | #[derive(Copy, Clone)] | |
12 | #[repr(C)] | |
13 | pub struct CallbackPtr<T: Callback> { | |
14 | callback_ptr: *const (), | |
15 | func: T::CallbackFunc, | |
16 | _marker: PhantomData<T>, | |
17 | } | |
18 | ||
19 | impl<T: Callback> CallbackPtr<T> { | |
20 | pub unsafe fn from_raw(data: T, func: T::CallbackFunc) -> Self { | |
21 | todo!() | |
22 | } | |
23 | ||
24 | pub fn func(&self) -> &T::CallbackFunc { | |
25 | &self.func | |
26 | } | |
27 | } |
giterated-abi/src/callback/operation.rs
@@ -0,0 +1,140 @@ | ||
1 | use std::future::Future; | |
2 | ||
3 | use giterated_models::{ | |
4 | error::OperationError, object::GiteratedObject, operation::GiteratedOperation, | |
5 | }; | |
6 | ||
7 | use crate::{ | |
8 | result::FfiResult, | |
9 | state::State, | |
10 | value_ex::FfiValueUntyped, | |
11 | vtable::{operation::Operation, Object}, | |
12 | FfiFuture, FfiValueMut, FfiValueRef, | |
13 | }; | |
14 | ||
15 | use super::{Callback, CallbackPtr}; | |
16 | ||
17 | use std::fmt::Debug; | |
18 | ||
19 | pub struct OperationHandlerCallback(FfiValueUntyped); | |
20 | ||
21 | impl Callback for OperationHandlerCallback { | |
22 | type CallbackFunc = unsafe extern "C" fn( | |
23 | CallbackPtr<OperationHandlerCallback>, | |
24 | state: FfiValueMut<State>, | |
25 | object: FfiValueRef<Object>, | |
26 | operation: FfiValueRef<Operation>, | |
27 | ) -> FfiFuture< | |
28 | FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>, | |
29 | >; | |
30 | } | |
31 | ||
32 | pub trait IntoPluginOperationHandler<O: GiteratedObject, D: GiteratedOperation<O>, A> { | |
33 | unsafe extern "C" fn handle( | |
34 | callback_ptr: CallbackPtr<OperationHandlerCallback>, | |
35 | state: FfiValueMut<State>, | |
36 | object: FfiValueRef<Object>, | |
37 | operation: FfiValueRef<Operation>, | |
38 | ) -> FfiFuture<FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>>; | |
39 | fn callback_ptr(&self) -> CallbackPtr<OperationHandlerCallback>; | |
40 | } | |
41 | ||
42 | impl<F, O, D, Fut> IntoPluginOperationHandler<O, D, ()> for F | |
43 | where | |
44 | Fut: Future<Output = Result<D::Success, OperationError<D::Failure>>> + Send + Sync, | |
45 | F: Fn(O, D) -> Fut + Send + Sync + 'static, | |
46 | O: Debug + GiteratedObject + 'static, | |
47 | D: Debug + GiteratedOperation<O> + 'static, | |
48 | { | |
49 | unsafe extern "C" fn handle( | |
50 | callback: CallbackPtr<OperationHandlerCallback>, | |
51 | state: FfiValueMut<State>, | |
52 | object: FfiValueRef<Object>, | |
53 | operation: FfiValueRef<Operation>, | |
54 | ) -> FfiFuture<FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>> { | |
55 | todo!() | |
56 | // let _guard = trace_span!( | |
57 | // "operation handler", | |
58 | // object = type_name::<O>(), | |
59 | // operation = type_name::<D>() | |
60 | // ) | |
61 | // .entered(); | |
62 | // let state = unsafe { state.transmute_ref::<S>() }; | |
63 | ||
64 | // // Since this is Rust code, we know that the AnyObject and AnyOperation are just boxes | |
65 | // let object = unsafe { object.transmute_owned::<O>() }; | |
66 | // let operation = unsafe { operation.transmute_owned::<D>() }; | |
67 | ||
68 | // // Cast the callback ptr to ourselves | |
69 | // let callback: *const F = std::mem::transmute(callback.0); | |
70 | // let callback = callback.as_ref().unwrap(); | |
71 | ||
72 | // let state = state.clone(); | |
73 | // runtime_state.spawn_future(async move { | |
74 | // let result = callback(state, *object, *operation).await; | |
75 | ||
76 | // match result { | |
77 | // Ok(success) => unsafe { | |
78 | // todo!() | |
79 | // // Ok(AnySuccess::from_raw( | |
80 | // // FFIBox::from_box(Box::new(success)).untyped(), | |
81 | // // OperationVTable::new::<O, D>(), | |
82 | // // )) | |
83 | // }, | |
84 | // Err(err) => match err { | |
85 | // OperationError::Operation(_) => todo!(), | |
86 | // OperationError::Internal(_) => todo!(), | |
87 | // OperationError::Unhandled => todo!(), | |
88 | // }, | |
89 | // } | |
90 | // }) | |
91 | } | |
92 | ||
93 | fn callback_ptr(&self) -> CallbackPtr<OperationHandlerCallback> { | |
94 | // unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } | |
95 | ||
96 | todo!() | |
97 | } | |
98 | } | |
99 | ||
100 | impl<F, O, D, Fut, A1> IntoPluginOperationHandler<O, D, (A1,)> for F | |
101 | where | |
102 | Fut: Future<Output = Result<D::Success, OperationError<D::Failure>>>, | |
103 | F: Fn(O, D, A1) -> Fut, | |
104 | O: Debug + GiteratedObject, | |
105 | D: Debug + GiteratedOperation<O>, | |
106 | { | |
107 | unsafe extern "C" fn handle( | |
108 | _callback_ptr: CallbackPtr<OperationHandlerCallback>, | |
109 | state: FfiValueMut<State>, | |
110 | object: FfiValueRef<Object>, | |
111 | operation: FfiValueRef<Operation>, | |
112 | ) -> FfiFuture<FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>> { | |
113 | todo!() | |
114 | } | |
115 | ||
116 | fn callback_ptr(&self) -> CallbackPtr<OperationHandlerCallback> { | |
117 | todo!() | |
118 | } | |
119 | } | |
120 | ||
121 | impl<F, O, D, Fut, A1, A2> IntoPluginOperationHandler<O, D, (A1, A2)> for F | |
122 | where | |
123 | Fut: Future<Output = Result<D::Success, OperationError<D::Failure>>>, | |
124 | F: Fn(O, D, A1, A2) -> Fut, | |
125 | O: Debug + GiteratedObject, | |
126 | D: Debug + GiteratedOperation<O>, | |
127 | { | |
128 | unsafe extern "C" fn handle( | |
129 | _callback_ptr: CallbackPtr<OperationHandlerCallback>, | |
130 | state: FfiValueMut<State>, | |
131 | object: FfiValueRef<Object>, | |
132 | operation: FfiValueRef<Operation>, | |
133 | ) -> FfiFuture<FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>> { | |
134 | todo!() | |
135 | } | |
136 | ||
137 | fn callback_ptr(&self) -> CallbackPtr<OperationHandlerCallback> { | |
138 | todo!() | |
139 | } | |
140 | } |
giterated-abi/src/callback/setting.rs
@@ -0,0 +1,161 @@ | ||
1 | use std::future::Future; | |
2 | ||
3 | use giterated_models::{error::OperationError, object::GiteratedObject}; | |
4 | ||
5 | use crate::{ | |
6 | state::State, | |
7 | value_ex::FfiValueUntyped, | |
8 | vtable::{Object, Setting}, | |
9 | FfiFuture, FfiValueMut, FfiValueRef, | |
10 | }; | |
11 | ||
12 | use super::{Callback, CallbackPtr}; | |
13 | ||
14 | pub struct SettingGetterCallback(FfiValueUntyped); | |
15 | ||
16 | impl Callback for SettingGetterCallback { | |
17 | type CallbackFunc = unsafe extern "C" fn( | |
18 | CallbackPtr<SettingGetterCallback>, | |
19 | state: FfiValueMut<State>, | |
20 | object: FfiValueRef<Object>, | |
21 | ) -> FfiFuture<Result<Setting, ()>>; | |
22 | } | |
23 | ||
24 | pub trait IntoPluginSettingGetter<O, OS> { | |
25 | unsafe extern "C" fn get_setting( | |
26 | callback_ptr: CallbackPtr<SettingGetterCallback>, | |
27 | state: FfiValueMut<State>, | |
28 | object: FfiValueRef<Object>, | |
29 | ) -> FfiFuture<Result<Setting, ()>>; | |
30 | ||
31 | fn callback_ptr(&self) -> CallbackPtr<SettingGetterCallback> { | |
32 | // unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } | |
33 | todo!() | |
34 | } | |
35 | } | |
36 | ||
37 | impl<F, O, OS, Fut> IntoPluginSettingGetter<O, OS> for F | |
38 | where | |
39 | Fut: Future<Output = Result<OS, OperationError<anyhow::Error>>> + Send + Sync + 'static, | |
40 | O: GiteratedObject + Send + Sync + 'static, | |
41 | OS: giterated_models::settings::Setting + Send + Sync + 'static, | |
42 | F: Fn(O) -> Fut + Send + Sync + 'static, | |
43 | { | |
44 | unsafe extern "C" fn get_setting( | |
45 | callback: CallbackPtr<SettingGetterCallback>, | |
46 | state: FfiValueMut<State>, | |
47 | mut object: FfiValueRef<Object>, | |
48 | ) -> FfiFuture<Result<Setting, ()>> { | |
49 | // let _guard = trace_span!( | |
50 | // "get_setting handler", | |
51 | // object = O::object_name(), | |
52 | // setting = OS::name() | |
53 | // ) | |
54 | // .entered(); | |
55 | // let state = unsafe { state.transmute_ref::<S>() }; | |
56 | ||
57 | // let object = unsafe { object.transmute_owned::<O>() }; | |
58 | ||
59 | // // Cast the callback ptr to ourselves | |
60 | // let callback: *const F = std::mem::transmute(callback.0); | |
61 | // let callback = callback.as_ref().unwrap(); | |
62 | ||
63 | // let state = state.clone(); | |
64 | // runtime_state.spawn_future(async move { | |
65 | // let result = callback(state, *object).await; | |
66 | ||
67 | // match result { | |
68 | // Ok(success) => unsafe { Ok(NewAnySetting::new(success)) }, | |
69 | // Err(err) => match err { | |
70 | // OperationError::Operation(_) => todo!(), | |
71 | // OperationError::Internal(_) => todo!(), | |
72 | // OperationError::Unhandled => todo!(), | |
73 | // }, | |
74 | // } | |
75 | ||
76 | todo!() | |
77 | // }) | |
78 | } | |
79 | } | |
80 | ||
81 | pub trait IntoPluginSettingSetter<O, OS> { | |
82 | unsafe extern "C" fn set_setting( | |
83 | callback_ptr: CallbackPtr<SettingGetterCallback>, | |
84 | state: FfiValueMut<State>, | |
85 | object: FfiValueRef<Object>, | |
86 | setting: Setting, | |
87 | ) -> FfiFuture<Result<(), ()>>; | |
88 | ||
89 | fn callback_ptr(&self) -> CallbackPtr<SettingGetterCallback> { | |
90 | // unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } | |
91 | todo!() | |
92 | } | |
93 | } | |
94 | ||
95 | impl<F, O, OS, Fut> IntoPluginSettingSetter<O, OS> for F | |
96 | where | |
97 | Fut: Future<Output = Result<(), OperationError<anyhow::Error>>>, | |
98 | O: GiteratedObject, | |
99 | OS: giterated_models::settings::Setting, | |
100 | F: Fn(O, OS) -> Fut, | |
101 | { | |
102 | unsafe extern "C" fn set_setting( | |
103 | callback: CallbackPtr<SettingGetterCallback>, | |
104 | state: FfiValueMut<State>, | |
105 | mut object: FfiValueRef<Object>, | |
106 | _setting: Setting, | |
107 | ) -> FfiFuture<Result<(), ()>> { | |
108 | // let _guard = trace_span!( | |
109 | // "get_setting handler", | |
110 | // object = O::object_name(), | |
111 | // setting = OS::name() | |
112 | // ) | |
113 | // .entered(); | |
114 | // let _state = unsafe { state.transmute_ref::<S>() }; | |
115 | ||
116 | // let _object = unsafe { object.transmute_owned::<O>() }; | |
117 | ||
118 | // // Cast the callback ptr to ourselves | |
119 | // let callback: *const F = std::mem::transmute(callback.0); | |
120 | // let _callback = callback.as_ref().unwrap(); | |
121 | ||
122 | // let result = callback(state.clone(), *object); | |
123 | ||
124 | // match result { | |
125 | // Ok(setting) => Ok(NewAnySetting::new(setting)), | |
126 | // Err(_) => todo!(), | |
127 | // } | |
128 | todo!() | |
129 | } | |
130 | } | |
131 | ||
132 | pub struct SettingChangeCallback(FfiValueUntyped); | |
133 | ||
134 | impl Callback for SettingChangeCallback { | |
135 | type CallbackFunc = unsafe extern "C" fn( | |
136 | state: FfiValueMut<State>, | |
137 | object: FfiValueRef<Object>, | |
138 | setting_name: &str, | |
139 | new_setting: Setting, | |
140 | ); | |
141 | } | |
142 | ||
143 | pub trait IntoSettingChangeCallback<S, O> { | |
144 | unsafe extern "C" fn setting_changed( | |
145 | state: FfiValueMut<State>, | |
146 | object: FfiValueRef<Object>, | |
147 | setting_name: &str, | |
148 | new_setting: Setting, | |
149 | ); | |
150 | } | |
151 | ||
152 | impl<F, S, O> IntoSettingChangeCallback<S, O> for F { | |
153 | unsafe extern "C" fn setting_changed( | |
154 | state: FfiValueMut<State>, | |
155 | _object: FfiValueRef<Object>, | |
156 | _setting_name: &str, | |
157 | _new_setting: Setting, | |
158 | ) { | |
159 | todo!() | |
160 | } | |
161 | } |
giterated-abi/src/callback/value.rs
@@ -0,0 +1,117 @@ | ||
1 | use std::future::Future; | |
2 | ||
3 | use giterated_models::{ | |
4 | error::OperationError, object::GiteratedObject, value::GiteratedObjectValue, | |
5 | }; | |
6 | ||
7 | use crate::{ | |
8 | result::{FfiError, FfiResult}, | |
9 | state::State, | |
10 | vtable::{Object, Value}, | |
11 | FfiFuture, FfiSliceRef, FfiValueMut, FfiValueRef, | |
12 | }; | |
13 | ||
14 | use super::{setting::SettingGetterCallback, Callback, CallbackPtr}; | |
15 | ||
16 | #[derive(Copy, Clone)] | |
17 | pub struct ValueGetterCallback(CallbackPtr<ValueGetterCallback>); | |
18 | ||
19 | impl Callback for ValueGetterCallback { | |
20 | type CallbackFunc = unsafe extern "C" fn( | |
21 | CallbackPtr<ValueGetterCallback>, | |
22 | state: FfiValueMut<State>, | |
23 | object: FfiValueRef<Object>, | |
24 | ) -> FfiFuture<FfiResult<Value, FfiError>>; | |
25 | } | |
26 | ||
27 | pub trait IntoPluginValueGetter<O, V> { | |
28 | unsafe extern "C" fn get_value( | |
29 | callback: CallbackPtr<SettingGetterCallback>, | |
30 | state: FfiValueMut<State>, | |
31 | object: FfiValueRef<Object>, | |
32 | ) -> FfiFuture<FfiResult<Value, FfiError>>; | |
33 | ||
34 | fn callback_ptr(&self) -> CallbackPtr<SettingGetterCallback>; | |
35 | } | |
36 | ||
37 | impl<F, O, V, Fut> IntoPluginValueGetter<O, V> for F | |
38 | where | |
39 | Fut: Future<Output = Result<V, OperationError<anyhow::Error>>> + Send + Sync, | |
40 | O: GiteratedObject + 'static, | |
41 | V: GiteratedObjectValue<Object = O> + Send + Sync + 'static, | |
42 | F: Fn(O) -> Fut + Send + Sync + 'static, | |
43 | { | |
44 | unsafe extern "C" fn get_value( | |
45 | callback: CallbackPtr<SettingGetterCallback>, | |
46 | state: FfiValueMut<State>, | |
47 | mut object: FfiValueRef<Object>, | |
48 | ) -> FfiFuture<FfiResult<Value, FfiError>> { | |
49 | // let _guard = trace_span!( | |
50 | // "get_value handler", | |
51 | // object = O::object_name(), | |
52 | // value = V::value_name() | |
53 | // ) | |
54 | // .entered(); | |
55 | // let state = unsafe { state.transmute_ref::<S>() }; | |
56 | ||
57 | // let object = unsafe { object.transmute_owned::<O>() }; | |
58 | ||
59 | // // Cast the callback ptr to ourselves | |
60 | // let callback: *const F = std::mem::transmute(callback.0); | |
61 | // let callback = callback.as_ref().unwrap(); | |
62 | ||
63 | // let state = state.clone(); | |
64 | // runtime_state.spawn_future(async move { | |
65 | // let result = callback(state, *object).await; | |
66 | ||
67 | // match result { | |
68 | // Ok(success) => unsafe { Ok(NewAnyValue::new(success)) }, | |
69 | // Err(err) => match err { | |
70 | // OperationError::Operation(_) => todo!(), | |
71 | // OperationError::Internal(_) => todo!(), | |
72 | // OperationError::Unhandled => todo!(), | |
73 | // }, | |
74 | // } | |
75 | // }) | |
76 | ||
77 | todo!() | |
78 | } | |
79 | ||
80 | fn callback_ptr(&self) -> CallbackPtr<SettingGetterCallback> { | |
81 | todo!() | |
82 | // unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } | |
83 | } | |
84 | } | |
85 | ||
86 | pub struct ValueChangeCallback(CallbackPtr<ValueChangeCallback>); | |
87 | ||
88 | impl Callback for ValueChangeCallback { | |
89 | type CallbackFunc = unsafe extern "C" fn( | |
90 | state: FfiValueMut<State>, | |
91 | object: FfiValueRef<Object>, | |
92 | value_name: FfiSliceRef<str>, | |
93 | new_value: Value, | |
94 | ) -> FfiFuture<()>; | |
95 | } | |
96 | ||
97 | pub trait IntoValueChangeCallback<S, O> { | |
98 | unsafe extern "C" fn value_changed( | |
99 | callback: CallbackPtr<ValueChangeCallback>, | |
100 | state: FfiValueMut<State>, | |
101 | object: FfiValueRef<Object>, | |
102 | value_name: FfiSliceRef<str>, | |
103 | new_value: Value, | |
104 | ) -> FfiFuture<()>; | |
105 | } | |
106 | ||
107 | impl<F, S, O> IntoValueChangeCallback<S, O> for F { | |
108 | unsafe extern "C" fn value_changed( | |
109 | callback: CallbackPtr<ValueChangeCallback>, | |
110 | state: FfiValueMut<State>, | |
111 | _object: FfiValueRef<Object>, | |
112 | _value_name: FfiSliceRef<str>, | |
113 | _new_value: Value, | |
114 | ) -> FfiFuture<()> { | |
115 | todo!() | |
116 | } | |
117 | } |
giterated-abi/src/future.rs
@@ -8,7 +8,7 @@ pub struct FfiFuture<Output> { | ||
8 | 8 | wake_fn: unsafe extern "C" fn(FfiValueMut<FfiFuture<()>>, FfiValueMut<()>), |
9 | 9 | |
10 | 10 | poll_state: FfiValue<()>, |
11 | waker_state: Option<FfiValue<()>>, | |
11 | pub waker_state: Option<FfiValue<()>>, | |
12 | 12 | |
13 | 13 | _output_marker: PhantomData<Output>, |
14 | 14 | } |
@@ -42,7 +42,7 @@ impl<Output> FfiFuture<Output> { | ||
42 | 42 | /// Very not in progress text :) |
43 | 43 | pub unsafe fn write_waker<WS>( |
44 | 44 | &mut self, |
45 | _wake_fn: unsafe extern "C" fn(FfiValueMut<FfiFuture<()>>, FfiValueMut<()>), | |
45 | _wake_fn: unsafe extern "C" fn(FfiValueMut<FfiFuture<()>>), | |
46 | 46 | _waker_state: WS, |
47 | 47 | ) { |
48 | 48 | todo!() |
giterated-abi/src/heap.rs
@@ -1,9 +1,26 @@ | ||
1 | use crate::FfiValue; | |
1 | use std::{mem::MaybeUninit, ptr::drop_in_place}; | |
2 | ||
3 | use crate::{abi_backing::HeapValueBacking, FfiValue}; | |
2 | 4 | |
3 | 5 | pub trait HeapPlacable { |
4 | 6 | unsafe extern "C" fn free(value: FfiValue<Self>, taken: bool); |
5 | 7 | } |
6 | 8 | |
7 | 9 | impl<T> HeapPlacable for T { |
8 | unsafe extern "C" fn free(_value: FfiValue<Self>, _taken: bool) {} | |
10 | unsafe extern "C" fn free(value: FfiValue<Self>, taken: bool) { | |
11 | if !taken { | |
12 | drop(Box::from_raw(value.inner as *mut HeapValueBacking<T>)) | |
13 | } else { | |
14 | let allocation = Box::from_raw(value.inner as *mut T); | |
15 | ||
16 | // Since we "took" the value, kindly inform the compiler that it can't | |
17 | // treat the value like it exists | |
18 | let allocation_uninit: Box<HeapValueBacking<MaybeUninit<T>>> = | |
19 | unsafe { core::mem::transmute(allocation) }; | |
20 | ||
21 | // Since the compiler has no idea whether the value exists or not, it won't try and | |
22 | // drop it. Success! | |
23 | drop(allocation_uninit); | |
24 | } | |
25 | } | |
9 | 26 | } |
giterated-abi/src/lib.rs
@@ -86,10 +86,12 @@ mod future; | ||
86 | 86 | pub mod heap; |
87 | 87 | pub mod model_impl; |
88 | 88 | pub mod result; |
89 | pub mod state; | |
89 | 90 | pub mod vtable; |
90 | 91 | use abi_backing::{HeapValueBacking, SliceBacking}; |
91 | 92 | pub use future::{FfiFuture, RuntimeFuturePoll}; |
92 | 93 | use heap::HeapPlacable; |
94 | use prelude::value_ex::FfiValueUntyped; | |
93 | 95 | |
94 | 96 | use std::{ |
95 | 97 | marker::PhantomData, |
@@ -269,6 +271,10 @@ impl<T> FfiValue<T> { | ||
269 | 271 | } |
270 | 272 | } |
271 | 273 | |
274 | pub fn erase_type(self) -> FfiValueUntyped { | |
275 | unsafe { transmute(self) } | |
276 | } | |
277 | ||
272 | 278 | pub fn pin(&self) -> HeapPinnedValue<'_, T> { |
273 | 279 | unsafe { HeapPinnedValue::from_raw(self) } |
274 | 280 | } |
giterated-abi/src/model_impl/mod.rs
@@ -93,12 +93,12 @@ impl<T> IntoValueVTable for T { | ||
93 | 93 | } |
94 | 94 | } |
95 | 95 | |
96 | // impl<T> IntoSettingVTable for T { | |
97 | // unsafe extern "C" fn serialize(this: Setting) -> FfiResult<FfiSlice<[u8]>, FfiError> { | |
98 | // todo!() | |
99 | // } | |
100 | ||
101 | // unsafe extern "C" fn deserialize(buffer: FfiSliceRef<[u8]>) -> FfiResult<Setting, FfiError> { | |
102 | // todo!() | |
103 | // } | |
104 | // } | |
96 | impl<T> IntoSettingVTable for T { | |
97 | unsafe extern "C" fn serialize(this: Setting) -> FfiResult<FfiSlice<[u8]>, FfiError> { | |
98 | todo!() | |
99 | } | |
100 | ||
101 | unsafe extern "C" fn deserialize(buffer: FfiSliceRef<[u8]>) -> FfiResult<Setting, FfiError> { | |
102 | todo!() | |
103 | } | |
104 | } |
giterated-abi/src/state.rs
@@ -0,0 +1,136 @@ | ||
1 | use anyhow::Error; | |
2 | ||
3 | pub trait FromOperationState<O, D>: Sized { | |
4 | fn from_operation_state( | |
5 | state: &mut State, | |
6 | object: &O, | |
7 | operation: &D, | |
8 | ) -> Result<Self, OperationError<Error>>; | |
9 | } | |
10 | ||
11 | pub struct StateExtractor<T>(T); | |
12 | ||
13 | impl<T: FromState> FromState for StateExtractor<T> { | |
14 | fn from_state(state: &mut State) -> Result<Self, Error> { | |
15 | todo!() | |
16 | } | |
17 | } | |
18 | ||
19 | use giterated_models::error::OperationError; | |
20 | ||
21 | use crate::{ | |
22 | value_ex::FfiValueUntyped, | |
23 | vtable::{ObjectABI, VTable}, | |
24 | }; | |
25 | ||
26 | #[repr(transparent)] | |
27 | pub struct State { | |
28 | inner: StateHandle, | |
29 | } | |
30 | ||
31 | #[repr(transparent)] | |
32 | struct StateHandle { | |
33 | state: FfiValueUntyped, | |
34 | } | |
35 | ||
36 | #[repr(C)] | |
37 | struct StateItem<T: ?Sized> { | |
38 | /// The pointer to the next item. | |
39 | /// | |
40 | /// `next_item` is most likely always an `FfiValue<StateItem<()>>` and that's how we free them. | |
41 | next_item: *const StateItem<()>, | |
42 | pub state_uuid: u128, | |
43 | pub state: T, | |
44 | } | |
45 | ||
46 | impl Drop for State { | |
47 | fn drop(&mut self) { | |
48 | let state_manager = unsafe { StateManager::new(self) }; | |
49 | ||
50 | for state in state_manager {} | |
51 | } | |
52 | } | |
53 | ||
54 | struct StateManager<'s> { | |
55 | state: &'s mut State, | |
56 | last: Option<StateHandle>, | |
57 | } | |
58 | ||
59 | impl<'s> StateManager<'s> { | |
60 | pub unsafe fn new(handle: &'s mut State) -> Self { | |
61 | todo!() | |
62 | } | |
63 | ||
64 | pub unsafe fn write_state<S: StateUUID>(&mut self, state: S) -> Self { | |
65 | todo!() | |
66 | } | |
67 | ||
68 | pub unsafe fn get_state<S: StateUUID>(&mut self) -> Option<&S> { | |
69 | todo!() | |
70 | } | |
71 | } | |
72 | ||
73 | impl<'s> Iterator for StateManager<'s> { | |
74 | type Item = StateItem<()>; | |
75 | ||
76 | fn next(&mut self) -> Option<StateItem<()>> { | |
77 | todo!() | |
78 | } | |
79 | } | |
80 | ||
81 | pub trait StateUUID { | |
82 | fn uuid() -> u128; | |
83 | ||
84 | fn unsafe_hint_copy() -> Option<bool> { | |
85 | None | |
86 | } | |
87 | } | |
88 | ||
89 | /// State values for the current execution domain. 99.99% of the time this means "plugin-specific" | |
90 | /// | |
91 | /// The remainder 0.01% of the time it refers to the daemon's runtime domain. | |
92 | pub struct DomainState(StateItem<()>); | |
93 | ||
94 | impl StateUUID for DomainState { | |
95 | fn uuid() -> u128 { | |
96 | todo!() | |
97 | } | |
98 | } | |
99 | ||
100 | pub struct RuntimeState(StateItem<&'static VTable<Runtime>>); | |
101 | ||
102 | impl StateUUID for RuntimeState { | |
103 | fn uuid() -> u128 { | |
104 | todo!() | |
105 | } | |
106 | } | |
107 | ||
108 | impl RuntimeState { | |
109 | pub fn queue_insert_state<S: StateUUID>(&mut self, state: S) { | |
110 | todo!() | |
111 | } | |
112 | } | |
113 | ||
114 | pub struct Runtime { | |
115 | pub queue_insert_state: unsafe extern "C" fn(state_uuid: u128, state: FfiValueUntyped), | |
116 | } | |
117 | ||
118 | impl ObjectABI for Runtime { | |
119 | type VTable = Runtime; | |
120 | } | |
121 | ||
122 | pub trait FromState: Sized { | |
123 | fn from_state(state: &mut State) -> Result<Self, Error>; | |
124 | } | |
125 | ||
126 | impl<T: StateUUID> FromState for T { | |
127 | fn from_state(state: &mut State) -> Result<Self, Error> { | |
128 | todo!() | |
129 | } | |
130 | } | |
131 | ||
132 | impl<T: FromState> FromState for Option<T> { | |
133 | fn from_state(state: &mut State) -> Result<Self, Error> { | |
134 | todo!() | |
135 | } | |
136 | } |
giterated-abi/src/vtable/mod.rs
@@ -1,11 +1,12 @@ | ||
1 | 1 | use std::{marker::PhantomData, mem::transmute, ops::Deref}; |
2 | 2 | |
3 | mod object; | |
3 | pub mod object; | |
4 | 4 | pub mod operation; |
5 | pub mod plugin; | |
6 | pub mod plugin_initialization; | |
7 | pub mod runtime; | |
5 | 8 | mod setting; |
6 | 9 | mod value; |
7 | mod runtime; | |
8 | mod plugin_initialization; | |
9 | 10 | |
10 | 11 | pub use object::*; |
11 | 12 | pub use setting::*; |
giterated-abi/src/vtable/plugin.rs
@@ -0,0 +1,24 @@ | ||
1 | use crate::value_ex::FfiValueRefUntyped; | |
2 | ||
3 | use super::ObjectABI; | |
4 | ||
5 | pub struct Plugin {} | |
6 | ||
7 | impl ObjectABI for Plugin { | |
8 | type VTable = PluginVTable; | |
9 | } | |
10 | ||
11 | pub struct PluginVTable { | |
12 | pub plugin_name: unsafe extern "C" fn() -> &'static str, | |
13 | pub type_metadata: unsafe extern "C" fn() -> FfiValueRefUntyped, | |
14 | } | |
15 | ||
16 | impl PluginVTable { | |
17 | pub fn plugin_name(&self) -> &'static str { | |
18 | todo!() | |
19 | } | |
20 | ||
21 | pub fn type_metadata(&self) -> FfiValueRefUntyped { | |
22 | todo!() | |
23 | } | |
24 | } |
giterated-abi/src/vtable/plugin_initialization.rs
@@ -1,61 +1,65 @@ | ||
1 | use crate::{ | |
2 | callback::{ | |
3 | operation::OperationHandlerCallback, setting::SettingGetterCallback, | |
4 | value::ValueGetterCallback, CallbackPtr, | |
5 | }, | |
6 | FfiValueMut, | |
7 | }; | |
8 | ||
9 | use super::{operation::Operation, Object, ObjectABI, Setting, VTable, Value}; | |
10 | ||
1 | 11 | #[repr(C)] |
2 | 12 | pub struct HostVTable {} |
3 | 13 | |
4 | 14 | #[repr(C)] |
5 | 15 | #[derive(Clone, Copy)] |
6 | pub struct Initialization { | |
16 | pub struct InitializationVTable { | |
7 | 17 | pub register_object: |
8 | unsafe extern "C" fn(*mut PluginInitializationState, &'static str, &'static VTable<Object>), | |
18 | unsafe extern "C" fn(state: FfiValueMut<()>, &'static str, &'static VTable<Object>), | |
9 | 19 | pub register_operation: unsafe extern "C" fn( |
10 | *mut PluginInitializationState, | |
20 | state: FfiValueMut<()>, | |
11 | 21 | &'static str, |
12 | 22 | &'static str, |
13 | 23 | &'static VTable<Operation>, |
14 | 24 | ), |
15 | 25 | pub register_setting: unsafe extern "C" fn( |
16 | *mut PluginInitializationState, | |
26 | state: FfiValueMut<()>, | |
17 | 27 | &'static str, |
18 | 28 | &'static str, |
19 | 29 | &'static VTable<Setting>, |
20 | 30 | ), |
21 | 31 | pub register_value: unsafe extern "C" fn( |
22 | *mut PluginInitializationState, | |
32 | state: FfiValueMut<()>, | |
23 | 33 | &'static str, |
24 | 34 | &'static str, |
25 | 35 | &'static VTable<Value>, |
26 | 36 | ), |
27 | 37 | |
28 | 38 | pub operation_handler: unsafe extern "C" fn( |
29 | *mut PluginInitializationState, | |
39 | state: FfiValueMut<()>, | |
30 | 40 | &'static str, |
31 | 41 | &'static str, |
32 | 42 | CallbackPtr<OperationHandlerCallback>, |
33 | 43 | ), |
34 | 44 | |
35 | 45 | pub value_getter: unsafe extern "C" fn( |
36 | *mut PluginInitializationState, | |
46 | state: FfiValueMut<()>, | |
37 | 47 | &'static str, |
38 | 48 | &'static str, |
39 | 49 | CallbackPtr<ValueGetterCallback>, |
40 | 50 | ), |
41 | 51 | |
42 | 52 | pub setting_getter: unsafe extern "C" fn( |
43 | *mut PluginInitializationState, | |
53 | state: FfiValueMut<()>, | |
44 | 54 | &'static str, |
45 | 55 | &'static str, |
46 | 56 | CallbackPtr<SettingGetterCallback>, |
47 | 57 | ), |
48 | 58 | } |
49 | 59 | |
50 | impl ObjectABI for Initialization { | |
51 | type VTable = Initialization; | |
52 | } | |
53 | ||
54 | impl Debug for Initialization { | |
55 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
56 | f.debug_struct("InitializationVTable").finish() | |
57 | } | |
60 | impl ObjectABI for InitializationVTable { | |
61 | type VTable = InitializationVTable; | |
58 | 62 | } |
59 | 63 | |
60 | unsafe impl Sync for Initialization {} | |
61 | unsafe impl Send for Initialization {} | |
64 | unsafe impl Sync for InitializationVTable {} | |
65 | unsafe impl Send for InitializationVTable {} |
giterated-abi/src/vtable/runtime.rs
@@ -1,37 +1,35 @@ | ||
1 | use giterated_abi::{ | |
1 | use giterated_models::{error::OperationError, object::ObjectRequestError}; | |
2 | ||
3 | use crate::{ | |
2 | 4 | result::{FfiError, FfiResult}, |
5 | state::State, | |
3 | 6 | value_ex::FfiValueUntyped, |
4 | vtable::Object, | |
5 | FfiSliceRef, | |
6 | }; | |
7 | use giterated_models::{ | |
8 | error::OperationError, object::ObjectRequestError, operation::OperationState, | |
7 | FfiFuture, FfiSliceRef, FfiValueMut, | |
9 | 8 | }; |
10 | 9 | |
11 | use crate::{ | |
12 | future::RuntimeFuture, | |
13 | new_stack::{PluginState, TypeMetadata}, | |
14 | }; | |
10 | use super::{Object, ObjectABI}; | |
11 | ||
12 | pub struct Runtime {} | |
13 | ||
14 | impl ObjectABI for Runtime { | |
15 | type VTable = RuntimeVTable; | |
16 | } | |
15 | 17 | |
16 | 18 | #[derive(Clone, Copy)] |
17 | 19 | pub struct RuntimeVTable { |
18 | pub(crate) runtime: PluginState, | |
19 | pub(crate) type_metadata: *const TypeMetadata, | |
20 | 20 | pub(crate) handle_fn: unsafe extern "C" fn( |
21 | PluginState, | |
22 | 21 | FfiSliceRef<str>, |
23 | 22 | FfiSliceRef<str>, |
24 | 23 | FfiSliceRef<str>, |
25 | 24 | FfiSliceRef<[u8]>, |
26 | 25 | FfiSliceRef<[u8]>, |
27 | ) -> RuntimeFuture< | |
26 | ) -> FfiFuture< | |
28 | 27 | FfiResult<FfiValueUntyped, OperationError<FfiError>>, |
29 | 28 | >, |
30 | 29 | pub(crate) get_object: |
31 | 30 | unsafe extern "C" fn( |
32 | PluginState, | |
33 | 31 | &str, |
34 | *mut OperationState, | |
32 | state: FfiValueMut<State>, | |
35 | 33 | ) -> FfiResult<Object, OperationError<ObjectRequestError>>, |
36 | 34 | } |
37 | 35 | |
@@ -40,17 +38,15 @@ unsafe impl Sync for RuntimeVTable {} | ||
40 | 38 | |
41 | 39 | pub trait IntoRuntimeVtable { |
42 | 40 | unsafe extern "C" fn handle( |
43 | this: PluginState, | |
44 | 41 | object_kind: FfiSliceRef<str>, |
45 | 42 | operation_name: FfiSliceRef<str>, |
46 | 43 | object: FfiSliceRef<str>, |
47 | 44 | operation_payload: FfiSliceRef<[u8]>, |
48 | 45 | operation_state: FfiSliceRef<[u8]>, |
49 | ) -> RuntimeFuture<FfiResult<FfiValueUntyped, OperationError<FfiError>>>; | |
46 | ) -> FfiFuture<FfiResult<FfiValueUntyped, OperationError<FfiError>>>; | |
50 | 47 | |
51 | 48 | unsafe extern "C" fn get_object( |
52 | this: PluginState, | |
53 | 49 | object_str: &str, |
54 | operation_state: *mut OperationState, | |
50 | operation_state: FfiValueMut<State>, | |
55 | 51 | ) -> FfiResult<Object, OperationError<ObjectRequestError>>; |
56 | 52 | } |
giterated-abi/src/vtable/setting.rs
@@ -12,11 +12,11 @@ pub struct Setting { | ||
12 | 12 | vtable: &'static VTable<Setting>, |
13 | 13 | } |
14 | 14 | |
15 | impl<T: IntoSettingVTable> From<T> for Setting { | |
16 | fn from(value: T) -> Self { | |
17 | todo!() | |
18 | } | |
19 | } | |
15 | // impl<T: IntoSettingVTable> From<T> for Setting { | |
16 | // fn from(value: T) -> Self { | |
17 | // todo!() | |
18 | // } | |
19 | // } | |
20 | 20 | |
21 | 21 | impl ObjectABI for Setting { |
22 | 22 | type VTable = SettingVTable; |
giterated-core/src/lib.rs
@@ -1,4 +1,3 @@ | ||
1 | mod callback; | |
2 | 1 | mod state; |
3 | 2 | mod types; |
4 | 3 |
giterated-core/src/types/mod.rs
@@ -74,4 +74,3 @@ impl TypeMetadata { | ||
74 | 74 | ); |
75 | 75 | } |
76 | 76 | } |
77 |
giterated-macros/src/lib.rs
@@ -11,14 +11,18 @@ pub fn plugin(metadata: TokenStream) -> TokenStream { | ||
11 | 11 | |
12 | 12 | #[proc_macro_attribute] |
13 | 13 | pub fn plugin_init(attribute: TokenStream, item: TokenStream) -> TokenStream { |
14 | let mut input = parse_macro_input!(item as ItemFn); | |
14 | let input = parse_macro_input!(item as ItemFn); | |
15 | ||
16 | let func = input.sig.ident.clone(); | |
15 | 17 | |
16 | 18 | quote! { |
17 | 19 | #[doc(hidden)] |
18 | 20 | #[no_mangle] |
19 | 21 | unsafe extern "C" fn __plugin_init() { |
20 | #input.sig.ident() | |
22 | #func(&mut ::giterated_plugin::local::PluginStackBuilder::new()).unwrap() | |
21 | 23 | } |
24 | ||
25 | #input | |
22 | 26 | } |
23 | 27 | .into() |
24 | 28 | } |
@@ -27,13 +31,13 @@ fn emit_plugin_api() -> impl Into<TokenStream> { | ||
27 | 31 | quote! { |
28 | 32 | #[doc(hidden)] |
29 | 33 | #[no_mangle] |
30 | unsafe extern "C" fn __load_runtime_vtable(vtable: &'static ::giterated_abi::VTable<Runtime>) { | |
34 | unsafe extern "C" fn __load_runtime_vtable(vtable: &'static ::giterated_plugin::abi::vtable::VTable<::giterated_plugin::abi::vtable::runtime::Runtime>) { | |
31 | 35 | todo!() |
32 | 36 | } |
33 | 37 | |
34 | 38 | #[doc(hidden)] |
35 | 39 | #[no_mangle] |
36 | unsafe extern "C" fn __get_plugin_vtable() -> &'static ::giterated_abi::VTable<Plugin> { | |
40 | unsafe extern "C" fn __get_plugin_vtable() -> &'static ::giterated_plugin::abi::vtable::VTable<::giterated_plugin::abi::vtable::plugin::Plugin> { | |
37 | 41 | todo!() |
38 | 42 | } |
39 | 43 | } |
giterated-plugin/src/future.rs
@@ -1,25 +1,29 @@ | ||
1 | 1 | use futures_util::future::BoxFuture; |
2 | 2 | use futures_util::FutureExt; |
3 | use giterated_abi::{FfiFuture, FfiValue, FfiValueMut, RuntimeFuturePoll}; | |
3 | use giterated_abi::{ | |
4 | state::State, value_ex::FfiValueUntyped, FfiFuture, FfiValue, FfiValueMut, FfiValueRef, | |
5 | RuntimeFuturePoll, | |
6 | }; | |
4 | 7 | use std::{ |
5 | 8 | cell::UnsafeCell, |
6 | 9 | future::Future, |
7 | 10 | marker::PhantomData, |
8 | 11 | mem::transmute, |
12 | ops::Deref, | |
9 | 13 | task::{Context, RawWaker, RawWakerVTable, Waker}, |
10 | 14 | }; |
11 | 15 | |
12 | 16 | #[repr(C)] |
13 | 17 | pub struct RuntimeWakerCallback { |
14 | callback: PluginState, | |
15 | waker_func: unsafe extern "C" fn(PluginState), | |
18 | callback: FfiValueUntyped, | |
19 | waker_func: unsafe extern "C" fn(FfiValueUntyped), | |
16 | 20 | } |
17 | 21 | |
18 | 22 | pub struct WakerState { |
19 | 23 | waker: Waker, |
20 | 24 | } |
21 | 25 | |
22 | unsafe extern "C" fn wake(_waker: PluginState) {} | |
26 | unsafe extern "C" fn wake(_waker: FfiValueUntyped) {} | |
23 | 27 | |
24 | 28 | pub struct LocalRuntimeFuture<Output> { |
25 | 29 | inner: BoxFuture<'static, Output>, |
@@ -44,7 +48,7 @@ pub trait RuntimeFuturesExt { | ||
44 | 48 | ) -> RuntimeFuture<Output>; |
45 | 49 | } |
46 | 50 | |
47 | impl RuntimeFuturesExt for RuntimeState { | |
51 | impl RuntimeFuturesExt for State { | |
48 | 52 | fn spawn_future<Output, F: Future<Output = Output> + Send + Sync + 'static>( |
49 | 53 | &self, |
50 | 54 | future: F, |
@@ -132,8 +136,6 @@ impl<Output: Unpin> Future for RuntimeFuture<Output> { | ||
132 | 136 | waker: cx.waker().clone(), |
133 | 137 | }; |
134 | 138 | |
135 | let waker_state = PluginState::from(waker_state); | |
136 | ||
137 | 139 | unsafe { self.0.write_waker(wake_local, waker_state) }; |
138 | 140 | |
139 | 141 | match unsafe { self.0.poll() } { |
@@ -147,6 +149,11 @@ impl<Output: Unpin> Future for RuntimeFuture<Output> { | ||
147 | 149 | } |
148 | 150 | } |
149 | 151 | |
150 | unsafe extern "C" fn wake_local(future: FfiValueMut<FfiFuture<()>>, state: FfiValueMut<()>) { | |
151 | todo!() | |
152 | /// The function used to wake a local future over FFI | |
153 | unsafe extern "C" fn wake_local(future: FfiValueMut<FfiFuture<()>>) { | |
154 | if let Some(waker) = &future.waker_state { | |
155 | let waker: FfiValueRef<WakerState> = unsafe { transmute(waker.deref()) }; | |
156 | ||
157 | waker.waker.wake_by_ref(); | |
158 | } | |
152 | 159 | } |
giterated-plugin/src/lib.rs
@@ -1,6 +1,8 @@ | ||
1 | 1 | #![allow(improper_ctypes_definitions)] |
2 | 2 | |
3 | 3 | pub mod future; |
4 | pub mod local; | |
5 | pub use giterated_abi as abi; | |
4 | 6 | |
5 | 7 | #[macro_use] |
6 | 8 | extern crate tracing; |
giterated-plugin/src/local.rs
@@ -1,49 +1,46 @@ | ||
1 | mod local_runtime; | |
2 | ||
3 | 1 | use giterated_abi::{ |
4 | callback::{Callback, CallbackPtr}, | |
2 | callback::{ | |
3 | operation::IntoPluginOperationHandler, | |
4 | setting::{IntoPluginSettingGetter, IntoPluginSettingSetter}, | |
5 | value::IntoPluginValueGetter, | |
6 | Callback, CallbackPtr, | |
7 | }, | |
5 | 8 | result::FfiError, |
9 | state::{State, StateUUID}, | |
6 | 10 | value_ex::FfiValueUntyped, |
7 | 11 | vtable::{ |
8 | 12 | operation::{IntoOperationVTable, OperationVTable}, |
13 | plugin_initialization::InitializationVTable, | |
9 | 14 | IntoObjectVTable, IntoSettingVTable, IntoValueVTable, Object, ObjectVTable, SettingVTable, |
10 | 15 | VTable, ValueVTable, |
11 | 16 | }, |
12 | FfiValueRef, | |
17 | FfiValueMut, FfiValueRef, | |
13 | 18 | }; |
14 | 19 | use giterated_models::{ |
15 | 20 | object::GiteratedObject, operation::GiteratedOperation, settings::Setting, |
16 | 21 | value::GiteratedObjectValue, |
17 | 22 | }; |
18 | use giterated_plugin::{ | |
19 | callback::{ | |
20 | IntoPluginOperationHandler, IntoPluginSettingGetter, IntoPluginSettingSetter, | |
21 | IntoPluginValueGetter, OperationHandlerCallback, SettingGetterCallback, | |
22 | ValueGetterCallback, | |
23 | }, | |
24 | handle::PluginInitializationState, | |
25 | new_stack::PluginState, | |
26 | vtable::Initialization, | |
27 | }; | |
23 | ||
28 | 24 | use tracing::trace_span; |
29 | 25 | |
30 | pub struct PluginStackBuilder<S> { | |
31 | init_state: *mut PluginInitializationState, | |
32 | vtable: &'static VTable<Initialization>, | |
33 | state: S, | |
26 | pub struct PluginStackBuilder { | |
27 | init_state: FfiValueUntyped, | |
28 | vtable: &'static VTable<InitializationVTable>, | |
34 | 29 | } |
35 | 30 | |
36 | impl<S> PluginStackBuilder<S> { | |
37 | pub fn new( | |
38 | plugin_state: S, | |
39 | state: *mut PluginInitializationState, | |
40 | vtable: &'static VTable<Initialization>, | |
41 | ) -> PluginStackBuilder<S> { | |
42 | PluginStackBuilder { | |
43 | init_state: state, | |
44 | vtable, | |
45 | state: plugin_state, | |
46 | } | |
31 | impl PluginStackBuilder { | |
32 | pub fn new(// state: FfiValueUntyped, | |
33 | // vtable: &'static VTable<InitializationVTable>, | |
34 | ) -> PluginStackBuilder { | |
35 | todo!() | |
36 | // PluginStackBuilder { | |
37 | // init_state: state, | |
38 | // vtable | |
39 | // } | |
40 | } | |
41 | ||
42 | pub fn insert_state<S: StateUUID>(&mut self, state: S) -> &mut Self { | |
43 | todo!() | |
47 | 44 | } |
48 | 45 | |
49 | 46 | pub fn object<O: IntoObjectVTable + GiteratedObject>(&mut self) -> &mut Self { |
@@ -51,11 +48,13 @@ impl<S> PluginStackBuilder<S> { | ||
51 | 48 | |
52 | 49 | let func = self.vtable.register_object; |
53 | 50 | |
51 | let mut init_state = self.init_state.pin(); | |
52 | ||
54 | 53 | unsafe { |
55 | 54 | func( |
56 | self.init_state, | |
55 | unsafe { init_state.grant_mut() }, | |
57 | 56 | O::object_name(), |
58 | O::VTABLE | |
57 | O::VTABLE, | |
59 | 58 | ) |
60 | 59 | }; |
61 | 60 | |
@@ -69,9 +68,11 @@ impl<S> PluginStackBuilder<S> { | ||
69 | 68 | { |
70 | 69 | let _guard = trace_span!("register operation").entered(); |
71 | 70 | |
71 | let mut init_state = self.init_state.pin(); | |
72 | ||
72 | 73 | unsafe { |
73 | 74 | (self.vtable.register_operation)( |
74 | self.init_state, | |
75 | unsafe { init_state.grant_mut() }, | |
75 | 76 | O::object_name(), |
76 | 77 | D::operation_name(), |
77 | 78 | <D as IntoOperationVTable<O>>::VTABLE, |
@@ -85,14 +86,16 @@ impl<S> PluginStackBuilder<S> { | ||
85 | 86 | where |
86 | 87 | O: GiteratedObject, |
87 | 88 | OS: IntoSettingVTable + Setting, |
88 | HG: IntoPluginSettingGetter<S, O, OS>, | |
89 | HS: IntoPluginSettingSetter<S, O, OS>, | |
89 | HG: IntoPluginSettingGetter<O, OS>, | |
90 | HS: IntoPluginSettingSetter<O, OS>, | |
90 | 91 | { |
91 | 92 | let _guard = trace_span!("register setting").entered(); |
92 | 93 | |
94 | let mut init_state = self.init_state.pin(); | |
95 | ||
93 | 96 | unsafe { |
94 | 97 | (self.vtable.register_setting)( |
95 | self.init_state, | |
98 | unsafe { init_state.grant_mut() }, | |
96 | 99 | O::object_name(), |
97 | 100 | OS::name(), |
98 | 101 | OS::VTABLE, |
@@ -109,9 +112,11 @@ impl<S> PluginStackBuilder<S> { | ||
109 | 112 | { |
110 | 113 | let _guard = trace_span!("register setting").entered(); |
111 | 114 | |
115 | let mut init_state = self.init_state.pin(); | |
116 | ||
112 | 117 | unsafe { |
113 | 118 | (self.vtable.register_setting)( |
114 | self.init_state, | |
119 | unsafe { init_state.grant_mut() }, | |
115 | 120 | O::object_name(), |
116 | 121 | OS::name(), |
117 | 122 | OS::VTABLE, |
@@ -125,13 +130,15 @@ impl<S> PluginStackBuilder<S> { | ||
125 | 130 | where |
126 | 131 | O: GiteratedObject, |
127 | 132 | V: IntoValueVTable + GiteratedObjectValue<Object = O>, |
128 | T: IntoPluginValueGetter<S, O, V>, | |
133 | T: IntoPluginValueGetter<O, V>, | |
129 | 134 | { |
130 | 135 | let _guard = trace_span!("register value").entered(); |
131 | 136 | |
137 | let mut init_state = self.init_state.pin(); | |
138 | ||
132 | 139 | unsafe { |
133 | 140 | (self.vtable.register_value)( |
134 | self.init_state, | |
141 | unsafe { init_state.grant_mut() }, | |
135 | 142 | O::object_name(), |
136 | 143 | V::value_name(), |
137 | 144 | V::VTABLE, |
@@ -154,7 +161,7 @@ impl<S> PluginStackBuilder<S> { | ||
154 | 161 | A, |
155 | 162 | O: GiteratedObject + IntoObjectVTable, |
156 | 163 | D: IntoOperationVTable<O> + GiteratedOperation<O>, |
157 | T: IntoPluginOperationHandler<S, O, D, A>, | |
164 | T: IntoPluginOperationHandler<O, D, A>, | |
158 | 165 | >( |
159 | 166 | &mut self, |
160 | 167 | handler: T, |
@@ -206,7 +213,7 @@ impl<S> PluginStackBuilder<S> { | ||
206 | 213 | where |
207 | 214 | O: GiteratedObject + IntoObjectVTable, |
208 | 215 | OS: Setting + IntoSettingVTable, |
209 | T: IntoPluginSettingGetter<S, O, OS>, | |
216 | T: IntoPluginSettingGetter<O, OS>, | |
210 | 217 | { |
211 | 218 | let _guard = trace_span!("register setting_getter handler").entered(); |
212 | 219 | |
@@ -221,9 +228,11 @@ impl<S> PluginStackBuilder<S> { | ||
221 | 228 | |
222 | 229 | self.object::<O>(); |
223 | 230 | |
231 | let mut init_state = self.init_state.pin(); | |
232 | ||
224 | 233 | unsafe { |
225 | 234 | (self.vtable.register_setting)( |
226 | self.init_state, | |
235 | unsafe { init_state.grant_mut() }, | |
227 | 236 | O::object_name(), |
228 | 237 | OS::name(), |
229 | 238 | OS::VTABLE, |
@@ -234,22 +243,22 @@ impl<S> PluginStackBuilder<S> { | ||
234 | 243 | } |
235 | 244 | } |
236 | 245 | |
237 | pub trait ValueSettingExt<PS> { | |
246 | pub trait ValueSettingExt { | |
238 | 247 | fn value_setting<O, VS, HG, HS>(&mut self, get: HG, set: HS) -> &mut Self |
239 | 248 | where |
240 | 249 | O: GiteratedObject + IntoObjectVTable + 'static, |
241 | 250 | VS: GiteratedObjectValue<Object = O> + IntoValueVTable + Setting + IntoSettingVTable, |
242 | HG: IntoPluginSettingGetter<PS, O, VS>, | |
243 | HS: IntoPluginSettingSetter<PS, O, VS>; | |
251 | HG: IntoPluginSettingGetter<O, VS>, | |
252 | HS: IntoPluginSettingSetter<O, VS>; | |
244 | 253 | } |
245 | 254 | |
246 | impl<PS> ValueSettingExt<PS> for PluginStackBuilder<PS> { | |
255 | impl ValueSettingExt for PluginStackBuilder { | |
247 | 256 | fn value_setting<O, VS, HG, HS>(&mut self, _get: HG, _set: HS) -> &mut Self |
248 | 257 | where |
249 | 258 | O: GiteratedObject + IntoObjectVTable + 'static, |
250 | 259 | VS: GiteratedObjectValue<Object = O> + IntoValueVTable + Setting + IntoSettingVTable, |
251 | HG: IntoPluginSettingGetter<PS, O, VS>, | |
252 | HS: IntoPluginSettingSetter<PS, O, VS>, | |
260 | HG: IntoPluginSettingGetter<O, VS>, | |
261 | HS: IntoPluginSettingSetter<O, VS>, | |
253 | 262 | { |
254 | 263 | self |
255 | 264 | } |
@@ -261,30 +270,30 @@ pub struct ValueSettingGetterCallback; | ||
261 | 270 | impl Callback for ValueSettingGetterCallback { |
262 | 271 | type CallbackFunc = unsafe extern "C" fn( |
263 | 272 | callback: CallbackPtr<ValueSettingGetterCallback>, |
264 | state: &PluginState, | |
273 | state: FfiValueMut<State>, | |
265 | 274 | object: FfiValueRef<Object>, |
266 | 275 | ) -> Result<FfiValueUntyped, FfiError>; |
267 | 276 | } |
268 | 277 | |
269 | pub trait ValueSettingGetter<S, O, V> { | |
278 | pub trait ValueSettingGetter<O, V> { | |
270 | 279 | unsafe extern "C" fn get_value( |
271 | 280 | callback: CallbackPtr<ValueSettingGetterCallback>, |
272 | state: &PluginState, | |
281 | state: FfiValueMut<State>, | |
273 | 282 | object: FfiValueRef<Object>, |
274 | 283 | ) -> Result<FfiValueUntyped, FfiError>; |
275 | 284 | |
276 | 285 | fn callback_ptr(&self) -> CallbackPtr<ValueSettingGetterCallback>; |
277 | 286 | } |
278 | 287 | |
279 | impl<S, O, VS, HG> ValueSettingGetter<S, O, VS> for HG | |
288 | impl<O, VS, HG> ValueSettingGetter<O, VS> for HG | |
280 | 289 | where |
281 | 290 | O: GiteratedObject, |
282 | 291 | VS: GiteratedObjectValue<Object = O>, |
283 | HG: IntoPluginSettingGetter<S, O, VS>, | |
292 | HG: IntoPluginSettingGetter<O, VS>, | |
284 | 293 | { |
285 | 294 | unsafe extern "C" fn get_value( |
286 | 295 | _callback: CallbackPtr<ValueSettingGetterCallback>, |
287 | _state: &PluginState, | |
296 | _state: FfiValueMut<State>, | |
288 | 297 | _object: FfiValueRef<Object>, |
289 | 298 | ) -> Result<FfiValueUntyped, FfiError> { |
290 | 299 | // let result = HG::get_setting(callback, state, object)?; |
plugins/example-plugin/src/lib.rs
@@ -1,10 +1,15 @@ | ||
1 | 1 | use anyhow::Error; |
2 | 2 | use giterated_models::{ |
3 | 3 | error::OperationError, |
4 | instance::Instance, | |
4 | 5 | object::{ObjectRequest, ObjectRequestError, ObjectResponse}, |
5 | 6 | user::{DisplayName, User}, |
6 | 7 | }; |
7 | use giterated_plugin::{new_stack::State, plugin}; | |
8 | use giterated_plugin::{ | |
9 | abi::state::{StateExtractor, StateUUID}, | |
10 | local::PluginStackBuilder, | |
11 | plugin, | |
12 | }; | |
8 | 13 | |
9 | 14 | plugin!( |
10 | 15 | name: "Example Plugin", |
@@ -18,16 +23,23 @@ plugin!( | ||
18 | 23 | /// Some kind of global state for the plugin |
19 | 24 | struct PluginState; |
20 | 25 | |
26 | impl StateUUID for PluginState { | |
27 | fn uuid() -> u128 { | |
28 | 214829528589663836760123667646253464473 | |
29 | } | |
30 | } | |
31 | ||
21 | 32 | /// The plugin's initialization function. Ran when the plugin is loaded, used to |
22 | 33 | /// build the plugin's stack. |
23 | 34 | #[plugin::init] |
24 | 35 | pub fn init(builder: &mut PluginStackBuilder) -> Result<(), Error> { |
25 | builder.insert_state(State); | |
26 | ||
27 | builder.object::<Instance>().object::<User>(); | |
28 | ||
29 | builder.value(value_getter); | |
30 | builder.setting_getter(setting_getter); | |
36 | builder | |
37 | .insert_state(PluginState); | |
38 | builder | |
39 | .object::<Instance>() | |
40 | .object::<User>(); | |
41 | builder | |
42 | .setting_getter(setting_getter); | |
31 | 43 | |
32 | 44 | Ok(()) |
33 | 45 | } |
@@ -35,14 +47,14 @@ pub fn init(builder: &mut PluginStackBuilder) -> Result<(), Error> { | ||
35 | 47 | async fn handler( |
36 | 48 | object: User, |
37 | 49 | operation: ObjectRequest, |
38 | state_extractor: State<PluginState>, | |
50 | // state_extractor: StateExtractor<PluginState>, | |
39 | 51 | ) -> Result<ObjectResponse, OperationError<ObjectRequestError>> { |
40 | 52 | todo!() |
41 | 53 | } |
42 | 54 | |
43 | 55 | async fn setting_getter( |
44 | 56 | object: User, |
45 | state_extractor: State<PluginState>, | |
57 | // state_extractor: StateExtractor<PluginState>, | |
46 | 58 | ) -> Result<DisplayName, OperationError<Error>> { |
47 | 59 | todo!() |
48 | 60 | } |
plugins/example-plugin/src/main.rs
@@ -5,7 +5,7 @@ use giterated_models::{ | ||
5 | 5 | operation::OperationState, |
6 | 6 | user::{DisplayName, User}, |
7 | 7 | }; |
8 | use giterated_plugin::{callback::RuntimeState, handle::PluginHandle, new_stack::Runtime}; | |
8 | use giterated_plugin::abi::state::{Runtime, RuntimeState}; | |
9 | 9 | use tracing::{info, Level}; |
10 | 10 | |
11 | 11 | #[tokio::main] |