Before
parent: tbd commit: e432306
Showing 45 changed files with 1526 insertions and 1435 deletions
Cargo.lock
@@ -688,6 +688,9 @@ dependencies = [ | ||
688 | 688 | [[package]] |
689 | 689 | name = "giterated-abi" |
690 | 690 | version = "0.1.0" |
691 | dependencies = [ | |
692 | "giterated-models", | |
693 | ] | |
691 | 694 | |
692 | 695 | [[package]] |
693 | 696 | name = "giterated-backend" |
@@ -708,6 +711,10 @@ dependencies = [ | ||
708 | 711 | ] |
709 | 712 | |
710 | 713 | [[package]] |
714 | name = "giterated-core" | |
715 | version = "0.1.0" | |
716 | ||
717 | [[package]] | |
711 | 718 | name = "giterated-daemon" |
712 | 719 | version = "0.1.0" |
713 | 720 | dependencies = [ |
@@ -762,6 +769,13 @@ dependencies = [ | ||
762 | 769 | ] |
763 | 770 | |
764 | 771 | [[package]] |
772 | name = "giterated-macros" | |
773 | version = "0.1.0" | |
774 | dependencies = [ | |
775 | "quote", | |
776 | ] | |
777 | ||
778 | [[package]] | |
765 | 779 | name = "giterated-models" |
766 | 780 | version = "0.1.0" |
767 | 781 | dependencies = [ |
@@ -794,6 +808,7 @@ dependencies = [ | ||
794 | 808 | "dlopen2", |
795 | 809 | "futures-util", |
796 | 810 | "giterated-abi", |
811 | "giterated-macros", | |
797 | 812 | "giterated-models", |
798 | 813 | "giterated-static-runtime", |
799 | 814 | "semver", |
@@ -808,6 +823,7 @@ dependencies = [ | ||
808 | 823 | name = "giterated-plugin-sys" |
809 | 824 | version = "0.1.0" |
810 | 825 | dependencies = [ |
826 | "giterated-abi", | |
811 | 827 | "giterated-models", |
812 | 828 | "giterated-plugin", |
813 | 829 | "tracing", |
@@ -837,6 +853,10 @@ dependencies = [ | ||
837 | 853 | ] |
838 | 854 | |
839 | 855 | [[package]] |
856 | name = "giterated-runtime" | |
857 | version = "0.1.0" | |
858 | ||
859 | [[package]] | |
840 | 860 | name = "giterated-static-runtime" |
841 | 861 | version = "0.1.0" |
842 | 862 |
Cargo.toml
@@ -1,10 +1,11 @@ | ||
1 | 1 | [workspace] |
2 | members = [ "giterated-abi", | |
2 | members = [ "giterated-abi", "giterated-core", | |
3 | 3 | "giterated-daemon", |
4 | 4 | "giterated-models", |
5 | 5 | "giterated-plugin", |
6 | "giterated-plugin/giterated-macros", | |
6 | 7 | "giterated-plugin/giterated-plugin-sys", |
7 | "giterated-plugin/giterated-static-runtime", | |
8 | "giterated-plugin/giterated-static-runtime", "giterated-runtime", | |
8 | 9 | "plugins/example-plugin", |
9 | 10 | "plugins/giterated-backend", |
10 | 11 | "plugins/giterated-issues", |
giterated-abi/Cargo.toml
@@ -6,3 +6,4 @@ 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 |
giterated-abi/src/callback.rs
@@ -0,0 +1,23 @@ | ||
1 | use std::marker::PhantomData; | |
2 | ||
3 | pub trait Callback { | |
4 | type CallbackFunc; | |
5 | } | |
6 | ||
7 | #[derive(Copy, Clone)] | |
8 | #[repr(C)] | |
9 | pub struct CallbackPtr<T: Callback> { | |
10 | callback_ptr: *const (), | |
11 | func: T::CallbackFunc, | |
12 | _marker: PhantomData<T>, | |
13 | } | |
14 | ||
15 | impl<T: Callback> CallbackPtr<T> { | |
16 | pub unsafe fn from_raw(data: T, func: T::CallbackFunc) -> Self { | |
17 | todo!() | |
18 | } | |
19 | ||
20 | pub fn func(&self) -> &T::CallbackFunc { | |
21 | &self.func | |
22 | } | |
23 | } |
giterated-abi/src/lib.rs
@@ -81,8 +81,10 @@ | ||
81 | 81 | //! |
82 | 82 | //! `RuntimeFuture`s drop the associated inner future as they drop. |
83 | 83 | |
84 | pub mod callback; | |
84 | 85 | mod future; |
85 | mod heap; | |
86 | pub mod heap; | |
87 | pub mod model_impl; | |
86 | 88 | pub mod result; |
87 | 89 | pub mod vtable; |
88 | 90 | use abi_backing::{HeapValueBacking, SliceBacking}; |
@@ -102,6 +104,7 @@ use guards::{HeapPinnedSlice, HeapPinnedValue, StackPinnedSlice, StackPinnedValu | ||
102 | 104 | pub mod prelude { |
103 | 105 | pub use crate::Ffi; |
104 | 106 | pub use crate::StackPinned; |
107 | pub use crate::*; | |
105 | 108 | pub use crate::{FfiSlice, FfiSliceRef, FfiValue, FfiValueRef}; |
106 | 109 | } |
107 | 110 |
giterated-abi/src/model_impl/mod.rs
@@ -0,0 +1,104 @@ | ||
1 | use std::ffi::CStr; | |
2 | ||
3 | use giterated_models::{object::GiteratedObject, operation::GiteratedOperation}; | |
4 | ||
5 | use crate::{ | |
6 | result::{FfiError, FfiResult}, | |
7 | value_ex::{FfiValueRefUntyped, FfiValueUntyped}, | |
8 | vtable::{ | |
9 | operation::{IntoOperationVTable, Operation}, | |
10 | IntoObjectVTable, IntoSettingVTable, IntoValueVTable, Object, Setting, | |
11 | }, | |
12 | FfiSlice, FfiSliceRef, FfiValueRef, | |
13 | }; | |
14 | ||
15 | impl<T> IntoObjectVTable for T | |
16 | where | |
17 | T: GiteratedObject, | |
18 | { | |
19 | fn object_kind() -> &'static CStr { | |
20 | todo!() | |
21 | } | |
22 | ||
23 | unsafe extern "C" fn to_str(this: FfiValueRef<Object>) -> FfiSlice<str> { | |
24 | todo!() | |
25 | } | |
26 | ||
27 | unsafe extern "C" fn from_str(from: FfiSliceRef<str>) -> FfiResult<Object, FfiError> { | |
28 | todo!() | |
29 | } | |
30 | ||
31 | unsafe extern "C" fn home_uri(this: FfiValueRef<Object>) -> FfiSlice<str> { | |
32 | todo!() | |
33 | } | |
34 | } | |
35 | ||
36 | impl<T, O> IntoOperationVTable<O> for T | |
37 | where | |
38 | T: GiteratedOperation<O>, | |
39 | O: GiteratedObject, | |
40 | { | |
41 | fn operation_kind() -> &'static CStr { | |
42 | todo!() | |
43 | } | |
44 | ||
45 | unsafe extern "C" fn operation_serialize( | |
46 | this: FfiValueRef<Operation>, | |
47 | ) -> FfiResult<FfiSlice<[u8]>, FfiError> { | |
48 | todo!() | |
49 | } | |
50 | ||
51 | unsafe extern "C" fn operation_deserialize( | |
52 | buffer: FfiSliceRef<[u8]>, | |
53 | ) -> FfiResult<Operation, FfiError> { | |
54 | todo!() | |
55 | } | |
56 | ||
57 | unsafe extern "C" fn success_serialize( | |
58 | success: FfiValueRefUntyped, | |
59 | ) -> FfiResult<FfiSlice<[u8]>, FfiError> { | |
60 | todo!() | |
61 | } | |
62 | ||
63 | unsafe extern "C" fn success_deserialize( | |
64 | buffer: FfiSliceRef<[u8]>, | |
65 | ) -> FfiResult<FfiValueUntyped, FfiError> { | |
66 | todo!() | |
67 | } | |
68 | ||
69 | unsafe extern "C" fn failure_serialize( | |
70 | failure: FfiValueRefUntyped, | |
71 | ) -> FfiResult<FfiSlice<[u8]>, FfiError> { | |
72 | todo!() | |
73 | } | |
74 | ||
75 | unsafe extern "C" fn failure_deserialize( | |
76 | buffer: FfiSliceRef<[u8]>, | |
77 | ) -> FfiResult<FfiValueUntyped, FfiError> { | |
78 | todo!() | |
79 | } | |
80 | } | |
81 | ||
82 | impl<T> IntoValueVTable for T { | |
83 | unsafe extern "C" fn serialize( | |
84 | buffer: FfiSliceRef<[u8]>, | |
85 | ) -> FfiResult<crate::vtable::Value, FfiError> { | |
86 | todo!() | |
87 | } | |
88 | ||
89 | unsafe extern "C" fn deserialize( | |
90 | this: crate::vtable::Value, | |
91 | ) -> FfiResult<FfiSlice<[u8]>, FfiError> { | |
92 | todo!() | |
93 | } | |
94 | } | |
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 | // } |
giterated-abi/src/result.rs
@@ -1,12 +1,12 @@ | ||
1 | 1 | use crate::FfiSlice; |
2 | 2 | |
3 | 3 | #[repr(C)] |
4 | pub enum Result<T, E> { | |
4 | pub enum FfiResult<T, E> { | |
5 | 5 | Ok(T), |
6 | 6 | Err(E), |
7 | 7 | } |
8 | 8 | |
9 | 9 | #[repr(C)] |
10 | pub struct Error { | |
10 | pub struct FfiError { | |
11 | 11 | last_error: FfiSlice<str>, |
12 | 12 | } |
giterated-abi/src/vtable/mod.rs
@@ -1,6 +1,4 @@ | ||
1 | use std::{ | |
2 | marker::PhantomData, mem::transmute, ops::Deref | |
3 | }; | |
1 | use std::{marker::PhantomData, mem::transmute, ops::Deref}; | |
4 | 2 | |
5 | 3 | mod object; |
6 | 4 | pub mod operation; |
giterated-abi/src/vtable/object.rs
@@ -1,7 +1,8 @@ | ||
1 | use std::ffi::CStr; | |
1 | use std::{ffi::CStr, str::FromStr}; | |
2 | 2 | |
3 | 3 | use crate::{ |
4 | result::{Error, Result}, | |
4 | result::{FfiError, FfiResult}, | |
5 | value_ex::FfiValueUntyped, | |
5 | 6 | FfiSlice, FfiSliceRef, FfiValueRef, |
6 | 7 | }; |
7 | 8 | |
@@ -9,10 +10,36 @@ use super::{ObjectABI, VTable}; | ||
9 | 10 | |
10 | 11 | #[repr(C)] |
11 | 12 | pub struct Object { |
12 | inner: (), | |
13 | inner: FfiValueUntyped, | |
13 | 14 | vtable: &'static VTable<Object>, |
14 | 15 | } |
15 | 16 | |
17 | impl Object { | |
18 | pub fn home_uri(&self) -> String { | |
19 | todo!() | |
20 | } | |
21 | } | |
22 | ||
23 | impl<O: IntoObjectVTable> From<O> for Object { | |
24 | fn from(value: O) -> Self { | |
25 | todo!() | |
26 | } | |
27 | } | |
28 | ||
29 | impl ToString for Object { | |
30 | fn to_string(&self) -> String { | |
31 | todo!() | |
32 | } | |
33 | } | |
34 | ||
35 | impl FromStr for Object { | |
36 | type Err = FfiError; | |
37 | ||
38 | fn from_str(s: &str) -> Result<Self, Self::Err> { | |
39 | todo!() | |
40 | } | |
41 | } | |
42 | ||
16 | 43 | impl ObjectABI for Object { |
17 | 44 | type VTable = ObjectVTable; |
18 | 45 | } |
@@ -20,19 +47,21 @@ impl ObjectABI for Object { | ||
20 | 47 | pub struct ObjectVTable { |
21 | 48 | pub object_kind: &'static CStr, |
22 | 49 | pub to_str: unsafe extern "C" fn(this: FfiValueRef<Object>) -> FfiSlice<str>, |
23 | pub from_str: unsafe extern "C" fn(from: FfiSliceRef<str>) -> Result<Object, Error>, | |
50 | pub from_str: unsafe extern "C" fn(from: FfiSliceRef<str>) -> FfiResult<Object, FfiError>, | |
24 | 51 | pub home_uri: unsafe extern "C" fn(this: FfiValueRef<Object>) -> FfiSlice<str>, |
25 | 52 | } |
26 | 53 | |
27 | 54 | impl ObjectVTable { |
28 | pub fn new<O: IntoObjectVTable>() -> Self { | |
55 | pub const fn new<O: IntoObjectVTable>() -> Self { | |
29 | 56 | todo!() |
30 | 57 | } |
31 | 58 | } |
32 | 59 | |
33 | pub trait IntoObjectVTable { | |
60 | pub trait IntoObjectVTable: Sized { | |
61 | const VTABLE: &'static VTable<Object> = VTable::new(&ObjectVTable::new::<Self>()); | |
62 | ||
34 | 63 | fn object_kind() -> &'static CStr; |
35 | 64 | unsafe extern "C" fn to_str(this: FfiValueRef<Object>) -> FfiSlice<str>; |
36 | unsafe extern "C" fn from_str(from: FfiSliceRef<str>) -> Result<Object, Error>; | |
65 | unsafe extern "C" fn from_str(from: FfiSliceRef<str>) -> FfiResult<Object, FfiError>; | |
37 | 66 | unsafe extern "C" fn home_uri(this: FfiValueRef<Object>) -> FfiSlice<str>; |
38 | 67 | } |
giterated-abi/src/vtable/operation.rs
@@ -1,7 +1,7 @@ | ||
1 | 1 | use std::ffi::CStr; |
2 | 2 | |
3 | 3 | use crate::{ |
4 | result::{Error, Result}, | |
4 | result::{FfiError, FfiResult}, | |
5 | 5 | value_ex::{FfiValueRefUntyped, FfiValueUntyped}, |
6 | 6 | FfiSlice, FfiSliceRef, FfiValue, FfiValueRef, |
7 | 7 | }; |
@@ -10,10 +10,24 @@ use super::{ObjectABI, VTable}; | ||
10 | 10 | |
11 | 11 | #[repr(C)] |
12 | 12 | pub struct Operation { |
13 | inner: FfiValue<()>, | |
13 | inner: FfiValueUntyped, | |
14 | 14 | vtable: &'static VTable<Operation>, |
15 | 15 | } |
16 | 16 | |
17 | impl Operation { | |
18 | pub fn operation_kind(&self) -> &'static str { | |
19 | todo!() | |
20 | } | |
21 | ||
22 | pub fn serialize(&self) -> Vec<u8> { | |
23 | todo!() | |
24 | } | |
25 | ||
26 | pub fn deserialize_from<O, T: IntoOperationVTable<O>>(buffer: &[u8]) -> Result<Self, FfiError> { | |
27 | todo!() | |
28 | } | |
29 | } | |
30 | ||
17 | 31 | impl ObjectABI for Operation { |
18 | 32 | type VTable = OperationVTable; |
19 | 33 | } |
@@ -21,43 +35,69 @@ impl ObjectABI for Operation { | ||
21 | 35 | pub struct OperationVTable { |
22 | 36 | pub operation_kind: &'static CStr, |
23 | 37 | pub operation_serialize: |
24 | unsafe extern "C" fn(this: FfiValueRef<Operation>) -> Result<FfiSlice<[u8]>, Error>, | |
38 | unsafe extern "C" fn(this: FfiValueRef<Operation>) -> FfiResult<FfiSlice<[u8]>, FfiError>, | |
25 | 39 | pub operation_deserialize: |
26 | unsafe extern "C" fn(buffer: FfiSliceRef<[u8]>) -> Result<Operation, Error>, | |
40 | unsafe extern "C" fn(buffer: FfiSliceRef<[u8]>) -> FfiResult<Operation, FfiError>, | |
27 | 41 | pub success_serialize: |
28 | unsafe extern "C" fn(success: FfiValueRefUntyped) -> Result<FfiSlice<[u8]>, Error>, | |
42 | unsafe extern "C" fn(success: FfiValueRefUntyped) -> FfiResult<FfiSlice<[u8]>, FfiError>, | |
29 | 43 | pub success_deserialize: |
30 | unsafe extern "C" fn(buffer: FfiSliceRef<[u8]>) -> Result<FfiValueUntyped, Error>, | |
44 | unsafe extern "C" fn(buffer: FfiSliceRef<[u8]>) -> FfiResult<FfiValueUntyped, FfiError>, | |
31 | 45 | pub failure_serialize: |
32 | unsafe extern "C" fn(failure: FfiValueRefUntyped) -> Result<FfiSlice<[u8]>, Error>, | |
46 | unsafe extern "C" fn(failure: FfiValueRefUntyped) -> FfiResult<FfiSlice<[u8]>, FfiError>, | |
33 | 47 | pub failure_deserialize: |
34 | unsafe extern "C" fn(buffer: FfiSliceRef<[u8]>) -> Result<FfiValueUntyped, Error>, | |
48 | unsafe extern "C" fn(buffer: FfiSliceRef<[u8]>) -> FfiResult<FfiValueUntyped, FfiError>, | |
35 | 49 | } |
36 | 50 | |
37 | 51 | impl OperationVTable { |
38 | pub const fn new<O: IntoOperationVTable>() -> Self { | |
52 | pub const fn new<O, T: IntoOperationVTable<O>>() -> Self { | |
53 | todo!() | |
54 | } | |
55 | ||
56 | pub fn serialize(&self, operation: Operation) -> Result<Vec<u8>, FfiError> { | |
57 | todo!() | |
58 | } | |
59 | ||
60 | pub fn deserialize(&self, buffer: &[u8]) -> Result<Operation, FfiError> { | |
61 | todo!() | |
62 | } | |
63 | ||
64 | pub fn serialize_success(&self, success: FfiValueUntyped) -> Result<Vec<u8>, FfiError> { | |
65 | todo!() | |
66 | } | |
67 | ||
68 | pub fn deserialize_success(&self, buffer: &[u8]) -> Result<FfiValueUntyped, FfiError> { | |
69 | todo!() | |
70 | } | |
71 | ||
72 | pub fn serialize_failure(&self, failure: FfiValueUntyped) -> Result<Vec<u8>, FfiError> { | |
73 | todo!() | |
74 | } | |
75 | ||
76 | pub fn deserialize_failure(&self, buffer: &[u8]) -> Result<FfiValueUntyped, FfiError> { | |
39 | 77 | todo!() |
40 | 78 | } |
41 | 79 | } |
42 | 80 | |
43 | pub trait IntoOperationVTable { | |
81 | pub trait IntoOperationVTable<O>: Sized { | |
82 | const VTABLE: &'static VTable<Operation> = VTable::new(&OperationVTable::new::<O, Self>()); | |
83 | ||
44 | 84 | fn operation_kind() -> &'static CStr; |
45 | 85 | unsafe extern "C" fn operation_serialize( |
46 | 86 | this: FfiValueRef<Operation>, |
47 | ) -> Result<FfiSlice<[u8]>, Error>; | |
87 | ) -> FfiResult<FfiSlice<[u8]>, FfiError>; | |
48 | 88 | unsafe extern "C" fn operation_deserialize( |
49 | 89 | buffer: FfiSliceRef<[u8]>, |
50 | ) -> Result<Operation, Error>; | |
90 | ) -> FfiResult<Operation, FfiError>; | |
51 | 91 | unsafe extern "C" fn success_serialize( |
52 | 92 | success: FfiValueRefUntyped, |
53 | ) -> Result<FfiSlice<[u8]>, Error>; | |
93 | ) -> FfiResult<FfiSlice<[u8]>, FfiError>; | |
54 | 94 | unsafe extern "C" fn success_deserialize( |
55 | 95 | buffer: FfiSliceRef<[u8]>, |
56 | ) -> Result<FfiValueUntyped, Error>; | |
96 | ) -> FfiResult<FfiValueUntyped, FfiError>; | |
57 | 97 | unsafe extern "C" fn failure_serialize( |
58 | 98 | failure: FfiValueRefUntyped, |
59 | ) -> Result<FfiSlice<[u8]>, Error>; | |
99 | ) -> FfiResult<FfiSlice<[u8]>, FfiError>; | |
60 | 100 | unsafe extern "C" fn failure_deserialize( |
61 | 101 | buffer: FfiSliceRef<[u8]>, |
62 | ) -> Result<FfiValueUntyped, Error>; | |
102 | ) -> FfiResult<FfiValueUntyped, FfiError>; | |
63 | 103 | } |
giterated-abi/src/vtable/setting.rs
@@ -1,5 +1,6 @@ | ||
1 | 1 | use crate::{ |
2 | result::{Error, Result}, | |
2 | result::{FfiError, FfiResult}, | |
3 | value_ex::FfiValueUntyped, | |
3 | 4 | FfiSlice, FfiSliceRef, |
4 | 5 | }; |
5 | 6 | |
@@ -7,26 +8,46 @@ use super::{ObjectABI, VTable}; | ||
7 | 8 | |
8 | 9 | #[repr(C)] |
9 | 10 | pub struct Setting { |
10 | inner: (), | |
11 | inner: FfiValueUntyped, | |
11 | 12 | vtable: &'static VTable<Setting>, |
12 | 13 | } |
13 | 14 | |
15 | impl<T: IntoSettingVTable> From<T> for Setting { | |
16 | fn from(value: T) -> Self { | |
17 | todo!() | |
18 | } | |
19 | } | |
20 | ||
14 | 21 | impl ObjectABI for Setting { |
15 | 22 | type VTable = SettingVTable; |
16 | 23 | } |
17 | 24 | |
18 | 25 | pub struct SettingVTable { |
19 | pub serialize: unsafe extern "C" fn(this: Setting) -> Result<FfiSlice<[u8]>, Error>, | |
20 | pub deserialize: unsafe extern "C" fn(buffer: FfiSliceRef<[u8]>) -> Result<Setting, Error>, | |
26 | pub serialize: unsafe extern "C" fn(this: Setting) -> FfiResult<FfiSlice<[u8]>, FfiError>, | |
27 | pub deserialize: | |
28 | unsafe extern "C" fn(buffer: FfiSliceRef<[u8]>) -> FfiResult<Setting, FfiError>, | |
21 | 29 | } |
22 | 30 | |
23 | 31 | impl SettingVTable { |
24 | pub fn new<S: IntoSettingVTable>() -> Self { | |
32 | pub const fn new<S: IntoSettingVTable>() -> Self { | |
33 | Self { | |
34 | serialize: S::serialize, | |
35 | deserialize: S::deserialize | |
36 | } | |
37 | } | |
38 | ||
39 | pub fn serialize(&self, setting: Setting) -> Result<Vec<u8>, FfiError> { | |
40 | todo!() | |
41 | } | |
42 | ||
43 | pub fn deserialize(&self, buffer: &[u8]) -> Result<Setting, FfiError> { | |
25 | 44 | todo!() |
26 | 45 | } |
27 | 46 | } |
28 | 47 | |
29 | pub trait IntoSettingVTable { | |
30 | unsafe extern "C" fn serialize(this: Setting) -> Result<FfiSlice<[u8]>, Error>; | |
31 | unsafe extern "C" fn deserialize(buffer: FfiSliceRef<[u8]>) -> Result<Setting, Error>; | |
48 | pub trait IntoSettingVTable: Sized { | |
49 | const VTABLE: &'static VTable<Setting> = VTable::new(&SettingVTable::new::<Self>()); | |
50 | ||
51 | unsafe extern "C" fn serialize(this: Setting) -> FfiResult<FfiSlice<[u8]>, FfiError>; | |
52 | unsafe extern "C" fn deserialize(buffer: FfiSliceRef<[u8]>) -> FfiResult<Setting, FfiError>; | |
32 | 53 | } |
giterated-abi/src/vtable/value.rs
@@ -1,5 +1,6 @@ | ||
1 | 1 | use crate::{ |
2 | result::{Error, Result}, | |
2 | result::{FfiError, FfiResult}, | |
3 | value_ex::FfiValueUntyped, | |
3 | 4 | FfiSlice, FfiSliceRef, |
4 | 5 | }; |
5 | 6 | |
@@ -7,17 +8,23 @@ use super::{ObjectABI, VTable}; | ||
7 | 8 | |
8 | 9 | #[repr(C)] |
9 | 10 | pub struct Value { |
10 | inner: (), | |
11 | inner: FfiValueUntyped, | |
11 | 12 | vtable: &'static VTable<Value>, |
12 | 13 | } |
13 | 14 | |
15 | impl Value { | |
16 | pub fn from<T: IntoValueVTable>(value: T) -> Self { | |
17 | todo!() | |
18 | } | |
19 | } | |
20 | ||
14 | 21 | impl ObjectABI for Value { |
15 | 22 | type VTable = ValueVTable; |
16 | 23 | } |
17 | 24 | |
18 | 25 | pub struct ValueVTable { |
19 | pub serialize: unsafe extern "C" fn(buffer: FfiSliceRef<[u8]>) -> Result<Value, Error>, | |
20 | pub deserialize: unsafe extern "C" fn(this: Value) -> Result<FfiSlice<[u8]>, Error>, | |
26 | pub serialize: unsafe extern "C" fn(buffer: FfiSliceRef<[u8]>) -> FfiResult<Value, FfiError>, | |
27 | pub deserialize: unsafe extern "C" fn(this: Value) -> FfiResult<FfiSlice<[u8]>, FfiError>, | |
21 | 28 | } |
22 | 29 | |
23 | 30 | impl ValueVTable { |
@@ -27,9 +34,19 @@ impl ValueVTable { | ||
27 | 34 | deserialize: V::deserialize, |
28 | 35 | } |
29 | 36 | } |
37 | ||
38 | pub fn serialize(&self, value: &Value) -> Result<Vec<u8>, FfiError> { | |
39 | todo!() | |
40 | } | |
41 | ||
42 | pub fn deserialize(&self, buffer: &[u8]) -> Result<Value, FfiError> { | |
43 | todo!() | |
44 | } | |
30 | 45 | } |
31 | 46 | |
32 | pub trait IntoValueVTable { | |
33 | unsafe extern "C" fn serialize(buffer: FfiSliceRef<[u8]>) -> Result<Value, Error>; | |
34 | unsafe extern "C" fn deserialize(this: Value) -> Result<FfiSlice<[u8]>, Error>; | |
47 | pub trait IntoValueVTable: Sized { | |
48 | const VTABLE: &'static VTable<Value> = VTable::new(&ValueVTable::new::<Self>()); | |
49 | ||
50 | unsafe extern "C" fn serialize(buffer: FfiSliceRef<[u8]>) -> FfiResult<Value, FfiError>; | |
51 | unsafe extern "C" fn deserialize(this: Value) -> FfiResult<FfiSlice<[u8]>, FfiError>; | |
35 | 52 | } |
giterated-core/Cargo.toml
@@ -0,0 +1,8 @@ | ||
1 | [package] | |
2 | name = "giterated-core" | |
3 | version = "0.1.0" | |
4 | edition = "2021" | |
5 | ||
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |
7 | ||
8 | [dependencies] |
giterated-core/src/callback/mod.rs
@@ -0,0 +1 @@ | ||
1 | mod operation; |
giterated-core/src/callback/operation.rs
@@ -0,0 +1,125 @@ | ||
1 | pub struct OperationHandlerCallback(FfiValueUntyped); | |
2 | ||
3 | impl Callback for OperationHandlerCallback { | |
4 | type CallbackFunc = unsafe extern "C" fn( | |
5 | CallbackPtr<OperationHandlerCallback>, | |
6 | state: FfiValueMut<State>, | |
7 | object: FfiValueRef<Object>, | |
8 | operation: FfiValueRef<Operation>, | |
9 | ) -> RuntimeFuture< | |
10 | FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>, | |
11 | >; | |
12 | } | |
13 | ||
14 | pub trait IntoPluginOperationHandler<S, O: GiteratedObject, D: GiteratedOperation<O>, A> { | |
15 | unsafe extern "C" fn handle( | |
16 | callback_ptr: CallbackPtr<OperationHandlerCallback>, | |
17 | state: FfiValueMut<State>, | |
18 | object: FfiValueRef<Object>, | |
19 | operation: FfiValueRef<Operation>, | |
20 | ) -> RuntimeFuture<FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>>; | |
21 | fn callback_ptr(&self) -> CallbackPtr<OperationHandlerCallback>; | |
22 | } | |
23 | ||
24 | impl<F, S, O, D, Fut> IntoPluginOperationHandler<S, O, D, ()> for F | |
25 | where | |
26 | Fut: Future<Output = Result<D::Success, OperationError<D::Failure>>> + Send + Sync, | |
27 | F: Fn(S, O, D) -> Fut + Send + Sync + 'static, | |
28 | S: Clone + Debug + Send + Sync + 'static, | |
29 | O: Debug + GiteratedObject + 'static, | |
30 | D: Debug + GiteratedOperation<O> + 'static, | |
31 | { | |
32 | unsafe extern "C" fn handle( | |
33 | callback: CallbackPtr<OperationHandlerCallback>, | |
34 | state: FfiValueMut<State>, | |
35 | object: FfiValueRef<Object>, | |
36 | operation: FfiValueRef<Operation>, | |
37 | ) -> RuntimeFuture<FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>> { | |
38 | todo!() | |
39 | // let _guard = trace_span!( | |
40 | // "operation handler", | |
41 | // object = type_name::<O>(), | |
42 | // operation = type_name::<D>() | |
43 | // ) | |
44 | // .entered(); | |
45 | // let state = unsafe { state.transmute_ref::<S>() }; | |
46 | ||
47 | // // Since this is Rust code, we know that the AnyObject and AnyOperation are just boxes | |
48 | // let object = unsafe { object.transmute_owned::<O>() }; | |
49 | // let operation = unsafe { operation.transmute_owned::<D>() }; | |
50 | ||
51 | // // Cast the callback ptr to ourselves | |
52 | // let callback: *const F = std::mem::transmute(callback.0); | |
53 | // let callback = callback.as_ref().unwrap(); | |
54 | ||
55 | // let state = state.clone(); | |
56 | // runtime_state.spawn_future(async move { | |
57 | // let result = callback(state, *object, *operation).await; | |
58 | ||
59 | // match result { | |
60 | // Ok(success) => unsafe { | |
61 | // todo!() | |
62 | // // Ok(AnySuccess::from_raw( | |
63 | // // FFIBox::from_box(Box::new(success)).untyped(), | |
64 | // // OperationVTable::new::<O, D>(), | |
65 | // // )) | |
66 | // }, | |
67 | // Err(err) => match err { | |
68 | // OperationError::Operation(_) => todo!(), | |
69 | // OperationError::Internal(_) => todo!(), | |
70 | // OperationError::Unhandled => todo!(), | |
71 | // }, | |
72 | // } | |
73 | // }) | |
74 | } | |
75 | ||
76 | fn callback_ptr(&self) -> CallbackPtr<OperationHandlerCallback> { | |
77 | // unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } | |
78 | ||
79 | todo!() | |
80 | } | |
81 | } | |
82 | ||
83 | impl<F, S, O, D, Fut, A1> IntoPluginOperationHandler<S, O, D, (A1,)> for F | |
84 | where | |
85 | Fut: Future<Output = Result<D::Success, OperationError<D::Failure>>>, | |
86 | F: Fn(S, O, D, A1) -> Fut, | |
87 | S: Clone + Debug, | |
88 | O: Debug + GiteratedObject, | |
89 | D: Debug + GiteratedOperation<O>, | |
90 | { | |
91 | unsafe extern "C" fn handle( | |
92 | _callback_ptr: CallbackPtr<OperationHandlerCallback>, | |
93 | state: FfiValueMut<State>, | |
94 | object: FfiValueRef<Object>, | |
95 | operation: FfiValueRef<Operation>, | |
96 | ) -> RuntimeFuture<FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>> { | |
97 | todo!() | |
98 | } | |
99 | ||
100 | fn callback_ptr(&self) -> CallbackPtr<OperationHandlerCallback> { | |
101 | todo!() | |
102 | } | |
103 | } | |
104 | ||
105 | impl<F, S, O, D, Fut, A1, A2> IntoPluginOperationHandler<S, O, D, (A1, A2)> for F | |
106 | where | |
107 | Fut: Future<Output = Result<D::Success, OperationError<D::Failure>>>, | |
108 | F: Fn(S, O, D, A1, A2) -> Fut, | |
109 | S: Clone + Debug, | |
110 | O: Debug + GiteratedObject, | |
111 | D: Debug + GiteratedOperation<O>, | |
112 | { | |
113 | unsafe extern "C" fn handle( | |
114 | _callback_ptr: CallbackPtr<OperationHandlerCallback>, | |
115 | state: FfiValueMut<State>, | |
116 | object: FfiValueRef<Object>, | |
117 | operation: FfiValueRef<Operation>, | |
118 | ) -> RuntimeFuture<FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>> { | |
119 | todo!() | |
120 | } | |
121 | ||
122 | fn callback_ptr(&self) -> CallbackPtr<OperationHandlerCallback> { | |
123 | todo!() | |
124 | } | |
125 | } |
giterated-core/src/lib.rs
@@ -0,0 +1,68 @@ | ||
1 | mod callback; | |
2 | mod state; | |
3 | ||
4 | #[derive(Clone)] | |
5 | #[repr(C)] | |
6 | pub struct RuntimeState { | |
7 | pub vtable: VTable<RuntimeState>, | |
8 | } | |
9 | ||
10 | impl RuntimeState { | |
11 | pub unsafe fn from_static() -> Self { | |
12 | let runtime = giterated_static_runtime::get_runtime_reference(); | |
13 | ||
14 | let runtime = runtime.cast::<Box<Runtime>>().as_ref(); | |
15 | ||
16 | runtime.state() | |
17 | } | |
18 | ||
19 | pub unsafe fn runtime_state() -> PluginState { | |
20 | let runtime = giterated_static_runtime::get_runtime_reference(); | |
21 | ||
22 | PluginState::from_raw_ptr(giterated_static_runtime::get_runtime_reference().as_ptr()) | |
23 | } | |
24 | } | |
25 | ||
26 | #[async_trait::async_trait(?Send)] | |
27 | impl ObjectBackend for RuntimeState { | |
28 | async fn object_operation<O, D>( | |
29 | &self, | |
30 | object: O, | |
31 | _operation: &str, | |
32 | payload: D, | |
33 | _operation_state: &OperationState, | |
34 | ) -> Result<D::Success, OperationError<D::Failure>> | |
35 | where | |
36 | O: GiteratedObject + Debug + 'static, | |
37 | D: GiteratedOperation<O> + Debug + 'static, | |
38 | D::Success: Clone, | |
39 | D::Failure: Clone, | |
40 | { | |
41 | // let _object = AnyObject::new(object); | |
42 | // let _operation = AnyOperation::new(payload); | |
43 | ||
44 | todo!() | |
45 | } | |
46 | ||
47 | async fn get_object<O: GiteratedObject + Debug + 'static>( | |
48 | &self, | |
49 | object_str: &str, | |
50 | operation_state: &OperationState, | |
51 | ) -> Result<Object<O, Self>, OperationError<ObjectRequestError>> { | |
52 | // let object = unsafe { | |
53 | // (self.vtable.get_object)( | |
54 | // Self::runtime_state(), | |
55 | // object_str, | |
56 | // &mut operation_state.clone(), | |
57 | // ) | |
58 | // }?; | |
59 | ||
60 | // let object = unsafe { object.cast::<O>() }; | |
61 | ||
62 | panic!("object casted"); | |
63 | ||
64 | // Ok(unsafe { Object::new_unchecked(object, self.clone()) }) | |
65 | ||
66 | todo!() | |
67 | } | |
68 | } |
giterated-core/src/state.rs
@@ -0,0 +1,15 @@ | ||
1 | pub trait FromOperationState<O, D>: Sized { | |
2 | fn from_operation_state( | |
3 | state: &mut State, | |
4 | object: &O, | |
5 | operation: &D, | |
6 | ) -> Result<Self, OperationError<anyhow::Error>>; | |
7 | } | |
8 | ||
9 | pub struct StateExtractor<T>(T); | |
10 | ||
11 | impl<T: FromState> FromState for StateExtractor<T> { | |
12 | fn from_state(state: &mut State) -> Result<Self, anyhow::Error> { | |
13 | todo!() | |
14 | } | |
15 | } |
giterated-plugin/Cargo.toml
@@ -19,3 +19,4 @@ async-trait = "0.1" | ||
19 | 19 | serde = "*" |
20 | 20 | futures-util = "0.3.30" |
21 | 21 | tokio = { version = "1.32", features = [ "full" ] } |
22 | giterated-macros = { path = "giterated-macros" } | |
22 | \ No newline at end of file |
giterated-plugin/giterated-macros/Cargo.toml
@@ -0,0 +1,10 @@ | ||
1 | [package] | |
2 | name = "giterated-macros" | |
3 | version = "0.1.0" | |
4 | edition = "2021" | |
5 | ||
6 | [lib] | |
7 | proc-macro = true | |
8 | ||
9 | [dependencies] | |
10 | quote = "1.0" | |
10 | \ No newline at end of file |
giterated-plugin/giterated-macros/src/lib.rs
@@ -0,0 +1,13 @@ | ||
1 | use proc_macro::TokenStream; | |
2 | ||
3 | extern crate proc_macro; | |
4 | ||
5 | #[proc_macro] | |
6 | pub fn plugin(metadata: TokenStream) -> TokenStream { | |
7 | "".parse().unwrap() | |
8 | } | |
9 | ||
10 | #[proc_macro_attribute] | |
11 | pub fn plugin_init(attribute: TokenStream, item: TokenStream) -> TokenStream { | |
12 | "".parse().unwrap() | |
13 | } | |
13 | \ No newline at end of file |
giterated-plugin/giterated-plugin-sys/Cargo.toml
@@ -8,4 +8,5 @@ edition = "2021" | ||
8 | 8 | [dependencies] |
9 | 9 | giterated-plugin = { path = "../." } |
10 | 10 | tracing = "0.1" |
11 | giterated-models = { path = "../../giterated-models" } | |
11 | \ No newline at end of file | |
11 | giterated-models = { path = "../../giterated-models" } | |
12 | giterated-abi = { path = "../../giterated-abi" } |
giterated-plugin/giterated-plugin-sys/src/lib.rs
@@ -1,37 +1,44 @@ | ||
1 | 1 | mod local_runtime; |
2 | 2 | |
3 | use giterated_abi::{ | |
4 | callback::{Callback, CallbackPtr}, | |
5 | result::FfiError, | |
6 | value_ex::FfiValueUntyped, | |
7 | vtable::{ | |
8 | operation::{IntoOperationVTable, OperationVTable}, | |
9 | IntoObjectVTable, IntoSettingVTable, IntoValueVTable, Object, ObjectVTable, SettingVTable, | |
10 | VTable, ValueVTable, | |
11 | }, | |
12 | FfiValueRef, | |
13 | }; | |
3 | 14 | use giterated_models::{ |
4 | 15 | object::GiteratedObject, operation::GiteratedOperation, settings::Setting, |
5 | 16 | value::GiteratedObjectValue, |
6 | 17 | }; |
7 | 18 | use giterated_plugin::{ |
8 | 19 | callback::{ |
9 | CallbackPtr, IntoPluginOperationHandler, IntoPluginSettingGetter, IntoPluginSettingSetter, | |
20 | IntoPluginOperationHandler, IntoPluginSettingGetter, IntoPluginSettingSetter, | |
10 | 21 | IntoPluginValueGetter, OperationHandlerCallback, SettingGetterCallback, |
11 | 22 | ValueGetterCallback, |
12 | 23 | }, |
13 | 24 | handle::PluginInitializationState, |
14 | 25 | new_stack::PluginState, |
15 | vtable::{ | |
16 | InitializationVTable, IntoObjectVTable, IntoOperationVTable, IntoSettingVTable, | |
17 | IntoValueVTable, ObjectVtable, OperationVTable, SettingVtable, ValueVTable, | |
18 | }, | |
19 | AnyObject, NewAnyValue, | |
26 | vtable::Initialization, | |
20 | 27 | }; |
21 | 28 | use tracing::trace_span; |
22 | 29 | |
23 | pub struct PluginStackBuilder<'init, S> { | |
30 | pub struct PluginStackBuilder<S> { | |
24 | 31 | init_state: *mut PluginInitializationState, |
25 | vtable: &'init InitializationVTable, | |
32 | vtable: &'static VTable<Initialization>, | |
26 | 33 | state: S, |
27 | 34 | } |
28 | 35 | |
29 | impl<'init, S> PluginStackBuilder<'init, S> { | |
36 | impl<S> PluginStackBuilder<S> { | |
30 | 37 | pub fn new( |
31 | 38 | plugin_state: S, |
32 | 39 | state: *mut PluginInitializationState, |
33 | vtable: &'init InitializationVTable, | |
34 | ) -> PluginStackBuilder<'init, S> { | |
40 | vtable: &'static VTable<Initialization>, | |
41 | ) -> PluginStackBuilder<S> { | |
35 | 42 | PluginStackBuilder { |
36 | 43 | init_state: state, |
37 | 44 | vtable, |
@@ -44,7 +51,13 @@ impl<'init, S> PluginStackBuilder<'init, S> { | ||
44 | 51 | |
45 | 52 | let func = self.vtable.register_object; |
46 | 53 | |
47 | unsafe { func(self.init_state, O::object_name(), ObjectVtable::new::<O>()) }; | |
54 | unsafe { | |
55 | func( | |
56 | self.init_state, | |
57 | O::object_name(), | |
58 | O::VTABLE | |
59 | ) | |
60 | }; | |
48 | 61 | |
49 | 62 | self |
50 | 63 | } |
@@ -61,7 +74,7 @@ impl<'init, S> PluginStackBuilder<'init, S> { | ||
61 | 74 | self.init_state, |
62 | 75 | O::object_name(), |
63 | 76 | D::operation_name(), |
64 | OperationVTable::new::<O, D>(), | |
77 | <D as IntoOperationVTable<O>>::VTABLE, | |
65 | 78 | ) |
66 | 79 | } |
67 | 80 | |
@@ -82,7 +95,7 @@ impl<'init, S> PluginStackBuilder<'init, S> { | ||
82 | 95 | self.init_state, |
83 | 96 | O::object_name(), |
84 | 97 | OS::name(), |
85 | SettingVtable::new::<OS>(), | |
98 | OS::VTABLE, | |
86 | 99 | ) |
87 | 100 | } |
88 | 101 | |
@@ -101,7 +114,7 @@ impl<'init, S> PluginStackBuilder<'init, S> { | ||
101 | 114 | self.init_state, |
102 | 115 | O::object_name(), |
103 | 116 | OS::name(), |
104 | SettingVtable::new::<OS>(), | |
117 | OS::VTABLE, | |
105 | 118 | ) |
106 | 119 | } |
107 | 120 | |
@@ -111,7 +124,7 @@ impl<'init, S> PluginStackBuilder<'init, S> { | ||
111 | 124 | pub fn value<O, V, T>(&mut self, handler: T) -> &mut Self |
112 | 125 | where |
113 | 126 | O: GiteratedObject, |
114 | V: IntoValueVTable<O> + GiteratedObjectValue<Object = O>, | |
127 | V: IntoValueVTable + GiteratedObjectValue<Object = O>, | |
115 | 128 | T: IntoPluginValueGetter<S, O, V>, |
116 | 129 | { |
117 | 130 | let _guard = trace_span!("register value").entered(); |
@@ -121,18 +134,18 @@ impl<'init, S> PluginStackBuilder<'init, S> { | ||
121 | 134 | self.init_state, |
122 | 135 | O::object_name(), |
123 | 136 | V::value_name(), |
124 | ValueVTable::new::<O, V>(), | |
137 | V::VTABLE, | |
125 | 138 | ) |
126 | 139 | } |
127 | 140 | |
128 | unsafe { | |
129 | (self.vtable.value_getter)( | |
130 | self.init_state, | |
131 | O::object_name(), | |
132 | V::value_name(), | |
133 | ValueGetterCallback::new::<S, O, V, T>(handler), | |
134 | ) | |
135 | } | |
141 | // unsafe { | |
142 | // (self.vtable.value_getter)( | |
143 | // self.init_state, | |
144 | // O::object_name(), | |
145 | // V::value_name(), | |
146 | // ValueGetterCallback::new::<S, O, V, T>(handler), | |
147 | // ) | |
148 | // } | |
136 | 149 | |
137 | 150 | self |
138 | 151 | } |
@@ -148,14 +161,14 @@ impl<'init, S> PluginStackBuilder<'init, S> { | ||
148 | 161 | ) -> &mut Self { |
149 | 162 | let _guard = trace_span!("register operation handler").entered(); |
150 | 163 | |
151 | unsafe { | |
152 | (self.vtable.operation_handler)( | |
153 | self.init_state, | |
154 | O::object_name(), | |
155 | D::operation_name(), | |
156 | OperationHandlerCallback::new::<S, O, D, A, T>(handler), | |
157 | ) | |
158 | } | |
164 | // unsafe { | |
165 | // (self.vtable.operation_handler)( | |
166 | // self.init_state, | |
167 | // O::object_name(), | |
168 | // D::operation_name(), | |
169 | // OperationHandlerCallback::new::<S, O, D, A, T>(handler), | |
170 | // ) | |
171 | // } | |
159 | 172 | |
160 | 173 | // TODO: Yikes? |
161 | 174 | self.object::<O>(); |
@@ -197,14 +210,14 @@ impl<'init, S> PluginStackBuilder<'init, S> { | ||
197 | 210 | { |
198 | 211 | let _guard = trace_span!("register setting_getter handler").entered(); |
199 | 212 | |
200 | unsafe { | |
201 | (self.vtable.setting_getter)( | |
202 | self.init_state, | |
203 | O::object_name(), | |
204 | OS::name(), | |
205 | SettingGetterCallback::new::<S, O, OS, T>(handler), | |
206 | ) | |
207 | } | |
213 | // unsafe { | |
214 | // (self.vtable.setting_getter)( | |
215 | // self.init_state, | |
216 | // O::object_name(), | |
217 | // OS::name(), | |
218 | // SettingGetterCallback::new::<S, O, OS, T>(handler), | |
219 | // ) | |
220 | // } | |
208 | 221 | |
209 | 222 | self.object::<O>(); |
210 | 223 | |
@@ -213,7 +226,7 @@ impl<'init, S> PluginStackBuilder<'init, S> { | ||
213 | 226 | self.init_state, |
214 | 227 | O::object_name(), |
215 | 228 | OS::name(), |
216 | SettingVtable::new::<OS>(), | |
229 | OS::VTABLE, | |
217 | 230 | ) |
218 | 231 | }; |
219 | 232 | |
@@ -225,16 +238,16 @@ pub trait ValueSettingExt<PS> { | ||
225 | 238 | fn value_setting<O, VS, HG, HS>(&mut self, get: HG, set: HS) -> &mut Self |
226 | 239 | where |
227 | 240 | O: GiteratedObject + IntoObjectVTable + 'static, |
228 | VS: GiteratedObjectValue<Object = O> + IntoValueVTable<O> + Setting + IntoSettingVTable, | |
241 | VS: GiteratedObjectValue<Object = O> + IntoValueVTable + Setting + IntoSettingVTable, | |
229 | 242 | HG: IntoPluginSettingGetter<PS, O, VS>, |
230 | 243 | HS: IntoPluginSettingSetter<PS, O, VS>; |
231 | 244 | } |
232 | 245 | |
233 | impl<PS> ValueSettingExt<PS> for PluginStackBuilder<'_, PS> { | |
246 | impl<PS> ValueSettingExt<PS> for PluginStackBuilder<PS> { | |
234 | 247 | fn value_setting<O, VS, HG, HS>(&mut self, _get: HG, _set: HS) -> &mut Self |
235 | 248 | where |
236 | 249 | O: GiteratedObject + IntoObjectVTable + 'static, |
237 | VS: GiteratedObjectValue<Object = O> + IntoValueVTable<O> + Setting + IntoSettingVTable, | |
250 | VS: GiteratedObjectValue<Object = O> + IntoValueVTable + Setting + IntoSettingVTable, | |
238 | 251 | HG: IntoPluginSettingGetter<PS, O, VS>, |
239 | 252 | HS: IntoPluginSettingSetter<PS, O, VS>, |
240 | 253 | { |
@@ -242,14 +255,25 @@ impl<PS> ValueSettingExt<PS> for PluginStackBuilder<'_, PS> { | ||
242 | 255 | } |
243 | 256 | } |
244 | 257 | |
258 | #[derive(Clone, Copy)] | |
259 | pub struct ValueSettingGetterCallback; | |
260 | ||
261 | impl Callback for ValueSettingGetterCallback { | |
262 | type CallbackFunc = unsafe extern "C" fn( | |
263 | callback: CallbackPtr<ValueSettingGetterCallback>, | |
264 | state: &PluginState, | |
265 | object: FfiValueRef<Object>, | |
266 | ) -> Result<FfiValueUntyped, FfiError>; | |
267 | } | |
268 | ||
245 | 269 | pub trait ValueSettingGetter<S, O, V> { |
246 | 270 | unsafe extern "C" fn get_value( |
247 | callback: CallbackPtr, | |
271 | callback: CallbackPtr<ValueSettingGetterCallback>, | |
248 | 272 | state: &PluginState, |
249 | object: AnyObject, | |
250 | ) -> Result<NewAnyValue, ()>; | |
273 | object: FfiValueRef<Object>, | |
274 | ) -> Result<FfiValueUntyped, FfiError>; | |
251 | 275 | |
252 | fn callback_ptr(&self) -> CallbackPtr; | |
276 | fn callback_ptr(&self) -> CallbackPtr<ValueSettingGetterCallback>; | |
253 | 277 | } |
254 | 278 | |
255 | 279 | impl<S, O, VS, HG> ValueSettingGetter<S, O, VS> for HG |
@@ -259,10 +283,10 @@ where | ||
259 | 283 | HG: IntoPluginSettingGetter<S, O, VS>, |
260 | 284 | { |
261 | 285 | unsafe extern "C" fn get_value( |
262 | _callback: CallbackPtr, | |
286 | _callback: CallbackPtr<ValueSettingGetterCallback>, | |
263 | 287 | _state: &PluginState, |
264 | _object: AnyObject, | |
265 | ) -> Result<NewAnyValue, ()> { | |
288 | _object: FfiValueRef<Object>, | |
289 | ) -> Result<FfiValueUntyped, FfiError> { | |
266 | 290 | // let result = HG::get_setting(callback, state, object)?; |
267 | 291 | |
268 | 292 | // let setting = *result.transmute_owned::<VS>(); |
@@ -272,7 +296,7 @@ where | ||
272 | 296 | // Ok(NewAnyValue::new(setting)) |
273 | 297 | } |
274 | 298 | |
275 | fn callback_ptr(&self) -> CallbackPtr { | |
276 | self.callback_ptr() | |
299 | fn callback_ptr(&self) -> CallbackPtr<ValueSettingGetterCallback> { | |
300 | todo!() | |
277 | 301 | } |
278 | 302 | } |
giterated-plugin/src/callback/mod.rs
@@ -17,81 +17,4 @@ pub use setting::*; | ||
17 | 17 | use crate::{ |
18 | 18 | new_stack::{PluginState, Runtime}, |
19 | 19 | vtable::RuntimeVTable, |
20 | AnyObject, AnyOperation, | |
21 | }; | |
22 | ||
23 | /// A container for a callback pointer, used to provide an internal callback function or | |
24 | /// state to a plugin when performing a callback. | |
25 | #[derive(Clone, Copy)] | |
26 | #[repr(C)] | |
27 | pub struct CallbackPtr(*const ()); | |
28 | ||
29 | impl CallbackPtr { | |
30 | pub unsafe fn from_raw(callback: *const ()) -> Self { | |
31 | Self(callback) | |
32 | } | |
33 | } | |
34 | ||
35 | #[derive(Clone)] | |
36 | #[repr(C)] | |
37 | pub struct RuntimeState { | |
38 | pub vtable: RuntimeVTable, | |
39 | } | |
40 | ||
41 | impl RuntimeState { | |
42 | pub unsafe fn from_static() -> Self { | |
43 | let runtime = giterated_static_runtime::get_runtime_reference(); | |
44 | ||
45 | let runtime = runtime.cast::<Box<Runtime>>().as_ref(); | |
46 | ||
47 | runtime.state() | |
48 | } | |
49 | ||
50 | pub unsafe fn runtime_state() -> PluginState { | |
51 | let runtime = giterated_static_runtime::get_runtime_reference(); | |
52 | ||
53 | PluginState::from_raw_ptr(giterated_static_runtime::get_runtime_reference().as_ptr()) | |
54 | } | |
55 | } | |
56 | ||
57 | #[async_trait::async_trait(?Send)] | |
58 | impl ObjectBackend for RuntimeState { | |
59 | async fn object_operation<O, D>( | |
60 | &self, | |
61 | object: O, | |
62 | _operation: &str, | |
63 | payload: D, | |
64 | _operation_state: &OperationState, | |
65 | ) -> Result<D::Success, OperationError<D::Failure>> | |
66 | where | |
67 | O: GiteratedObject + Debug + 'static, | |
68 | D: GiteratedOperation<O> + Debug + 'static, | |
69 | D::Success: Clone, | |
70 | D::Failure: Clone, | |
71 | { | |
72 | let _object = AnyObject::new(object); | |
73 | let _operation = AnyOperation::new(payload); | |
74 | ||
75 | todo!() | |
76 | } | |
77 | ||
78 | async fn get_object<O: GiteratedObject + Debug + 'static>( | |
79 | &self, | |
80 | object_str: &str, | |
81 | operation_state: &OperationState, | |
82 | ) -> Result<Object<O, Self>, OperationError<ObjectRequestError>> { | |
83 | let object = unsafe { | |
84 | (self.vtable.get_object)( | |
85 | Self::runtime_state(), | |
86 | object_str, | |
87 | &mut operation_state.clone(), | |
88 | ) | |
89 | }?; | |
90 | ||
91 | let object = unsafe { object.cast::<O>() }; | |
92 | ||
93 | panic!("object casted"); | |
94 | ||
95 | Ok(unsafe { Object::new_unchecked(object, self.clone()) }) | |
96 | } | |
97 | } | |
20 | }; | |
20 | \ No newline at end of file |
giterated-plugin/src/callback/operation.rs
@@ -1,3 +1,10 @@ | ||
1 | use giterated_abi::{ | |
2 | callback::{Callback, CallbackPtr}, | |
3 | result::FfiResult, | |
4 | value_ex::FfiValueUntyped, | |
5 | vtable::{operation::Operation, Object}, | |
6 | FfiValueMut, FfiValueRef, | |
7 | }; | |
1 | 8 | use giterated_models::{ |
2 | 9 | error::OperationError, |
3 | 10 | object::GiteratedObject, |
@@ -7,53 +14,48 @@ use giterated_models::{ | ||
7 | 14 | use crate::{ |
8 | 15 | future::{RuntimeFuture, RuntimeFuturesExt}, |
9 | 16 | new_stack::{handle::RuntimeHandle, PluginState}, |
10 | vtable::OperationVTable, | |
11 | AnyFailure, AnyObject, AnyOperation, AnySuccess, FFIBox, | |
17 | state::{FromState, State, StateUUID}, | |
12 | 18 | }; |
13 | 19 | |
14 | 20 | use std::{any::type_name, fmt::Debug, future::Future}; |
15 | 21 | |
16 | use super::{CallbackPtr, RuntimeState}; | |
17 | ||
18 | #[derive(Clone, Copy)] | |
19 | pub struct OperationHandlerCallback { | |
20 | pub callback_ptr: CallbackPtr, | |
21 | pub func: unsafe extern "C" fn( | |
22 | CallbackPtr, | |
23 | &RuntimeState, | |
24 | &PluginState, | |
25 | object: AnyObject, | |
26 | operation: AnyOperation, | |
27 | ) | |
28 | -> RuntimeFuture<Result<AnySuccess, OperationError<AnyFailure>>>, | |
22 | use super::RuntimeState; | |
23 | ||
24 | pub struct OperationHandlerCallback(FfiValueUntyped); | |
25 | ||
26 | impl Callback for OperationHandlerCallback { | |
27 | type CallbackFunc = unsafe extern "C" fn( | |
28 | CallbackPtr<OperationHandlerCallback>, | |
29 | state: FfiValueMut<State>, | |
30 | object: FfiValueRef<Object>, | |
31 | operation: FfiValueRef<Operation>, | |
32 | ) -> RuntimeFuture< | |
33 | FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>, | |
34 | >; | |
29 | 35 | } |
30 | 36 | |
31 | 37 | impl OperationHandlerCallback { |
32 | pub fn new< | |
33 | S, | |
34 | O: GiteratedObject, | |
35 | D: GiteratedOperation<O>, | |
36 | A, | |
37 | T: IntoPluginOperationHandler<S, O, D, A>, | |
38 | >( | |
39 | handler: T, | |
40 | ) -> Self { | |
41 | OperationHandlerCallback { | |
42 | func: T::handle, | |
43 | callback_ptr: T::callback_ptr(&handler), | |
44 | } | |
45 | } | |
38 | // pub fn new< | |
39 | // S, | |
40 | // O: GiteratedObject, | |
41 | // D: GiteratedOperation<O>, | |
42 | // A, | |
43 | // T: IntoPluginOperationHandler<S, O, D, A>, | |
44 | // >( | |
45 | // handler: T, | |
46 | // ) -> Self { | |
47 | // OperationHandlerCallback(unsafe { CallbackPtr::from_raw(&handler, T::handle as _) }) | |
48 | // } | |
46 | 49 | } |
47 | 50 | |
48 | 51 | pub trait IntoPluginOperationHandler<S, O: GiteratedObject, D: GiteratedOperation<O>, A> { |
49 | 52 | unsafe extern "C" fn handle( |
50 | callback_ptr: CallbackPtr, | |
51 | runtime_state: &RuntimeState, | |
52 | state: &PluginState, | |
53 | object: AnyObject, | |
54 | operation: AnyOperation, | |
55 | ) -> RuntimeFuture<Result<AnySuccess, OperationError<AnyFailure>>>; | |
56 | fn callback_ptr(&self) -> CallbackPtr; | |
53 | callback_ptr: CallbackPtr<OperationHandlerCallback>, | |
54 | state: FfiValueMut<State>, | |
55 | object: FfiValueRef<Object>, | |
56 | operation: FfiValueRef<Operation>, | |
57 | ) -> RuntimeFuture<FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>>; | |
58 | fn callback_ptr(&self) -> CallbackPtr<OperationHandlerCallback>; | |
57 | 59 | } |
58 | 60 | |
59 | 61 | impl<F, S, O, D, Fut> IntoPluginOperationHandler<S, O, D, ()> for F |
@@ -65,50 +67,53 @@ where | ||
65 | 67 | D: Debug + GiteratedOperation<O> + 'static, |
66 | 68 | { |
67 | 69 | unsafe extern "C" fn handle( |
68 | callback: CallbackPtr, | |
69 | runtime_state: &RuntimeState, | |
70 | state: &PluginState, | |
71 | mut object: AnyObject, | |
72 | mut operation: AnyOperation, | |
73 | ) -> RuntimeFuture<Result<AnySuccess, OperationError<AnyFailure>>> { | |
74 | let _guard = trace_span!( | |
75 | "operation handler", | |
76 | object = type_name::<O>(), | |
77 | operation = type_name::<D>() | |
78 | ) | |
79 | .entered(); | |
80 | let state = unsafe { state.transmute_ref::<S>() }; | |
81 | ||
82 | // Since this is Rust code, we know that the AnyObject and AnyOperation are just boxes | |
83 | let object = unsafe { object.transmute_owned::<O>() }; | |
84 | let operation = unsafe { operation.transmute_owned::<D>() }; | |
85 | ||
86 | // Cast the callback ptr to ourselves | |
87 | let callback: *const F = std::mem::transmute(callback.0); | |
88 | let callback = callback.as_ref().unwrap(); | |
89 | ||
90 | let state = state.clone(); | |
91 | runtime_state.spawn_future(async move { | |
92 | let result = callback(state, *object, *operation).await; | |
93 | ||
94 | match result { | |
95 | Ok(success) => unsafe { | |
96 | Ok(AnySuccess::from_raw( | |
97 | FFIBox::from_box(Box::new(success)).untyped(), | |
98 | OperationVTable::new::<O, D>(), | |
99 | )) | |
100 | }, | |
101 | Err(err) => match err { | |
102 | OperationError::Operation(_) => todo!(), | |
103 | OperationError::Internal(_) => todo!(), | |
104 | OperationError::Unhandled => todo!(), | |
105 | }, | |
106 | } | |
107 | }) | |
70 | callback: CallbackPtr<OperationHandlerCallback>, | |
71 | state: FfiValueMut<State>, | |
72 | object: FfiValueRef<Object>, | |
73 | operation: FfiValueRef<Operation>, | |
74 | ) -> RuntimeFuture<FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>> { | |
75 | todo!() | |
76 | // let _guard = trace_span!( | |
77 | // "operation handler", | |
78 | // object = type_name::<O>(), | |
79 | // operation = type_name::<D>() | |
80 | // ) | |
81 | // .entered(); | |
82 | // let state = unsafe { state.transmute_ref::<S>() }; | |
83 | ||
84 | // // Since this is Rust code, we know that the AnyObject and AnyOperation are just boxes | |
85 | // let object = unsafe { object.transmute_owned::<O>() }; | |
86 | // let operation = unsafe { operation.transmute_owned::<D>() }; | |
87 | ||
88 | // // Cast the callback ptr to ourselves | |
89 | // let callback: *const F = std::mem::transmute(callback.0); | |
90 | // let callback = callback.as_ref().unwrap(); | |
91 | ||
92 | // let state = state.clone(); | |
93 | // runtime_state.spawn_future(async move { | |
94 | // let result = callback(state, *object, *operation).await; | |
95 | ||
96 | // match result { | |
97 | // Ok(success) => unsafe { | |
98 | // todo!() | |
99 | // // Ok(AnySuccess::from_raw( | |
100 | // // FFIBox::from_box(Box::new(success)).untyped(), | |
101 | // // OperationVTable::new::<O, D>(), | |
102 | // // )) | |
103 | // }, | |
104 | // Err(err) => match err { | |
105 | // OperationError::Operation(_) => todo!(), | |
106 | // OperationError::Internal(_) => todo!(), | |
107 | // OperationError::Unhandled => todo!(), | |
108 | // }, | |
109 | // } | |
110 | // }) | |
108 | 111 | } |
109 | 112 | |
110 | fn callback_ptr(&self) -> CallbackPtr { | |
111 | unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } | |
113 | fn callback_ptr(&self) -> CallbackPtr<OperationHandlerCallback> { | |
114 | // unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } | |
115 | ||
116 | todo!() | |
112 | 117 | } |
113 | 118 | } |
114 | 119 | |
@@ -121,16 +126,15 @@ where | ||
121 | 126 | D: Debug + GiteratedOperation<O>, |
122 | 127 | { |
123 | 128 | unsafe extern "C" fn handle( |
124 | _callback_ptr: CallbackPtr, | |
125 | _runtime_state: &RuntimeState, | |
126 | _state: &PluginState, | |
127 | _object: AnyObject, | |
128 | _operation: AnyOperation, | |
129 | ) -> RuntimeFuture<Result<AnySuccess, OperationError<AnyFailure>>> { | |
129 | _callback_ptr: CallbackPtr<OperationHandlerCallback>, | |
130 | state: FfiValueMut<State>, | |
131 | object: FfiValueRef<Object>, | |
132 | operation: FfiValueRef<Operation>, | |
133 | ) -> RuntimeFuture<FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>> { | |
130 | 134 | todo!() |
131 | 135 | } |
132 | 136 | |
133 | fn callback_ptr(&self) -> CallbackPtr { | |
137 | fn callback_ptr(&self) -> CallbackPtr<OperationHandlerCallback> { | |
134 | 138 | todo!() |
135 | 139 | } |
136 | 140 | } |
@@ -144,50 +148,65 @@ where | ||
144 | 148 | D: Debug + GiteratedOperation<O>, |
145 | 149 | { |
146 | 150 | unsafe extern "C" fn handle( |
147 | _callback_ptr: CallbackPtr, | |
148 | _runtime_state: &RuntimeState, | |
149 | _state: &PluginState, | |
150 | _object: AnyObject, | |
151 | _operation: AnyOperation, | |
152 | ) -> RuntimeFuture<Result<AnySuccess, OperationError<AnyFailure>>> { | |
151 | _callback_ptr: CallbackPtr<OperationHandlerCallback>, | |
152 | state: FfiValueMut<State>, | |
153 | object: FfiValueRef<Object>, | |
154 | operation: FfiValueRef<Operation>, | |
155 | ) -> RuntimeFuture<FfiResult<FfiValueUntyped, OperationError<FfiValueUntyped>>> { | |
153 | 156 | todo!() |
154 | 157 | } |
155 | 158 | |
156 | fn callback_ptr(&self) -> CallbackPtr { | |
159 | fn callback_ptr(&self) -> CallbackPtr<OperationHandlerCallback> { | |
157 | 160 | todo!() |
158 | 161 | } |
159 | 162 | } |
160 | 163 | |
161 | 164 | pub trait FromOperationState<O, D>: Sized { |
162 | 165 | fn from_operation_state( |
163 | operation_state: &OperationState, | |
164 | runtime_state: &RuntimeState, | |
166 | state: &mut State, | |
165 | 167 | object: &O, |
166 | 168 | operation: &D, |
167 | 169 | ) -> Result<Self, OperationError<anyhow::Error>>; |
168 | 170 | } |
169 | 171 | |
170 | impl<O, D> FromOperationState<O, D> for RuntimeHandle { | |
171 | fn from_operation_state( | |
172 | _operation_state: &OperationState, | |
173 | runtime_state: &RuntimeState, | |
174 | _object: &O, | |
175 | _operation: &D, | |
176 | ) -> Result<Self, OperationError<anyhow::Error>> { | |
177 | Ok(unsafe { RuntimeHandle::from_vtable(runtime_state.vtable) }) | |
178 | } | |
179 | } | |
172 | pub struct StateExtractor<T>(T); | |
180 | 173 | |
181 | impl<O, D, T> FromOperationState<O, D> for Option<T> | |
182 | where | |
183 | T: FromOperationState<O, D>, | |
184 | { | |
185 | fn from_operation_state( | |
186 | operation_state: &OperationState, | |
187 | runtime_state: &RuntimeState, | |
188 | object: &O, | |
189 | operation: &D, | |
190 | ) -> Result<Self, OperationError<anyhow::Error>> { | |
191 | Ok(T::from_operation_state(operation_state, runtime_state, object, operation).ok()) | |
174 | impl<T: FromState> FromState for StateExtractor<T> { | |
175 | fn from_state(state: &mut State) -> Result<Self, anyhow::Error> { | |
176 | todo!() | |
192 | 177 | } |
193 | 178 | } |
179 | ||
180 | // pub trait FromOperationState<O, D>: Sized { | |
181 | // fn from_operation_state( | |
182 | // operation_state: &OperationState, | |
183 | // state: &mut State, | |
184 | // object: &O, | |
185 | // operation: &D, | |
186 | // ) -> Result<Self, OperationError<anyhow::Error>>; | |
187 | // } | |
188 | ||
189 | // impl<O, D> FromOperationState<O, D> for RuntimeHandle { | |
190 | // fn from_operation_state( | |
191 | // _operation_state: &OperationState, | |
192 | // state: &mut State, | |
193 | // _object: &O, | |
194 | // _operation: &D, | |
195 | // ) -> Result<Self, OperationError<anyhow::Error>> { | |
196 | // Ok(unsafe { RuntimeHandle::from_vtable(runtime_state.vtable) }) | |
197 | // } | |
198 | // } | |
199 | ||
200 | // impl<O, D, T> FromOperationState<O, D> for Option<T> | |
201 | // where | |
202 | // T: FromOperationState<O, D>, | |
203 | // { | |
204 | // fn from_operation_state( | |
205 | // operation_state: &OperationState, | |
206 | // state: &mut State, | |
207 | // object: &O, | |
208 | // operation: &D, | |
209 | // ) -> Result<Self, OperationError<anyhow::Error>> { | |
210 | // Ok(T::from_operation_state(operation_state, runtime_state, object, operation).ok()) | |
211 | // } | |
212 | // } |
giterated-plugin/src/callback/setting.rs
@@ -1,49 +1,50 @@ | ||
1 | 1 | use std::future::Future; |
2 | 2 | |
3 | use giterated_models::{ | |
4 | error::OperationError, | |
5 | object::GiteratedObject, | |
6 | settings::{AnySetting, Setting}, | |
3 | use giterated_abi::{ | |
4 | callback::{Callback, CallbackPtr}, | |
5 | value_ex::FfiValueUntyped, | |
6 | vtable::{Object, Setting}, | |
7 | FfiValueMut, FfiValueRef, | |
7 | 8 | }; |
9 | use giterated_models::{error::OperationError, object::GiteratedObject}; | |
8 | 10 | |
9 | 11 | use crate::{ |
10 | 12 | future::{RuntimeFuture, RuntimeFuturesExt}, |
11 | 13 | new_stack::PluginState, |
12 | AnyObject, NewAnySetting, | |
14 | state::State, | |
13 | 15 | }; |
14 | 16 | |
15 | use super::{CallbackPtr, RuntimeState}; | |
17 | use super::RuntimeState; | |
16 | 18 | |
17 | #[derive(Clone, Copy)] | |
18 | pub struct SettingGetterCallback { | |
19 | pub callback_ptr: CallbackPtr, | |
20 | pub func: unsafe extern "C" fn( | |
21 | CallbackPtr, | |
22 | runtime_state: &RuntimeState, | |
23 | &PluginState, | |
24 | object: AnyObject, | |
25 | ) -> RuntimeFuture<Result<NewAnySetting, ()>>, | |
19 | pub struct SettingGetterCallback(FfiValueUntyped); | |
20 | ||
21 | impl Callback for SettingGetterCallback { | |
22 | type CallbackFunc = unsafe extern "C" fn( | |
23 | CallbackPtr<SettingGetterCallback>, | |
24 | state: FfiValueMut<State>, | |
25 | object: FfiValueRef<Object>, | |
26 | ) -> RuntimeFuture<Result<Setting, ()>>; | |
26 | 27 | } |
27 | 28 | |
28 | 29 | impl SettingGetterCallback { |
29 | pub fn new<S, O, OS, T: IntoPluginSettingGetter<S, O, OS>>(callback: T) -> Self { | |
30 | Self { | |
31 | func: T::get_setting, | |
32 | callback_ptr: callback.callback_ptr(), | |
33 | } | |
34 | } | |
30 | // pub fn new<S, O, OS, T: IntoPluginSettingGetter<S, O, OS>>(callback: T) -> Self { | |
31 | // Self { | |
32 | // func: T::get_setting, | |
33 | // callback_ptr: callback.callback_ptr(), | |
34 | // } | |
35 | // } | |
35 | 36 | } |
36 | 37 | |
37 | 38 | pub trait IntoPluginSettingGetter<S, O, OS> { |
38 | 39 | unsafe extern "C" fn get_setting( |
39 | callback_ptr: CallbackPtr, | |
40 | runtime_state: &RuntimeState, | |
41 | state: &PluginState, | |
42 | object: AnyObject, | |
43 | ) -> RuntimeFuture<Result<NewAnySetting, ()>>; | |
40 | callback_ptr: CallbackPtr<SettingGetterCallback>, | |
41 | state: FfiValueMut<State>, | |
42 | object: FfiValueRef<Object>, | |
43 | ) -> RuntimeFuture<Result<Setting, ()>>; | |
44 | 44 | |
45 | fn callback_ptr(&self) -> CallbackPtr { | |
46 | unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } | |
45 | fn callback_ptr(&self) -> CallbackPtr<SettingGetterCallback> { | |
46 | // unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } | |
47 | todo!() | |
47 | 48 | } |
48 | 49 | } |
49 | 50 | |
@@ -52,55 +53,57 @@ where | ||
52 | 53 | Fut: Future<Output = Result<OS, OperationError<anyhow::Error>>> + Send + Sync + 'static, |
53 | 54 | S: Clone + Send + Sync + 'static, |
54 | 55 | O: GiteratedObject + Send + Sync + 'static, |
55 | OS: Setting + Send + Sync + 'static, | |
56 | OS: giterated_models::settings::Setting + Send + Sync + 'static, | |
56 | 57 | F: Fn(S, O) -> Fut + Send + Sync + 'static, |
57 | 58 | { |
58 | 59 | unsafe extern "C" fn get_setting( |
59 | callback: CallbackPtr, | |
60 | runtime_state: &RuntimeState, | |
61 | state: &PluginState, | |
62 | mut object: AnyObject, | |
63 | ) -> RuntimeFuture<Result<NewAnySetting, ()>> { | |
64 | let _guard = trace_span!( | |
65 | "get_setting handler", | |
66 | object = O::object_name(), | |
67 | setting = OS::name() | |
68 | ) | |
69 | .entered(); | |
70 | let state = unsafe { state.transmute_ref::<S>() }; | |
71 | ||
72 | let object = unsafe { object.transmute_owned::<O>() }; | |
73 | ||
74 | // Cast the callback ptr to ourselves | |
75 | let callback: *const F = std::mem::transmute(callback.0); | |
76 | let callback = callback.as_ref().unwrap(); | |
77 | ||
78 | let state = state.clone(); | |
79 | runtime_state.spawn_future(async move { | |
80 | let result = callback(state, *object).await; | |
81 | ||
82 | match result { | |
83 | Ok(success) => unsafe { Ok(NewAnySetting::new(success)) }, | |
84 | Err(err) => match err { | |
85 | OperationError::Operation(_) => todo!(), | |
86 | OperationError::Internal(_) => todo!(), | |
87 | OperationError::Unhandled => todo!(), | |
88 | }, | |
89 | } | |
90 | }) | |
60 | callback: CallbackPtr<SettingGetterCallback>, | |
61 | state: FfiValueMut<State>, | |
62 | mut object: FfiValueRef<Object>, | |
63 | ) -> RuntimeFuture<Result<Setting, ()>> { | |
64 | // let _guard = trace_span!( | |
65 | // "get_setting handler", | |
66 | // object = O::object_name(), | |
67 | // setting = OS::name() | |
68 | // ) | |
69 | // .entered(); | |
70 | // let state = unsafe { state.transmute_ref::<S>() }; | |
71 | ||
72 | // let object = unsafe { object.transmute_owned::<O>() }; | |
73 | ||
74 | // // Cast the callback ptr to ourselves | |
75 | // let callback: *const F = std::mem::transmute(callback.0); | |
76 | // let callback = callback.as_ref().unwrap(); | |
77 | ||
78 | // let state = state.clone(); | |
79 | // runtime_state.spawn_future(async move { | |
80 | // let result = callback(state, *object).await; | |
81 | ||
82 | // match result { | |
83 | // Ok(success) => unsafe { Ok(NewAnySetting::new(success)) }, | |
84 | // Err(err) => match err { | |
85 | // OperationError::Operation(_) => todo!(), | |
86 | // OperationError::Internal(_) => todo!(), | |
87 | // OperationError::Unhandled => todo!(), | |
88 | // }, | |
89 | // } | |
90 | ||
91 | todo!() | |
92 | // }) | |
91 | 93 | } |
92 | 94 | } |
93 | 95 | |
94 | 96 | pub trait IntoPluginSettingSetter<S, O, OS> { |
95 | 97 | unsafe extern "C" fn set_setting( |
96 | callback_ptr: CallbackPtr, | |
98 | callback_ptr: CallbackPtr<SettingGetterCallback>, | |
97 | 99 | state: &PluginState, |
98 | object: AnyObject, | |
99 | setting: AnySetting, | |
100 | object: FfiValueRef<Object>, | |
101 | setting: Setting, | |
100 | 102 | ) -> RuntimeFuture<Result<(), ()>>; |
101 | 103 | |
102 | fn callback_ptr(&self) -> CallbackPtr { | |
103 | unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } | |
104 | fn callback_ptr(&self) -> CallbackPtr<SettingGetterCallback> { | |
105 | // unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } | |
106 | todo!() | |
104 | 107 | } |
105 | 108 | } |
106 | 109 | |
@@ -109,28 +112,28 @@ where | ||
109 | 112 | Fut: Future<Output = Result<(), OperationError<anyhow::Error>>>, |
110 | 113 | S: Clone, |
111 | 114 | O: GiteratedObject, |
112 | OS: Setting, | |
115 | OS: giterated_models::settings::Setting, | |
113 | 116 | F: Fn(S, O, OS) -> Fut, |
114 | 117 | { |
115 | 118 | unsafe extern "C" fn set_setting( |
116 | callback: CallbackPtr, | |
119 | callback: CallbackPtr<SettingGetterCallback>, | |
117 | 120 | state: &PluginState, |
118 | mut object: AnyObject, | |
119 | _setting: AnySetting, | |
121 | mut object: FfiValueRef<Object>, | |
122 | _setting: Setting, | |
120 | 123 | ) -> RuntimeFuture<Result<(), ()>> { |
121 | let _guard = trace_span!( | |
122 | "get_setting handler", | |
123 | object = O::object_name(), | |
124 | setting = OS::name() | |
125 | ) | |
126 | .entered(); | |
127 | let _state = unsafe { state.transmute_ref::<S>() }; | |
124 | // let _guard = trace_span!( | |
125 | // "get_setting handler", | |
126 | // object = O::object_name(), | |
127 | // setting = OS::name() | |
128 | // ) | |
129 | // .entered(); | |
130 | // let _state = unsafe { state.transmute_ref::<S>() }; | |
128 | 131 | |
129 | let _object = unsafe { object.transmute_owned::<O>() }; | |
132 | // let _object = unsafe { object.transmute_owned::<O>() }; | |
130 | 133 | |
131 | // Cast the callback ptr to ourselves | |
132 | let callback: *const F = std::mem::transmute(callback.0); | |
133 | let _callback = callback.as_ref().unwrap(); | |
134 | // // Cast the callback ptr to ourselves | |
135 | // let callback: *const F = std::mem::transmute(callback.0); | |
136 | // let _callback = callback.as_ref().unwrap(); | |
134 | 137 | |
135 | 138 | // let result = callback(state.clone(), *object); |
136 | 139 | |
@@ -142,39 +145,41 @@ where | ||
142 | 145 | } |
143 | 146 | } |
144 | 147 | |
145 | pub struct SettingChangeCallback { | |
146 | func: unsafe extern "C" fn( | |
148 | pub struct SettingChangeCallback(FfiValueUntyped); | |
149 | ||
150 | impl Callback for SettingChangeCallback { | |
151 | type CallbackFunc = unsafe extern "C" fn( | |
147 | 152 | &PluginState, |
148 | object: AnyObject, | |
153 | object: FfiValueRef<Object>, | |
149 | 154 | setting_name: &str, |
150 | new_setting: NewAnySetting, | |
151 | ), | |
155 | new_setting: Setting, | |
156 | ); | |
152 | 157 | } |
153 | 158 | |
154 | 159 | pub trait IntoSettingChangeCallback<S, O> { |
155 | 160 | unsafe extern "C" fn setting_changed( |
156 | 161 | state: &PluginState, |
157 | object: AnyObject, | |
162 | object: FfiValueRef<Object>, | |
158 | 163 | setting_name: &str, |
159 | new_setting: NewAnySetting, | |
164 | new_setting: Setting, | |
160 | 165 | ); |
161 | 166 | } |
162 | 167 | |
163 | 168 | impl<F, S, O> IntoSettingChangeCallback<S, O> for F { |
164 | 169 | unsafe extern "C" fn setting_changed( |
165 | 170 | _state: &PluginState, |
166 | _object: AnyObject, | |
171 | _object: FfiValueRef<Object>, | |
167 | 172 | _setting_name: &str, |
168 | _new_setting: NewAnySetting, | |
173 | _new_setting: Setting, | |
169 | 174 | ) { |
170 | 175 | todo!() |
171 | 176 | } |
172 | 177 | } |
173 | 178 | |
174 | impl SettingChangeCallback { | |
175 | pub fn new<S, O, T: IntoSettingChangeCallback<S, O>>() -> Self { | |
176 | Self { | |
177 | func: T::setting_changed, | |
178 | } | |
179 | } | |
180 | } | |
179 | // impl SettingChangeCallback { | |
180 | // pub fn new<S, O, T: IntoSettingChangeCallback<S, O>>() -> Self { | |
181 | // Self { | |
182 | // func: T::setting_changed, | |
183 | // } | |
184 | // } | |
185 | // } |
giterated-plugin/src/callback/value.rs
@@ -1,46 +1,47 @@ | ||
1 | 1 | use std::future::Future; |
2 | 2 | |
3 | use giterated_abi::{ | |
4 | callback::{Callback, CallbackPtr}, | |
5 | result::{FfiError, FfiResult}, | |
6 | vtable::{Object, Value}, | |
7 | FfiSliceRef, FfiValueMut, FfiValueRef, | |
8 | }; | |
3 | 9 | use giterated_models::{ |
4 | 10 | error::OperationError, object::GiteratedObject, value::GiteratedObjectValue, |
5 | 11 | }; |
6 | 12 | |
7 | use crate::{ | |
8 | future::{RuntimeFuture, RuntimeFuturesExt}, | |
9 | new_stack::PluginState, | |
10 | vtable::{AnyObject, NewAnyValue}, | |
11 | }; | |
13 | use crate::{future::RuntimeFuture, new_stack::PluginState, state::State}; | |
12 | 14 | |
13 | use super::{CallbackPtr, RuntimeState}; | |
15 | use super::{RuntimeState, SettingGetterCallback}; | |
14 | 16 | |
15 | 17 | #[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, ()>>, | |
18 | pub struct ValueGetterCallback(CallbackPtr<ValueGetterCallback>); | |
19 | ||
20 | impl Callback for ValueGetterCallback { | |
21 | type CallbackFunc = unsafe extern "C" fn( | |
22 | CallbackPtr<ValueGetterCallback>, | |
23 | state: FfiValueMut<State>, | |
24 | object: FfiValueRef<Object>, | |
25 | ) -> RuntimeFuture<FfiResult<Value, FfiError>>; | |
24 | 26 | } |
25 | 27 | |
26 | 28 | 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 | } | |
29 | // pub fn new<S, O, V, T: IntoPluginValueGetter<S, O, V>>(handler: T) -> Self { | |
30 | // Self { | |
31 | // func: T::get_value, | |
32 | // callback_ptr: handler.callback_ptr(), | |
33 | // } | |
34 | // } | |
33 | 35 | } |
34 | 36 | |
35 | 37 | pub trait IntoPluginValueGetter<S, O, V> { |
36 | 38 | unsafe extern "C" fn get_value( |
37 | callback: CallbackPtr, | |
38 | runtime_state: &RuntimeState, | |
39 | state: &PluginState, | |
40 | object: AnyObject, | |
41 | ) -> RuntimeFuture<Result<NewAnyValue, ()>>; | |
39 | callback: CallbackPtr<SettingGetterCallback>, | |
40 | state: FfiValueMut<State>, | |
41 | object: FfiValueRef<Object>, | |
42 | ) -> RuntimeFuture<FfiResult<Value, FfiError>>; | |
42 | 43 | |
43 | fn callback_ptr(&self) -> CallbackPtr; | |
44 | fn callback_ptr(&self) -> CallbackPtr<SettingGetterCallback>; | |
44 | 45 | } |
45 | 46 | |
46 | 47 | impl<F, S, O, V, Fut> IntoPluginValueGetter<S, O, V> for F |
@@ -52,78 +53,84 @@ where | ||
52 | 53 | F: Fn(S, O) -> Fut + Send + Sync + 'static, |
53 | 54 | { |
54 | 55 | 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 | }) | |
56 | callback: CallbackPtr<SettingGetterCallback>, | |
57 | state: FfiValueMut<State>, | |
58 | mut object: FfiValueRef<Object>, | |
59 | ) -> RuntimeFuture<FfiResult<Value, FfiError>> { | |
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 | todo!() | |
87 | 89 | } |
88 | 90 | |
89 | fn callback_ptr(&self) -> CallbackPtr { | |
90 | unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } | |
91 | fn callback_ptr(&self) -> CallbackPtr<SettingGetterCallback> { | |
92 | todo!() | |
93 | // unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) } | |
91 | 94 | } |
92 | 95 | } |
93 | 96 | |
94 | pub struct ValueChangeCallback { | |
95 | func: unsafe extern "C" fn( | |
97 | pub struct ValueChangeCallback(CallbackPtr<ValueChangeCallback>); | |
98 | ||
99 | impl Callback for ValueChangeCallback { | |
100 | type CallbackFunc = unsafe extern "C" fn( | |
96 | 101 | &PluginState, |
97 | object: AnyObject, | |
98 | value_name: &str, | |
99 | new_value: NewAnyValue, | |
100 | ) -> RuntimeFuture<()>, | |
102 | object: FfiValueRef<Object>, | |
103 | value_name: FfiSliceRef<str>, | |
104 | new_value: Value, | |
105 | ) -> RuntimeFuture<()>; | |
101 | 106 | } |
102 | 107 | |
103 | 108 | pub trait IntoValueChangeCallback<S, O> { |
104 | 109 | unsafe extern "C" fn value_changed( |
105 | state: &PluginState, | |
106 | object: AnyObject, | |
107 | value_name: &str, | |
108 | new_value: NewAnyValue, | |
110 | callback: CallbackPtr<ValueChangeCallback>, | |
111 | state: FfiValueMut<State>, | |
112 | object: FfiValueRef<Object>, | |
113 | value_name: FfiSliceRef<str>, | |
114 | new_value: Value, | |
109 | 115 | ) -> RuntimeFuture<()>; |
110 | 116 | } |
111 | 117 | |
112 | 118 | impl<F, S, O> IntoValueChangeCallback<S, O> for F { |
113 | 119 | unsafe extern "C" fn value_changed( |
114 | _state: &PluginState, | |
115 | _object: AnyObject, | |
116 | _value_name: &str, | |
117 | _new_value: NewAnyValue, | |
120 | callback: CallbackPtr<ValueChangeCallback>, | |
121 | state: FfiValueMut<State>, | |
122 | _object: FfiValueRef<Object>, | |
123 | _value_name: FfiSliceRef<str>, | |
124 | _new_value: Value, | |
118 | 125 | ) -> RuntimeFuture<()> { |
119 | 126 | todo!() |
120 | 127 | } |
121 | 128 | } |
122 | 129 | |
123 | 130 | impl ValueChangeCallback { |
124 | pub fn new<S, O, T: IntoValueChangeCallback<S, O>>() -> Self { | |
125 | Self { | |
126 | func: T::value_changed, | |
127 | } | |
128 | } | |
131 | // pub fn new<S, O, T: IntoValueChangeCallback<S, O>>() -> Self { | |
132 | // Self { | |
133 | // func: T::value_changed, | |
134 | // } | |
135 | // } | |
129 | 136 | } |
giterated-plugin/src/future.rs
@@ -9,7 +9,7 @@ use std::{ | ||
9 | 9 | task::{Context, RawWaker, RawWakerVTable, Waker}, |
10 | 10 | }; |
11 | 11 | |
12 | use crate::{callback::RuntimeState, new_stack::PluginState, FFIBox}; | |
12 | use crate::{callback::RuntimeState, new_stack::PluginState}; | |
13 | 13 | |
14 | 14 | #[repr(C)] |
15 | 15 | pub struct RuntimeWakerCallback { |
@@ -51,15 +51,17 @@ impl RuntimeFuturesExt for RuntimeState { | ||
51 | 51 | &self, |
52 | 52 | future: F, |
53 | 53 | ) -> RuntimeFuture<Output> { |
54 | let type_eraser = async move { | |
55 | let result = future.await; | |
54 | // let type_eraser = async move { | |
55 | // let result = future.await; | |
56 | 56 | |
57 | FFIBox::from_box(Box::new(result)).untyped() | |
58 | }; | |
57 | // FFIBox::from_box(Box::new(result)).untyped() | |
58 | // }; | |
59 | ||
60 | // let runtime_future = unsafe { FfiFuture::from_raw(poll_local, type_eraser.boxed()) }; | |
59 | 61 | |
60 | let runtime_future = unsafe { FfiFuture::from_raw(poll_local, type_eraser.boxed()) }; | |
62 | // RuntimeFuture(runtime_future) | |
61 | 63 | |
62 | RuntimeFuture(runtime_future) | |
64 | todo!() | |
63 | 65 | } |
64 | 66 | } |
65 | 67 |
giterated-plugin/src/handle.rs
@@ -2,6 +2,10 @@ use std::{collections::HashMap, marker::PhantomData, sync::Arc}; | ||
2 | 2 | |
3 | 3 | use anyhow::Error; |
4 | 4 | use dlopen2::wrapper::Container; |
5 | use giterated_abi::{ | |
6 | callback::CallbackPtr, | |
7 | vtable::{operation::Operation, Object, Setting, VTable, Value}, | |
8 | }; | |
5 | 9 | use giterated_models::operation::OperationState; |
6 | 10 | use semver::Version; |
7 | 11 | use tracing::{debug, trace}; |
@@ -14,7 +18,7 @@ use crate::{ | ||
14 | 18 | ObjectOperationPair, ObjectSettingPair, ObjectValuePair, PluginMeta, PluginState, |
15 | 19 | TypeMetadata, |
16 | 20 | }, |
17 | vtable::{InitializationVTable, ObjectVtable, OperationVTable, SettingVtable, ValueVTable}, | |
21 | vtable::Initialization, | |
18 | 22 | GiteratedPluginApi, |
19 | 23 | }; |
20 | 24 | |
@@ -22,7 +26,7 @@ use crate::{ | ||
22 | 26 | pub struct PluginHandle { |
23 | 27 | pub meta: PluginMeta, |
24 | 28 | pub raw: Arc<Container<GiteratedPluginApi>>, |
25 | pub initialization: Arc<PluginInitializationState>, | |
29 | pub domain_metadata: Arc<TypeMetadata>, | |
26 | 30 | pub state: PluginState, |
27 | 31 | } |
28 | 32 | |
@@ -54,8 +58,8 @@ impl PluginHandle { | ||
54 | 58 | Ok(Self { |
55 | 59 | raw: Arc::new(handle), |
56 | 60 | meta: metadata, |
57 | initialization: Arc::new(initalization), | |
58 | 61 | state: init_state, |
62 | domain_metadata: todo!(), | |
59 | 63 | }) |
60 | 64 | } |
61 | 65 | |
@@ -125,9 +129,10 @@ pub struct PluginSubstackBuilder {} | ||
125 | 129 | #[derive(Default)] |
126 | 130 | pub struct PluginInitializationState { |
127 | 131 | pub type_metadata: TypeMetadata, |
128 | pub operation_handlers: HashMap<ObjectOperationPair<'static>, OperationHandlerCallback>, | |
129 | pub value_getters: HashMap<ObjectValuePair<'static>, ValueGetterCallback>, | |
130 | pub setting_getters: HashMap<ObjectSettingPair<'static>, SettingGetterCallback>, | |
132 | pub operation_handlers: | |
133 | HashMap<ObjectOperationPair<'static>, CallbackPtr<OperationHandlerCallback>>, | |
134 | pub value_getters: HashMap<ObjectValuePair<'static>, CallbackPtr<ValueGetterCallback>>, | |
135 | pub setting_getters: HashMap<ObjectSettingPair<'static>, CallbackPtr<SettingGetterCallback>>, | |
131 | 136 | } |
132 | 137 | |
133 | 138 | impl PluginInitializationState { |
@@ -142,8 +147,8 @@ pub struct PluginInitializationTable<'a> { | ||
142 | 147 | } |
143 | 148 | |
144 | 149 | impl<'a> PluginInitializationTable<'a> { |
145 | pub unsafe fn func_table(&mut self) -> InitializationVTable { | |
146 | InitializationVTable { | |
150 | pub unsafe fn func_table(&mut self) -> &'static VTable<Initialization> { | |
151 | VTable::new(&Initialization { | |
147 | 152 | register_object, |
148 | 153 | register_operation, |
149 | 154 | register_setting, |
@@ -151,14 +156,14 @@ impl<'a> PluginInitializationTable<'a> { | ||
151 | 156 | operation_handler, |
152 | 157 | value_getter, |
153 | 158 | setting_getter, |
154 | } | |
159 | }) | |
155 | 160 | } |
156 | 161 | } |
157 | 162 | |
158 | 163 | unsafe extern "C" fn register_object( |
159 | 164 | state: *mut PluginInitializationState, |
160 | 165 | object_kind: &'static str, |
161 | vtable: ObjectVtable, | |
166 | vtable: &'static VTable<Object>, | |
162 | 167 | ) { |
163 | 168 | let mut state = Box::from_raw(state); |
164 | 169 | |
@@ -171,7 +176,7 @@ unsafe extern "C" fn register_operation( | ||
171 | 176 | state: *mut PluginInitializationState, |
172 | 177 | object_kind: &'static str, |
173 | 178 | operation_name: &'static str, |
174 | vtable: OperationVTable, | |
179 | vtable: &'static VTable<Operation>, | |
175 | 180 | ) { |
176 | 181 | let mut state = Box::from_raw(state); |
177 | 182 | |
@@ -186,7 +191,7 @@ unsafe extern "C" fn register_setting( | ||
186 | 191 | state: *mut PluginInitializationState, |
187 | 192 | object_kind: &'static str, |
188 | 193 | setting_name: &'static str, |
189 | vtable: SettingVtable, | |
194 | vtable: &'static VTable<Setting>, | |
190 | 195 | ) { |
191 | 196 | let mut state = Box::from_raw(state); |
192 | 197 | |
@@ -201,7 +206,7 @@ unsafe extern "C" fn register_value( | ||
201 | 206 | state: *mut PluginInitializationState, |
202 | 207 | object_kind: &'static str, |
203 | 208 | value_name: &'static str, |
204 | vtable: ValueVTable, | |
209 | vtable: &'static VTable<Value>, | |
205 | 210 | ) { |
206 | 211 | let mut state = Box::from_raw(state); |
207 | 212 | |
@@ -216,7 +221,7 @@ unsafe extern "C" fn operation_handler( | ||
216 | 221 | state: *mut PluginInitializationState, |
217 | 222 | object_kind: &'static str, |
218 | 223 | operation_name: &'static str, |
219 | handler: OperationHandlerCallback, | |
224 | handler: CallbackPtr<OperationHandlerCallback>, | |
220 | 225 | ) { |
221 | 226 | let mut state = Box::from_raw(state); |
222 | 227 | |
@@ -234,7 +239,7 @@ unsafe extern "C" fn value_getter( | ||
234 | 239 | state: *mut PluginInitializationState, |
235 | 240 | object_kind: &'static str, |
236 | 241 | value_name: &'static str, |
237 | handler: ValueGetterCallback, | |
242 | handler: CallbackPtr<ValueGetterCallback>, | |
238 | 243 | ) { |
239 | 244 | let mut state = Box::from_raw(state); |
240 | 245 | |
@@ -251,7 +256,7 @@ unsafe extern "C" fn setting_getter( | ||
251 | 256 | state: *mut PluginInitializationState, |
252 | 257 | object_kind: &'static str, |
253 | 258 | setting_name: &'static str, |
254 | handler: SettingGetterCallback, | |
259 | handler: CallbackPtr<SettingGetterCallback>, | |
255 | 260 | ) { |
256 | 261 | let mut state = Box::from_raw(state); |
257 | 262 |
giterated-plugin/src/lib.rs
@@ -4,6 +4,7 @@ pub mod callback; | ||
4 | 4 | pub mod future; |
5 | 5 | pub mod handle; |
6 | 6 | pub mod new_stack; |
7 | pub mod state; | |
7 | 8 | pub mod vtable; |
8 | 9 | |
9 | 10 | #[macro_use] |
@@ -14,17 +15,17 @@ use std::{marker::PhantomData, mem::forget}; | ||
14 | 15 | use callback::RuntimeState; |
15 | 16 | use dlopen2::wrapper::WrapperApi; |
16 | 17 | |
18 | use giterated_abi::vtable::VTable; | |
17 | 19 | use handle::PluginInitializationState; |
18 | 20 | use new_stack::{FFIPluginMeta, PluginState}; |
19 | 21 | |
20 | pub use vtable::{AnyFailure, AnyObject, AnyOperation, AnySuccess, NewAnySetting, NewAnyValue}; | |
21 | use vtable::{HostVTable, InitializationVTable}; | |
22 | use vtable::{HostVTable, Initialization}; | |
22 | 23 | |
23 | 24 | #[derive(WrapperApi)] |
24 | 25 | pub struct GiteratedPluginApi { |
25 | 26 | plugin_meta: unsafe extern "C" fn() -> FFIPluginMeta, |
26 | 27 | load_host_vtable: unsafe extern "C" fn(vtable: &HostVTable), |
27 | load_initialization_vtable: unsafe extern "C" fn(vtable: &InitializationVTable), | |
28 | load_initialization_vtable: unsafe extern "C" fn(vtable: &'static VTable<Initialization>), | |
28 | 29 | initialize: unsafe extern "C" fn(runtime_state: *const RuntimeState) -> PluginState, |
29 | 30 | initialize_registration: unsafe extern "C" fn( |
30 | 31 | init_state: *mut PluginInitializationState, |
@@ -32,148 +33,8 @@ pub struct GiteratedPluginApi { | ||
32 | 33 | load_type_metadata: unsafe extern "C" fn(metadata: *mut ()), |
33 | 34 | } |
34 | 35 | |
35 | #[repr(C)] | |
36 | pub struct FFIBox<T: ?Sized>(*mut T); | |
37 | ||
38 | impl<T: ?Sized> FFIBox<T> { | |
39 | pub fn from_box(src: Box<T>) -> Self { | |
40 | Self(Box::into_raw(src)) | |
41 | } | |
42 | ||
43 | pub fn untyped(self) -> FFIBox<()> { | |
44 | FFIBox(self.0 as *mut ()) | |
45 | } | |
46 | ||
47 | pub unsafe fn retype<N>(self) -> FFIBox<N> { | |
48 | FFIBox(self.0 as *mut N) | |
49 | } | |
50 | ||
51 | pub unsafe fn into_box(self) -> Box<T> { | |
52 | Box::from_raw(self.0) | |
53 | } | |
54 | ||
55 | pub unsafe fn transmute_ref<N>(&self) -> &N { | |
56 | unsafe { (self.0 as *const N).as_ref() }.unwrap() | |
57 | } | |
58 | } | |
59 | ||
60 | impl ToString for FFIBox<str> { | |
61 | fn to_string(&self) -> String { | |
62 | let slice: Box<[u8]> = unsafe { Box::from_raw(self.0.clone() as *mut _) }; | |
63 | ||
64 | let string = unsafe { std::str::from_boxed_utf8_unchecked(slice) }; | |
65 | ||
66 | String::from(string) | |
67 | } | |
68 | } | |
69 | ||
70 | impl<T: ?Sized> AsRef<T> for FFIBox<T> { | |
71 | fn as_ref(&self) -> &T { | |
72 | unsafe { self.0.as_ref() }.unwrap() | |
73 | } | |
74 | } | |
75 | ||
76 | impl<T: ?Sized> std::ops::Deref for FFIBox<T> { | |
77 | type Target = T; | |
78 | ||
79 | fn deref(&self) -> &Self::Target { | |
80 | unsafe { self.0.as_ref() }.unwrap() | |
81 | } | |
82 | } | |
83 | ||
84 | #[repr(transparent)] | |
85 | pub struct FFI<T, Ownership: FfiOwnershipDrop> { | |
86 | /// Can either be a pointer to `FFIData<T>` or to `T` | |
87 | /// depending on the ownership of the FFI reference. | |
88 | inner: *const (), | |
89 | _marker: PhantomData<(T, Ownership)>, | |
36 | pub mod plugin { | |
37 | pub use giterated_macros::plugin_init as init; | |
90 | 38 | } |
91 | 39 | |
92 | #[repr(C)] | |
93 | pub struct FFIData<T> { | |
94 | /// SAFETY: THIS VALUE COULD BE NULL. | |
95 | drop_fn: *const extern "C" fn(*const FFIData<T>), | |
96 | drop_state: *const (), | |
97 | ||
98 | allocation: T, | |
99 | } | |
100 | ||
101 | pub struct Owned; | |
102 | ||
103 | impl FfiOwnershipDrop for Owned {} | |
104 | ||
105 | pub struct StackOwned; | |
106 | ||
107 | impl FfiOwnershipDrop for StackOwned {} | |
108 | ||
109 | trait FfiOwnershipDrop {} | |
110 | ||
111 | pub struct PinnedRef; | |
112 | ||
113 | impl FfiOwnershipDrop for PinnedRef {} | |
114 | ||
115 | pub struct PinnedMut; | |
116 | ||
117 | impl FfiOwnershipDrop for PinnedMut {} | |
118 | ||
119 | impl<T> FFI<T, Owned> { | |
120 | pub fn place_heap(value: T) -> FFI<T, Owned> { | |
121 | todo!() | |
122 | } | |
123 | ||
124 | pub fn ref_guard<'a>(&'a self) -> StackPinnedGuard<'a, T> { | |
125 | todo!() | |
126 | } | |
127 | } | |
128 | ||
129 | impl<T> FFI<T, StackOwned> { | |
130 | pub fn place_stack<'a>(value: T) -> StackPinned<'a, T> { | |
131 | todo!() | |
132 | } | |
133 | } | |
134 | ||
135 | pub struct StackPinned<'a, T> { | |
136 | descriptor: FFIData<T>, | |
137 | _lifetime: PhantomData<&'a ()>, | |
138 | } | |
139 | ||
140 | impl<'a, T> StackPinned<'a, T> { | |
141 | pub unsafe fn grant_ref(&self) -> FFI<T, PinnedRef> { | |
142 | todo!() | |
143 | } | |
144 | } | |
145 | ||
146 | pub struct StackPinnedGuard<'a, T> { | |
147 | pinned_owned: &'a FFI<T, Owned>, | |
148 | } | |
149 | ||
150 | impl<'a, T> StackPinnedGuard<'a, T> { | |
151 | pub unsafe fn grant_ref(&self) -> FFI<T, PinnedRef> { | |
152 | todo!() | |
153 | } | |
154 | } | |
155 | ||
156 | impl<T, O: FfiOwnershipDrop> Drop for FFI<T, O> { | |
157 | fn drop(&mut self) { | |
158 | todo!() | |
159 | } | |
160 | } | |
161 | ||
162 | pub struct FFISlice<T: ?Sized> { | |
163 | len: usize, | |
164 | slice: T, | |
165 | } | |
166 | ||
167 | fn example() { | |
168 | let stack_ffi_value = FFI::place_stack(()); | |
169 | ||
170 | let stack_ffi_ref = unsafe { stack_ffi_value.grant_ref() }; | |
171 | ||
172 | let foo = stack_ffi_ref; | |
173 | ||
174 | let heap_ffi_value = FFI::place_heap(()); | |
175 | ||
176 | let heap_ffi_ref_guard = heap_ffi_value.ref_guard(); | |
177 | ||
178 | let heap_ffi_ref = unsafe { heap_ffi_ref_guard.grant_ref() }; | |
179 | } | |
40 | pub use giterated_macros::plugin; |
giterated-plugin/src/new_stack/mod.rs
@@ -4,6 +4,13 @@ pub mod runtime_handler; | ||
4 | 4 | |
5 | 5 | use std::{collections::HashMap, fmt::Debug, mem::transmute, ptr::null_mut, sync::Arc}; |
6 | 6 | |
7 | use giterated_abi::{ | |
8 | callback::CallbackPtr, | |
9 | result::FfiResult, | |
10 | value_ex::FfiValueUntyped, | |
11 | vtable::{operation::Operation, Object, Setting, VTable, Value}, | |
12 | FfiSliceRef, | |
13 | }; | |
7 | 14 | use giterated_models::{ |
8 | 15 | error::OperationError, |
9 | 16 | object::{GiteratedObject, ObjectRequestError}, |
@@ -19,11 +26,8 @@ use crate::{ | ||
19 | 26 | ValueChangeCallback, ValueGetterCallback, |
20 | 27 | }, |
21 | 28 | future::RuntimeFuture, |
22 | handle::PluginHandle, | |
23 | vtable::{ | |
24 | IntoRuntimeVtable, ObjectVtable, OperationVTable, RuntimeVTable, SettingVtable, ValueVTable, | |
25 | }, | |
26 | AnyFailure, AnySuccess, | |
29 | handle::{PluginHandle, PluginInitializationState, PluginInitializationTable}, | |
30 | vtable::{IntoRuntimeVtable, RuntimeVTable}, | |
27 | 31 | }; |
28 | 32 | |
29 | 33 | use self::operation_walker::OperationHandlerRules; |
@@ -40,10 +44,10 @@ impl<S> std::ops::Deref for State<S> { | ||
40 | 44 | |
41 | 45 | #[derive(Default, Clone)] |
42 | 46 | pub struct TypeMetadata { |
43 | pub objects: HashMap<&'static str, ObjectVtable>, | |
44 | pub operations: HashMap<ObjectOperationPair<'static>, OperationVTable>, | |
45 | pub settings: HashMap<ObjectSettingPair<'static>, SettingVtable>, | |
46 | pub values: HashMap<ObjectValuePair<'static>, ValueVTable>, | |
47 | pub objects: HashMap<&'static str, &'static VTable<Object>>, | |
48 | pub operations: HashMap<ObjectOperationPair<'static>, &'static VTable<Operation>>, | |
49 | pub settings: HashMap<ObjectSettingPair<'static>, &'static VTable<Setting>>, | |
50 | pub values: HashMap<ObjectValuePair<'static>, &'static VTable<Value>>, | |
47 | 51 | } |
48 | 52 | |
49 | 53 | impl TypeMetadata { |
@@ -53,7 +57,7 @@ impl TypeMetadata { | ||
53 | 57 | .as_ref() |
54 | 58 | } |
55 | 59 | |
56 | pub fn register_object(&mut self, object_kind: &'static str, vtable: ObjectVtable) { | |
60 | pub fn register_object(&mut self, object_kind: &'static str, vtable: &'static VTable<Object>) { | |
57 | 61 | trace!("Registering type metadata for {}", object_kind); |
58 | 62 | |
59 | 63 | self.objects.insert(object_kind, vtable); |
@@ -63,7 +67,7 @@ impl TypeMetadata { | ||
63 | 67 | &mut self, |
64 | 68 | object_kind: &'static str, |
65 | 69 | operation_name: &'static str, |
66 | vtable: OperationVTable, | |
70 | vtable: &'static VTable<Operation>, | |
67 | 71 | ) { |
68 | 72 | trace!( |
69 | 73 | "Registering operation metadata for {}::{}", |
@@ -84,7 +88,7 @@ impl TypeMetadata { | ||
84 | 88 | &mut self, |
85 | 89 | object_kind: &'static str, |
86 | 90 | setting_name: &'static str, |
87 | vtable: SettingVtable, | |
91 | vtable: &'static VTable<Setting>, | |
88 | 92 | ) { |
89 | 93 | trace!("Registering setting {}::{}", object_kind, setting_name); |
90 | 94 | |
@@ -101,7 +105,7 @@ impl TypeMetadata { | ||
101 | 105 | &mut self, |
102 | 106 | object_kind: &'static str, |
103 | 107 | value_name: &'static str, |
104 | vtable: ValueVTable, | |
108 | vtable: &'static VTable<Value>, | |
105 | 109 | ) { |
106 | 110 | trace!("Registering value {}::{}", object_kind, value_name); |
107 | 111 | |
@@ -217,12 +221,13 @@ pub struct FfiRuntimeMetadata { | ||
217 | 221 | impl IntoRuntimeVtable for Runtime { |
218 | 222 | unsafe extern "C" fn handle( |
219 | 223 | _this: PluginState, |
220 | _object_kind: crate::FFIBox<str>, | |
221 | _operation_name: crate::FFIBox<str>, | |
222 | _object: crate::FFIBox<str>, | |
223 | _operation_payload: crate::FFIBox<[u8]>, | |
224 | _operation_state: crate::FFIBox<[u8]>, | |
225 | ) -> RuntimeFuture<Result<AnySuccess, OperationError<AnyFailure>>> { | |
224 | _object_kind: FfiSliceRef<str>, | |
225 | _operation_name: FfiSliceRef<str>, | |
226 | _object: FfiSliceRef<str>, | |
227 | _operation_payload: FfiSliceRef<[u8]>, | |
228 | _operation_state: FfiSliceRef<[u8]>, | |
229 | ) -> RuntimeFuture<FfiResult<FfiValueUntyped, OperationError<giterated_abi::result::FfiError>>> | |
230 | { | |
226 | 231 | todo!() |
227 | 232 | } |
228 | 233 | |
@@ -230,8 +235,7 @@ impl IntoRuntimeVtable for Runtime { | ||
230 | 235 | this: PluginState, |
231 | 236 | object_str: &str, |
232 | 237 | operation_state: *mut OperationState, |
233 | ) -> Result<crate::AnyObject, OperationError<giterated_models::object::ObjectRequestError>> | |
234 | { | |
238 | ) -> FfiResult<Object, OperationError<giterated_models::object::ObjectRequestError>> { | |
235 | 239 | let runtime_state = unsafe { RuntimeState::from_static() }; |
236 | 240 | |
237 | 241 | let type_metada = runtime_state |
@@ -241,21 +245,18 @@ impl IntoRuntimeVtable for Runtime { | ||
241 | 245 | .unwrap_or_else(|| { |
242 | 246 | let runtime = this.transmute_ref::<Runtime>(); |
243 | 247 | |
244 | &runtime | |
245 | .plugins | |
246 | .first() | |
247 | .unwrap() | |
248 | .initialization | |
249 | .type_metadata | |
248 | &runtime.plugins.first().unwrap().domain_metadata | |
250 | 249 | }); |
251 | 250 | |
252 | for (object_type, object_vtable) in &type_metada.objects { | |
253 | if let Ok(object) = (object_vtable.from_str)(object_str) { | |
254 | return Ok(object); | |
255 | } | |
256 | } | |
251 | // for (object_type, object_vtable) in &type_metada.objects { | |
252 | // if let Ok(object) = (object_vtable.from_str)(object_str) { | |
253 | // return Ok(object); | |
254 | // } | |
255 | // } | |
256 | ||
257 | // Err(OperationError::Operation(ObjectRequestError::Invalid)) | |
257 | 258 | |
258 | Err(OperationError::Operation(ObjectRequestError::Invalid)) | |
259 | todo!() | |
259 | 260 | } |
260 | 261 | } |
261 | 262 | |
@@ -278,17 +279,21 @@ impl Runtime { | ||
278 | 279 | } |
279 | 280 | } |
280 | 281 | |
281 | pub fn insert_plugin(&mut self, plugin: PluginHandle) { | |
282 | pub fn insert_plugin( | |
283 | &mut self, | |
284 | mut plugin: PluginHandle, | |
285 | mut initialization: PluginInitializationState, | |
286 | ) { | |
282 | 287 | let _guard = debug_span!("inserting plugin", meta = debug(&plugin.meta)).entered(); |
283 | 288 | |
284 | for (pair, callback) in &plugin.initialization.operation_handlers { | |
289 | for (pair, callback) in initialization.operation_handlers.drain() { | |
285 | 290 | let _guard = |
286 | 291 | trace_span!("processing operation handler callbacks", pair = debug(pair)).entered(); |
287 | 292 | |
288 | 293 | if self |
289 | 294 | .handlers |
290 | 295 | .operation_handlers |
291 | .insert(*pair, (RuntimeDomain::from_plugin(&plugin), *callback)) | |
296 | .insert(pair, (RuntimeDomain::from_plugin(&plugin), callback)) | |
292 | 297 | .is_some() |
293 | 298 | { |
294 | 299 | warn!("Warning! Insertion of handler for overwrote a previous handler.") |
@@ -297,14 +302,14 @@ impl Runtime { | ||
297 | 302 | trace!("Insertion of operation handler successful") |
298 | 303 | } |
299 | 304 | |
300 | for (pair, callback) in &plugin.initialization.value_getters { | |
305 | for (pair, callback) in initialization.value_getters.drain() { | |
301 | 306 | let _guard = |
302 | 307 | trace_span!("processing value getter callbacks", pair = debug(pair)).entered(); |
303 | 308 | |
304 | 309 | if self |
305 | 310 | .handlers |
306 | 311 | .value_getters |
307 | .insert(*pair, (RuntimeDomain::from_plugin(&plugin), *callback)) | |
312 | .insert(pair, (RuntimeDomain::from_plugin(&plugin), callback)) | |
308 | 313 | .is_some() |
309 | 314 | { |
310 | 315 | warn!("Warning! Insertion of handler for overwrote a previous handler.") |
@@ -313,14 +318,14 @@ impl Runtime { | ||
313 | 318 | trace!("Insertion of operation handler successful") |
314 | 319 | } |
315 | 320 | |
316 | for (pair, callback) in &plugin.initialization.setting_getters { | |
321 | for (pair, callback) in initialization.setting_getters { | |
317 | 322 | let _guard = |
318 | 323 | trace_span!("processing setting getter callbacks", pair = debug(pair)).entered(); |
319 | 324 | |
320 | 325 | if self |
321 | 326 | .handlers |
322 | 327 | .setting_getters |
323 | .insert(*pair, (RuntimeDomain::from_plugin(&plugin), *callback)) | |
328 | .insert(pair, (RuntimeDomain::from_plugin(&plugin), callback)) | |
324 | 329 | .is_some() |
325 | 330 | { |
326 | 331 | warn!("Warning! Insertion of setting handler for overwrote a previous handler.") |
@@ -362,12 +367,18 @@ impl Runtime { | ||
362 | 367 | |
363 | 368 | #[derive(Default)] |
364 | 369 | pub struct RuntimeHandlers { |
365 | operation_handlers: | |
366 | HashMap<ObjectOperationPair<'static>, (RuntimeDomain, OperationHandlerCallback)>, | |
367 | value_getters: HashMap<ObjectValuePair<'static>, (RuntimeDomain, ValueGetterCallback)>, | |
368 | setting_getters: HashMap<ObjectSettingPair<'static>, (RuntimeDomain, SettingGetterCallback)>, | |
369 | value_change: HashMap<ObjectValuePair<'static>, (RuntimeDomain, ValueChangeCallback)>, | |
370 | setting_change: HashMap<ObjectSettingPair<'static>, (RuntimeDomain, SettingChangeCallback)>, | |
370 | operation_handlers: HashMap< | |
371 | ObjectOperationPair<'static>, | |
372 | (RuntimeDomain, CallbackPtr<OperationHandlerCallback>), | |
373 | >, | |
374 | value_getters: | |
375 | HashMap<ObjectValuePair<'static>, (RuntimeDomain, CallbackPtr<ValueGetterCallback>)>, | |
376 | setting_getters: | |
377 | HashMap<ObjectSettingPair<'static>, (RuntimeDomain, CallbackPtr<SettingGetterCallback>)>, | |
378 | value_change: | |
379 | HashMap<ObjectValuePair<'static>, (RuntimeDomain, CallbackPtr<ValueChangeCallback>)>, | |
380 | setting_change: | |
381 | HashMap<ObjectSettingPair<'static>, (RuntimeDomain, CallbackPtr<SettingChangeCallback>)>, | |
371 | 382 | } |
372 | 383 | |
373 | 384 | unsafe impl Send for RuntimeHandlers {} |
@@ -377,7 +388,7 @@ impl RuntimeHandlers { | ||
377 | 388 | pub fn operation_handler( |
378 | 389 | &mut self, |
379 | 390 | pair: ObjectOperationPair<'static>, |
380 | handler: OperationHandlerCallback, | |
391 | handler: CallbackPtr<OperationHandlerCallback>, | |
381 | 392 | domain: RuntimeDomain, |
382 | 393 | ) { |
383 | 394 | trace!( |
@@ -400,7 +411,7 @@ impl RuntimeHandlers { | ||
400 | 411 | pub fn value_getter( |
401 | 412 | &mut self, |
402 | 413 | pair: ObjectValuePair<'static>, |
403 | handler: ValueGetterCallback, | |
414 | handler: CallbackPtr<ValueGetterCallback>, | |
404 | 415 | domain: RuntimeDomain, |
405 | 416 | ) { |
406 | 417 | trace!( |
@@ -420,7 +431,7 @@ impl RuntimeHandlers { | ||
420 | 431 | pub fn setting_getter( |
421 | 432 | &mut self, |
422 | 433 | pair: ObjectSettingPair<'static>, |
423 | handler: SettingGetterCallback, | |
434 | handler: CallbackPtr<SettingGetterCallback>, | |
424 | 435 | domain: RuntimeDomain, |
425 | 436 | ) { |
426 | 437 | trace!( |
@@ -441,7 +452,7 @@ impl RuntimeHandlers { | ||
441 | 452 | pub fn value_change( |
442 | 453 | &mut self, |
443 | 454 | pair: ObjectValuePair<'static>, |
444 | handler: ValueChangeCallback, | |
455 | handler: CallbackPtr<ValueChangeCallback>, | |
445 | 456 | domain: RuntimeDomain, |
446 | 457 | ) { |
447 | 458 | trace!( |
@@ -459,7 +470,7 @@ impl RuntimeHandlers { | ||
459 | 470 | pub fn setting_change( |
460 | 471 | &mut self, |
461 | 472 | pair: ObjectSettingPair<'static>, |
462 | handler: SettingChangeCallback, | |
473 | handler: CallbackPtr<SettingChangeCallback>, | |
463 | 474 | domain: RuntimeDomain, |
464 | 475 | ) { |
465 | 476 | trace!( |
@@ -500,10 +511,9 @@ impl RuntimeDomain { | ||
500 | 511 | } |
501 | 512 | } |
502 | 513 | |
503 | pub fn object_vtable(&self, object_kind: &str) -> Option<ObjectVtable> { | |
514 | pub fn object_vtable(&self, object_kind: &str) -> Option<&'static VTable<Object>> { | |
504 | 515 | self.plugin |
505 | .initialization | |
506 | .type_metadata | |
516 | .domain_metadata | |
507 | 517 | .objects |
508 | 518 | .get(object_kind) |
509 | 519 | .copied() |
@@ -513,28 +523,33 @@ impl RuntimeDomain { | ||
513 | 523 | &self, |
514 | 524 | object_kind: &str, |
515 | 525 | operation_name: &str, |
516 | ) -> Option<OperationVTable> { | |
526 | ) -> Option<&'static VTable<Operation>> { | |
517 | 527 | self.plugin |
518 | .initialization | |
519 | .type_metadata | |
528 | .domain_metadata | |
520 | 529 | .operations |
521 | 530 | .get(&ObjectOperationPair::new(object_kind, operation_name)) |
522 | 531 | .copied() |
523 | 532 | } |
524 | 533 | |
525 | pub fn setting_vtable(&self, object_kind: &str, setting_name: &str) -> Option<SettingVtable> { | |
534 | pub fn setting_vtable( | |
535 | &self, | |
536 | object_kind: &str, | |
537 | setting_name: &str, | |
538 | ) -> Option<&'static VTable<Setting>> { | |
526 | 539 | self.plugin |
527 | .initialization | |
528 | .type_metadata | |
540 | .domain_metadata | |
529 | 541 | .settings |
530 | 542 | .get(&ObjectSettingPair::new(object_kind, setting_name)) |
531 | 543 | .copied() |
532 | 544 | } |
533 | 545 | |
534 | pub fn value_vtable(&self, object_kind: &str, value_name: &str) -> Option<ValueVTable> { | |
546 | pub fn value_vtable( | |
547 | &self, | |
548 | object_kind: &str, | |
549 | value_name: &str, | |
550 | ) -> Option<&'static VTable<Value>> { | |
535 | 551 | self.plugin |
536 | .initialization | |
537 | .type_metadata | |
552 | .domain_metadata | |
538 | 553 | .values |
539 | 554 | .get(&ObjectValuePair::new(object_kind, value_name)) |
540 | 555 | .copied() |
giterated-plugin/src/new_stack/operation_walker.rs
@@ -1,4 +1,5 @@ | ||
1 | use crate::{callback::RuntimeState, AnyFailure, AnySuccess, FFIBox}; | |
1 | use crate::callback::RuntimeState; | |
2 | use giterated_abi::{result::FfiError, value_ex::FfiValueUntyped}; | |
2 | 3 | use giterated_models::{ |
3 | 4 | error::OperationError, operation::GiteratedOperation, settings::GetSetting, value::GetValue, |
4 | 5 | }; |
@@ -49,7 +50,7 @@ impl<'o> OperationHandlerRules<'o> { | ||
49 | 50 | runtime_state: &RuntimeState, |
50 | 51 | object: &str, |
51 | 52 | operation_payload: &[u8], |
52 | ) -> Result<AnySuccess, OperationError<AnyFailure>> { | |
53 | ) -> Result<FfiValueUntyped, OperationError<FfiError>> { | |
53 | 54 | // object_kind: `any` |
54 | 55 | // operation_kind: `typed` |
55 | 56 | if let Some(_handler) = self |
@@ -111,25 +112,27 @@ impl<'o> OperationHandlerRules<'o> { | ||
111 | 112 | operation.value_name |
112 | 113 | ); |
113 | 114 | |
114 | let object = unsafe { (object_vtable.from_str)(object) } | |
115 | .map_err(|_| OperationError::Internal(anyhow::anyhow!("yikes!")))?; | |
116 | ||
117 | let _guard = debug_span!("get_value handler"); | |
118 | ||
119 | let result = unsafe { | |
120 | (callback.func)( | |
121 | callback.callback_ptr, | |
122 | runtime_state, | |
123 | &domain.plugin.state, | |
124 | object, | |
125 | ) | |
126 | } | |
127 | .await; | |
128 | ||
129 | match result { | |
130 | Ok(value) => return Ok(value.into()), | |
131 | Err(_err) => todo!(), | |
132 | } | |
115 | // let object = unsafe { (object_vtable.from_str)(object) } | |
116 | // .map_err(|_| OperationError::Internal(anyhow::anyhow!("yikes!")))?; | |
117 | ||
118 | // let _guard = debug_span!("get_value handler"); | |
119 | ||
120 | // let result = unsafe { | |
121 | // (callback.func)( | |
122 | // callback.callback_ptr, | |
123 | // runtime_state, | |
124 | // &domain.plugin.state, | |
125 | // object, | |
126 | // ) | |
127 | // } | |
128 | // .await; | |
129 | ||
130 | // match result { | |
131 | // Ok(value) => return Ok(value.into()), | |
132 | // Err(_err) => todo!(), | |
133 | // } | |
134 | ||
135 | todo!() | |
133 | 136 | } else { |
134 | 137 | trace!("Failed to resolve handler."); |
135 | 138 | } |
@@ -166,38 +169,42 @@ impl<'o> OperationHandlerRules<'o> { | ||
166 | 169 | .ok_or_else(|| OperationError::Unhandled)?; |
167 | 170 | trace!("Resolved setting vtable for {}", operation.setting_name); |
168 | 171 | |
169 | let object = unsafe { (object_vtable.from_str)(object) } | |
170 | .map_err(|_| OperationError::Internal(anyhow::anyhow!("yikes!")))?; | |
171 | ||
172 | let _guard = debug_span!("get_value handler"); | |
173 | ||
174 | let result = unsafe { | |
175 | (callback.func)( | |
176 | callback.callback_ptr, | |
177 | runtime_state, | |
178 | &domain.plugin.state, | |
179 | object, | |
180 | ) | |
181 | } | |
182 | .await; | |
183 | ||
184 | match result { | |
185 | Ok(value) => { | |
186 | let vtable = unsafe { (value.vtable.get_setting_vtable)() }; | |
187 | let return_value: Value = serde_json::from_slice(unsafe { | |
188 | (value.vtable.serialize)(value).unwrap().as_ref() | |
189 | }) | |
190 | .unwrap(); | |
191 | ||
192 | return Ok(unsafe { | |
193 | AnySuccess::from_raw( | |
194 | FFIBox::from_box(Box::new(return_value)).untyped(), | |
195 | vtable, | |
196 | ) | |
197 | }); | |
198 | } | |
199 | Err(_err) => todo!(), | |
200 | } | |
172 | todo!() | |
173 | ||
174 | // let object = unsafe { (object_vtable.from_str)(object) } | |
175 | // .map_err(|_| OperationError::Internal(anyhow::anyhow!("yikes!")))?; | |
176 | ||
177 | // let _guard = debug_span!("get_value handler"); | |
178 | ||
179 | // let result = unsafe { | |
180 | // (callback.func())( | |
181 | // callback.callback_ptr, | |
182 | // runtime_state, | |
183 | // &domain.plugin.state, | |
184 | // object, | |
185 | // ) | |
186 | // } | |
187 | // .await; | |
188 | ||
189 | // match result { | |
190 | // Ok(value) => { | |
191 | // let vtable = unsafe { (value.vtable.get_setting_vtable)() }; | |
192 | // let return_value: Value = serde_json::from_slice(unsafe { | |
193 | // (value.vtable.serialize)(value).unwrap().as_ref() | |
194 | // }) | |
195 | // .unwrap(); | |
196 | ||
197 | // todo!() | |
198 | ||
199 | // // return Ok(unsafe { | |
200 | // // AnySuccess::from_raw( | |
201 | // // FFIBox::from_box(Box::new(return_value)).untyped(), | |
202 | // // vtable, | |
203 | // // ) | |
204 | // // }); | |
205 | // } | |
206 | // Err(_err) => todo!(), | |
207 | // } | |
201 | 208 | } else { |
202 | 209 | trace!("Failed to resolve handler."); |
203 | 210 | } |
@@ -239,24 +246,26 @@ impl<'o> OperationHandlerRules<'o> { | ||
239 | 246 | self.operation_name |
240 | 247 | ); |
241 | 248 | |
242 | let object = unsafe { (object_vtable.from_str)(object) } | |
243 | .map_err(|_| OperationError::Internal(anyhow::anyhow!("yikes!")))?; | |
244 | let operation = unsafe { (operation_vtable.deserialize)(operation_payload) } | |
245 | .map_err(|_| OperationError::Internal(anyhow::anyhow!("yikes!")))?; | |
246 | trace!("Parsed operation data"); | |
247 | ||
248 | let _guard = debug_span!("calling handler").entered(); | |
249 | let result = unsafe { | |
250 | (handler.func)( | |
251 | handler.callback_ptr, | |
252 | runtime_state, | |
253 | &domain.plugin.state, | |
254 | object, | |
255 | operation, | |
256 | ) | |
257 | }; | |
258 | ||
259 | return result.await; | |
249 | todo!() | |
250 | ||
251 | // let object = unsafe { (object_vtable.from_str)(object) } | |
252 | // .map_err(|_| OperationError::Internal(anyhow::anyhow!("yikes!")))?; | |
253 | // let operation = unsafe { (operation_vtable.deserialize)(operation_payload) } | |
254 | // .map_err(|_| OperationError::Internal(anyhow::anyhow!("yikes!")))?; | |
255 | // trace!("Parsed operation data"); | |
256 | ||
257 | // let _guard = debug_span!("calling handler").entered(); | |
258 | // let result = unsafe { | |
259 | // (handler.func)( | |
260 | // handler.callback_ptr, | |
261 | // runtime_state, | |
262 | // &domain.plugin.state, | |
263 | // object, | |
264 | // operation, | |
265 | // ) | |
266 | // }; | |
267 | ||
268 | // return result.await; | |
260 | 269 | } |
261 | 270 | |
262 | 271 | Err(OperationError::Unhandled) |
giterated-plugin/src/new_stack/runtime_handler.rs
@@ -1,7 +1,9 @@ | ||
1 | use giterated_abi::{ | |
2 | value_ex::FfiValueUntyped, | |
3 | vtable::{operation::Operation, VTable}, | |
4 | }; | |
1 | 5 | use giterated_models::error::OperationError; |
2 | 6 | |
3 | use crate::vtable::{AnyFailure, AnySuccess, OperationVTable}; | |
4 | ||
5 | 7 | use super::PluginState; |
6 | 8 | |
7 | 9 | #[repr(C)] |
@@ -20,6 +22,6 @@ unsafe impl Sync for RuntimeHandleInner {} | ||
20 | 22 | |
21 | 23 | #[repr(C)] |
22 | 24 | struct HandlerResult { |
23 | operation_vtable: OperationVTable, | |
24 | result: Result<AnySuccess, OperationError<AnyFailure>>, | |
25 | operation_vtable: VTable<Operation>, | |
26 | result: Result<FfiValueUntyped, OperationError<FfiValueUntyped>>, | |
25 | 27 | } |
giterated-plugin/src/state.rs
@@ -0,0 +1,116 @@ | ||
1 | use giterated_abi::prelude::*; | |
2 | use giterated_abi::value_ex::FfiValueUntyped; | |
3 | use giterated_abi::vtable::ObjectABI; | |
4 | use giterated_abi::vtable::VTable; | |
5 | ||
6 | #[repr(transparent)] | |
7 | pub struct State { | |
8 | inner: StateHandle, | |
9 | } | |
10 | ||
11 | #[repr(transparent)] | |
12 | struct StateHandle { | |
13 | state: FfiValue<()>, | |
14 | } | |
15 | ||
16 | #[repr(C)] | |
17 | struct StateItem<T: ?Sized> { | |
18 | /// The pointer to the next item. | |
19 | /// | |
20 | /// `next_item` is most likely always an `FfiValue<StateItem<()>>` and that's how we free them. | |
21 | next_item: *const StateItem<()>, | |
22 | pub state_uuid: u128, | |
23 | pub state: T, | |
24 | } | |
25 | ||
26 | impl Drop for State { | |
27 | fn drop(&mut self) { | |
28 | let state_manager = unsafe { StateManager::new(self) }; | |
29 | ||
30 | for state in state_manager {} | |
31 | } | |
32 | } | |
33 | ||
34 | struct StateManager<'s> { | |
35 | state: &'s mut State, | |
36 | last: Option<StateHandle>, | |
37 | } | |
38 | ||
39 | impl<'s> StateManager<'s> { | |
40 | pub unsafe fn new(handle: &'s mut State) -> Self { | |
41 | todo!() | |
42 | } | |
43 | ||
44 | pub unsafe fn write_state<S: StateUUID>(&mut self, state: S) -> Self { | |
45 | todo!() | |
46 | } | |
47 | ||
48 | pub unsafe fn get_state<S: StateUUID>(&mut self) -> Option<&S> { | |
49 | todo!() | |
50 | } | |
51 | } | |
52 | ||
53 | impl<'s> Iterator for StateManager<'s> { | |
54 | type Item = StateItem<()>; | |
55 | ||
56 | fn next(&mut self) -> Option<StateItem<()>> { | |
57 | todo!() | |
58 | } | |
59 | } | |
60 | ||
61 | pub trait StateUUID { | |
62 | fn uuid() -> u128; | |
63 | ||
64 | fn unsafe_hint_copy() -> Option<bool> { | |
65 | None | |
66 | } | |
67 | } | |
68 | ||
69 | /// State values for the current execution domain. 99.99% of the time this means "plugin-specific" | |
70 | /// | |
71 | /// The remainder 0.01% of the time it refers to the daemon's runtime domain. | |
72 | pub struct DomainState(StateItem<()>); | |
73 | ||
74 | impl StateUUID for DomainState { | |
75 | fn uuid() -> u128 { | |
76 | todo!() | |
77 | } | |
78 | } | |
79 | ||
80 | pub struct RuntimeState(StateItem<&'static VTable<Runtime>>); | |
81 | ||
82 | impl StateUUID for RuntimeState { | |
83 | fn uuid() -> u128 { | |
84 | todo!() | |
85 | } | |
86 | } | |
87 | ||
88 | impl RuntimeState { | |
89 | pub fn queue_insert_state<S: StateUUID>(&mut self, state: S) { | |
90 | todo!() | |
91 | } | |
92 | } | |
93 | ||
94 | pub struct Runtime { | |
95 | pub queue_insert_state: unsafe extern "C" fn(state_uuid: u128, state: FfiValueUntyped), | |
96 | } | |
97 | ||
98 | impl ObjectABI for Runtime { | |
99 | type VTable = Runtime; | |
100 | } | |
101 | ||
102 | pub trait FromState: Sized { | |
103 | fn from_state(state: &mut State) -> Result<Self, anyhow::Error>; | |
104 | } | |
105 | ||
106 | impl<T: StateUUID> FromState for T { | |
107 | fn from_state(state: &mut State) -> Result<Self, anyhow::Error> { | |
108 | todo!() | |
109 | } | |
110 | } | |
111 | ||
112 | impl<T: FromState> FromState for Option<T> { | |
113 | fn from_state(state: &mut State) -> Result<Self, anyhow::Error> { | |
114 | todo!() | |
115 | } | |
116 | } |
giterated-plugin/src/vtable/host.rs
@@ -1,4 +1,8 @@ | ||
1 | use super::{ObjectVtable, OperationVTable, SettingVtable, ValueVTable}; | |
1 | use giterated_abi::{ | |
2 | callback::CallbackPtr, | |
3 | vtable::{operation::Operation, Object, ObjectABI, Setting, VTable, Value}, | |
4 | }; | |
5 | ||
2 | 6 | use crate::{ |
3 | 7 | callback::{OperationHandlerCallback, SettingGetterCallback, ValueGetterCallback}, |
4 | 8 | handle::PluginInitializationState, |
@@ -10,55 +14,59 @@ pub struct HostVTable {} | ||
10 | 14 | |
11 | 15 | #[repr(C)] |
12 | 16 | #[derive(Clone, Copy)] |
13 | pub struct InitializationVTable { | |
17 | pub struct Initialization { | |
14 | 18 | pub register_object: |
15 | unsafe extern "C" fn(*mut PluginInitializationState, &'static str, ObjectVtable), | |
19 | unsafe extern "C" fn(*mut PluginInitializationState, &'static str, &'static VTable<Object>), | |
16 | 20 | pub register_operation: unsafe extern "C" fn( |
17 | 21 | *mut PluginInitializationState, |
18 | 22 | &'static str, |
19 | 23 | &'static str, |
20 | OperationVTable, | |
24 | &'static VTable<Operation>, | |
21 | 25 | ), |
22 | 26 | pub register_setting: unsafe extern "C" fn( |
23 | 27 | *mut PluginInitializationState, |
24 | 28 | &'static str, |
25 | 29 | &'static str, |
26 | SettingVtable, | |
30 | &'static VTable<Setting>, | |
27 | 31 | ), |
28 | 32 | pub register_value: unsafe extern "C" fn( |
29 | 33 | *mut PluginInitializationState, |
30 | 34 | &'static str, |
31 | 35 | &'static str, |
32 | ValueVTable, | |
36 | &'static VTable<Value>, | |
33 | 37 | ), |
34 | 38 | |
35 | 39 | pub operation_handler: unsafe extern "C" fn( |
36 | 40 | *mut PluginInitializationState, |
37 | 41 | &'static str, |
38 | 42 | &'static str, |
39 | OperationHandlerCallback, | |
43 | CallbackPtr<OperationHandlerCallback>, | |
40 | 44 | ), |
41 | 45 | |
42 | 46 | pub value_getter: unsafe extern "C" fn( |
43 | 47 | *mut PluginInitializationState, |
44 | 48 | &'static str, |
45 | 49 | &'static str, |
46 | ValueGetterCallback, | |
50 | CallbackPtr<ValueGetterCallback>, | |
47 | 51 | ), |
48 | 52 | |
49 | 53 | pub setting_getter: unsafe extern "C" fn( |
50 | 54 | *mut PluginInitializationState, |
51 | 55 | &'static str, |
52 | 56 | &'static str, |
53 | SettingGetterCallback, | |
57 | CallbackPtr<SettingGetterCallback>, | |
54 | 58 | ), |
55 | 59 | } |
56 | 60 | |
57 | impl Debug for InitializationVTable { | |
61 | impl ObjectABI for Initialization { | |
62 | type VTable = Initialization; | |
63 | } | |
64 | ||
65 | impl Debug for Initialization { | |
58 | 66 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
59 | 67 | f.debug_struct("InitializationVTable").finish() |
60 | 68 | } |
61 | 69 | } |
62 | 70 | |
63 | unsafe impl Sync for InitializationVTable {} | |
64 | unsafe impl Send for InitializationVTable {} | |
71 | unsafe impl Sync for Initialization {} | |
72 | unsafe impl Send for Initialization {} |
giterated-plugin/src/vtable/mod.rs
@@ -2,14 +2,6 @@ | ||
2 | 2 | //! |
3 | 3 | //! Docs here? :) |
4 | 4 | mod runtime; |
5 | mod setting; | |
6 | 5 | pub use runtime::*; |
7 | pub use setting::*; | |
8 | mod operation; | |
9 | pub use operation::*; | |
10 | mod object; | |
11 | pub use object::*; | |
12 | mod value; | |
13 | pub use value::*; | |
14 | 6 | mod host; |
15 | 7 | pub use host::*; |
giterated-plugin/src/vtable/runtime.rs
@@ -1,3 +1,9 @@ | ||
1 | use giterated_abi::{ | |
2 | result::{FfiError, FfiResult}, | |
3 | value_ex::FfiValueUntyped, | |
4 | vtable::Object, | |
5 | FfiSliceRef, | |
6 | }; | |
1 | 7 | use giterated_models::{ |
2 | 8 | error::OperationError, object::ObjectRequestError, operation::OperationState, |
3 | 9 | }; |
@@ -5,7 +11,6 @@ use giterated_models::{ | ||
5 | 11 | use crate::{ |
6 | 12 | future::RuntimeFuture, |
7 | 13 | new_stack::{PluginState, TypeMetadata}, |
8 | AnyFailure, AnyObject, AnySuccess, FFIBox, | |
9 | 14 | }; |
10 | 15 | |
11 | 16 | #[derive(Clone, Copy)] |
@@ -14,20 +19,20 @@ pub struct RuntimeVTable { | ||
14 | 19 | pub(crate) type_metadata: *const TypeMetadata, |
15 | 20 | pub(crate) handle_fn: unsafe extern "C" fn( |
16 | 21 | PluginState, |
17 | FFIBox<str>, | |
18 | FFIBox<str>, | |
19 | FFIBox<str>, | |
20 | FFIBox<[u8]>, | |
21 | FFIBox<[u8]>, | |
22 | FfiSliceRef<str>, | |
23 | FfiSliceRef<str>, | |
24 | FfiSliceRef<str>, | |
25 | FfiSliceRef<[u8]>, | |
26 | FfiSliceRef<[u8]>, | |
22 | 27 | ) -> RuntimeFuture< |
23 | Result<AnySuccess, OperationError<AnyFailure>>, | |
28 | FfiResult<FfiValueUntyped, OperationError<FfiError>>, | |
24 | 29 | >, |
25 | 30 | pub(crate) get_object: |
26 | 31 | unsafe extern "C" fn( |
27 | 32 | PluginState, |
28 | 33 | &str, |
29 | 34 | *mut OperationState, |
30 | ) -> Result<AnyObject, OperationError<ObjectRequestError>>, | |
35 | ) -> FfiResult<Object, OperationError<ObjectRequestError>>, | |
31 | 36 | } |
32 | 37 | |
33 | 38 | unsafe impl Send for RuntimeVTable {} |
@@ -36,16 +41,16 @@ unsafe impl Sync for RuntimeVTable {} | ||
36 | 41 | pub trait IntoRuntimeVtable { |
37 | 42 | unsafe extern "C" fn handle( |
38 | 43 | this: PluginState, |
39 | object_kind: FFIBox<str>, | |
40 | operation_name: FFIBox<str>, | |
41 | object: FFIBox<str>, | |
42 | operation_payload: FFIBox<[u8]>, | |
43 | operation_state: FFIBox<[u8]>, | |
44 | ) -> RuntimeFuture<Result<AnySuccess, OperationError<AnyFailure>>>; | |
44 | object_kind: FfiSliceRef<str>, | |
45 | operation_name: FfiSliceRef<str>, | |
46 | object: FfiSliceRef<str>, | |
47 | operation_payload: FfiSliceRef<[u8]>, | |
48 | operation_state: FfiSliceRef<[u8]>, | |
49 | ) -> RuntimeFuture<FfiResult<FfiValueUntyped, OperationError<FfiError>>>; | |
45 | 50 | |
46 | 51 | unsafe extern "C" fn get_object( |
47 | 52 | this: PluginState, |
48 | 53 | object_str: &str, |
49 | 54 | operation_state: *mut OperationState, |
50 | ) -> Result<AnyObject, OperationError<ObjectRequestError>>; | |
55 | ) -> FfiResult<Object, OperationError<ObjectRequestError>>; | |
51 | 56 | } |
giterated-runtime/Cargo.toml
@@ -0,0 +1,8 @@ | ||
1 | [package] | |
2 | name = "giterated-runtime" | |
3 | version = "0.1.0" | |
4 | edition = "2021" | |
5 | ||
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |
7 | ||
8 | [dependencies] |
giterated-runtime/src/lib.rs
plugins/example-plugin/src/lib.rs
@@ -1,116 +1,46 @@ | ||
1 | use std::{mem::forget, sync::OnceLock}; | |
1 | use anyhow::Error; | |
2 | use giterated_models::{error::OperationError, object::{ObjectRequest, ObjectRequestError, ObjectResponse}, user::{DisplayName, User}}; | |
3 | use giterated_plugin::{new_stack::State, plugin}; | |
4 | ||
5 | plugin!( | |
6 | name: "Example Plugin", | |
7 | version: "0.0.1", | |
8 | author: "Amber Kowalski", | |
9 | // Experimental syntax for requesting specific plugin features | |
10 | features: ["tracing", "tokio"], | |
11 | description: "An example plugin to demonstrate the development process of Giterated plugins." | |
12 | ); | |
13 | ||
14 | /// Some kind of global state for the plugin | |
15 | struct PluginState; | |
16 | ||
17 | /// The plugin's initialization function. Ran when the plugin is loaded, used to | |
18 | /// build the plugin's stack. | |
19 | #[plugin::init] | |
20 | pub fn init(builder: &mut PluginStackBuilder) -> Result<(), Error> { | |
21 | builder.insert_state(State); | |
22 | ||
23 | builder | |
24 | .object::<Instance>() | |
25 | .object::<User>(); | |
2 | 26 | |
3 | use giterated_models::{ | |
4 | error::OperationError, | |
5 | instance::Instance, | |
6 | object::{ObjectRequest, ObjectRequestError, ObjectResponse}, | |
7 | user::{DisplayName, User}, | |
8 | }; | |
9 | use giterated_plugin::{ | |
10 | handle::PluginInitializationState, | |
11 | new_stack::{FFIPluginMeta, PluginState}, | |
12 | vtable::{HostVTable, InitializationVTable}, | |
13 | }; | |
14 | use giterated_plugin_sys::PluginStackBuilder; | |
15 | use tracing::{info, trace_span, Level}; | |
16 | ||
17 | static INIT_VTABLE: OnceLock<InitializationVTable> = OnceLock::new(); | |
18 | ||
19 | #[no_mangle] | |
20 | pub extern "C" fn plugin_meta() -> FFIPluginMeta { | |
21 | const PLUGIN_NAME: &str = "Example Plugin"; | |
22 | const PLUGIN_VERSION: &str = "1.0.0"; | |
23 | ||
24 | FFIPluginMeta { | |
25 | name: PLUGIN_NAME.as_ptr(), | |
26 | name_len: PLUGIN_NAME.len(), | |
27 | version: PLUGIN_VERSION.as_ptr(), | |
28 | version_len: PLUGIN_VERSION.len(), | |
29 | } | |
30 | } | |
31 | ||
32 | #[no_mangle] | |
33 | pub extern "C" fn load_host_vtable(_vtable: &HostVTable) { | |
34 | println!("Loading vtable"); | |
35 | } | |
36 | ||
37 | #[no_mangle] | |
38 | pub extern "C" fn load_initialization_vtable(init_vtable: &InitializationVTable) { | |
39 | INIT_VTABLE.set(*init_vtable).unwrap(); | |
40 | println!("Loaded initialization vtable"); | |
41 | } | |
42 | ||
43 | #[no_mangle] | |
44 | pub extern "C" fn load_type_metadata(metadata: *mut ()) { | |
45 | unsafe { giterated_static_runtime::initialize_type_metadata(metadata) } | |
46 | println!("Initialized type metadata for plugin"); | |
47 | } | |
48 | ||
49 | #[no_mangle] | |
50 | pub extern "C" fn initialize() -> PluginState { | |
51 | tracing_subscriber::fmt() | |
52 | .pretty() | |
53 | .with_thread_names(true) | |
54 | .with_max_level(Level::TRACE) | |
55 | .init(); | |
56 | ||
57 | println!("Building runtime"); | |
58 | let runtime = tokio::runtime::Builder::new_multi_thread() | |
59 | .enable_all() | |
60 | .build() | |
61 | .unwrap(); | |
62 | ||
63 | let _guard = runtime.enter(); | |
64 | ||
65 | forget(_guard); | |
66 | ||
67 | PluginState { | |
68 | inner: Box::into_raw(Box::new(())), | |
69 | } | |
70 | } | |
71 | ||
72 | #[no_mangle] | |
73 | pub extern "C" fn initialize_registration( | |
74 | state: *mut PluginInitializationState, | |
75 | ) -> *mut PluginInitializationState { | |
76 | let _guard: tracing::span::EnteredSpan = trace_span!("initialize_registration").entered(); | |
77 | let init_vtable = INIT_VTABLE.get().unwrap(); | |
78 | let mut builder = PluginStackBuilder::new((), state, init_vtable); | |
79 | ||
80 | builder.object::<Instance>().object::<User>(); | |
81 | builder.operation(handler); | |
82 | 27 | builder.value(value_getter); |
83 | 28 | builder.setting_getter(setting_getter); |
84 | 29 | |
85 | state | |
30 | Ok(()) | |
86 | 31 | } |
87 | 32 | |
88 | 33 | async fn handler( |
89 | _state: (), | |
90 | object: Instance, | |
34 | object: User, | |
91 | 35 | operation: ObjectRequest, |
36 | state_extractor: State<PluginState> | |
92 | 37 | ) -> Result<ObjectResponse, OperationError<ObjectRequestError>> { |
93 | info!("handling operation!"); | |
94 | ||
95 | info!("Try get object {} from instance {}", operation.0, object); | |
96 | ||
97 | Ok(ObjectResponse(operation.0)) | |
98 | } | |
99 | ||
100 | async fn value_getter( | |
101 | _state: (), | |
102 | _object: User, | |
103 | ) -> Result<DisplayName, OperationError<anyhow::Error>> { | |
104 | info!("OwO, value gotten!"); | |
105 | ||
106 | Ok(DisplayName(String::from("heya!"))) | |
38 | todo!() | |
107 | 39 | } |
108 | 40 | |
109 | 41 | async fn setting_getter( |
110 | _state: (), | |
111 | _object: User, | |
112 | ) -> Result<DisplayName, OperationError<anyhow::Error>> { | |
113 | info!("OwO, setting gotten!"); | |
114 | ||
115 | Ok(DisplayName(String::from("heya! (but from a setting)"))) | |
116 | } | |
42 | object: User, | |
43 | state_extractor: State<PluginState> | |
44 | ) -> Result<DisplayName, OperationError<Error>> { | |
45 | todo!() | |
46 | } | |
46 | \ No newline at end of file |
plugins/example-plugin/src/main.rs
@@ -24,7 +24,7 @@ async fn main() -> Result<(), anyhow::Error> { | ||
24 | 24 | |
25 | 25 | info!("2"); |
26 | 26 | |
27 | runtime.insert_plugin(handle); | |
27 | // runtime.insert_plugin(handle); | |
28 | 28 | |
29 | 29 | info!("3"); |
30 | 30 |
plugins/example-plugin/src/newlib.rs
@@ -0,0 +1,179 @@ | ||
1 | plugin!( | |
2 | name: "Example Plugin", | |
3 | version: "0.0.1", | |
4 | author: "Amber Kowalski", | |
5 | // Experimental syntax for requesting specific plugin features | |
6 | features: ["tracing", "tokio"], | |
7 | description: "An example plugin to demonstrate the development process of Giterated plugins." | |
8 | ); | |
9 | ||
10 | /// Some kind of global state for the plugin | |
11 | struct PluginState; | |
12 | ||
13 | /// The plugin's initialization function. Ran when the plugin is loaded, used to | |
14 | /// build the plugin's stack. | |
15 | #[plugin::init] | |
16 | pub fn init(builder: &mut PluginStackBuilder) -> Result<(), Error> { | |
17 | builder.insert_state(State); | |
18 | ||
19 | builder | |
20 | .object::<Instance>() | |
21 | .object::<User>(); | |
22 | ||
23 | builder.value(value_getter); | |
24 | builder.setting_getter(setting_getter); | |
25 | ||
26 | Ok(()) | |
27 | } | |
28 | ||
29 | async fn handler( | |
30 | object: User, | |
31 | operation: ObjectRequest, | |
32 | state_extractor: State<PluginState> | |
33 | ) -> Result<ObjectResponse, OperationError<ObjectRequestError>> { | |
34 | todo!() | |
35 | } | |
36 | ||
37 | async fn setting_getter( | |
38 | object: User, | |
39 | state_extractor: State<PluginState> | |
40 | ) -> Result<DisplayName, OperationError<Error>> { | |
41 | todo!() | |
42 | } | |
43 | ||
44 | fn emit_statics() -> &'static str { | |
45 | r#" | |
46 | static INIT_VTABLE: OnceLock<InitializationVTable> = OnceLock::new(); | |
47 | "# | |
48 | } | |
49 | ||
50 | pub struct PluginConstants { | |
51 | plugin_name: String, | |
52 | plugin_version: String, | |
53 | plugin_author: String | |
54 | } | |
55 | ||
56 | fn emit_constants(constants: PluginConstants) -> &'static str { | |
57 | r#" | |
58 | const PLUGIN_NAME: &'static str = {constants.plugin_name}; | |
59 | const PLUGIN_VERSION: &'static str = {constants.plugin_version}; | |
60 | const PLUGIN_AUTHOR: &'static str = {constants.plugin_author}; | |
61 | "# | |
62 | } | |
63 | ||
64 | // use std::{mem::forget, sync::OnceLock}; | |
65 | ||
66 | // use giterated_models::{ | |
67 | // error::OperationError, | |
68 | // instance::Instance, | |
69 | // object::{ObjectRequest, ObjectRequestError, ObjectResponse}, | |
70 | // user::{DisplayName, User}, | |
71 | // }; | |
72 | // use giterated_plugin::{ | |
73 | // handle::PluginInitializationState, | |
74 | // new_stack::{FFIPluginMeta, PluginState}, | |
75 | // vtable::{HostVTable}, | |
76 | // }; | |
77 | // use giterated_plugin_sys::PluginStackBuilder; | |
78 | // use tracing::{info, trace_span, Level}; | |
79 | ||
80 | // static INIT_VTABLE: OnceLock<InitializationVTable> = OnceLock::new(); | |
81 | ||
82 | // #[no_mangle] | |
83 | // pub extern "C" fn plugin_meta() -> FFIPluginMeta { | |
84 | // const PLUGIN_NAME: &str = "Example Plugin"; | |
85 | // const PLUGIN_VERSION: &str = "1.0.0"; | |
86 | ||
87 | // FFIPluginMeta { | |
88 | // name: PLUGIN_NAME.as_ptr(), | |
89 | // name_len: PLUGIN_NAME.len(), | |
90 | // version: PLUGIN_VERSION.as_ptr(), | |
91 | // version_len: PLUGIN_VERSION.len(), | |
92 | // } | |
93 | // } | |
94 | ||
95 | // #[no_mangle] | |
96 | // pub extern "C" fn load_host_vtable(_vtable: &HostVTable) { | |
97 | // println!("Loading vtable"); | |
98 | // } | |
99 | ||
100 | // #[no_mangle] | |
101 | // pub extern "C" fn load_initialization_vtable(init_vtable: &InitializationVTable) { | |
102 | // INIT_VTABLE.set(*init_vtable).unwrap(); | |
103 | // println!("Loaded initialization vtable"); | |
104 | // } | |
105 | ||
106 | // #[no_mangle] | |
107 | // pub extern "C" fn load_type_metadata(metadata: *mut ()) { | |
108 | // unsafe { giterated_static_runtime::initialize_type_metadata(metadata) } | |
109 | // println!("Initialized type metadata for plugin"); | |
110 | // } | |
111 | ||
112 | // #[no_mangle] | |
113 | // pub extern "C" fn initialize() -> PluginState { | |
114 | // tracing_subscriber::fmt() | |
115 | // .pretty() | |
116 | // .with_thread_names(true) | |
117 | // .with_max_level(Level::TRACE) | |
118 | // .init(); | |
119 | ||
120 | // println!("Building runtime"); | |
121 | // let runtime = tokio::runtime::Builder::new_multi_thread() | |
122 | // .enable_all() | |
123 | // .build() | |
124 | // .unwrap(); | |
125 | ||
126 | // let _guard = runtime.enter(); | |
127 | ||
128 | // forget(_guard); | |
129 | ||
130 | // PluginState { | |
131 | // inner: Box::into_raw(Box::new(())), | |
132 | // } | |
133 | // } | |
134 | ||
135 | // #[no_mangle] | |
136 | // pub extern "C" fn initialize_registration( | |
137 | // state: *mut PluginInitializationState, | |
138 | // ) -> *mut PluginInitializationState { | |
139 | // let _guard: tracing::span::EnteredSpan = trace_span!("initialize_registration").entered(); | |
140 | // let init_vtable = INIT_VTABLE.get().unwrap(); | |
141 | // let mut builder = PluginStackBuilder::new((), state, init_vtable); | |
142 | ||
143 | // builder.object::<Instance>().object::<User>(); | |
144 | // builder.operation(handler); | |
145 | // builder.value(value_getter); | |
146 | // builder.setting_getter(setting_getter); | |
147 | ||
148 | // state | |
149 | // } | |
150 | ||
151 | // async fn handler( | |
152 | // _state: (), | |
153 | // object: Instance, | |
154 | // operation: ObjectRequest, | |
155 | // ) -> Result<ObjectResponse, OperationError<ObjectRequestError>> { | |
156 | // info!("handling operation!"); | |
157 | ||
158 | // info!("Try get object {} from instance {}", operation.0, object); | |
159 | ||
160 | // Ok(ObjectResponse(operation.0)) | |
161 | // } | |
162 | ||
163 | // async fn value_getter( | |
164 | // _state: (), | |
165 | // _object: User, | |
166 | // ) -> Result<DisplayName, OperationError<anyhow::Error>> { | |
167 | // info!("OwO, value gotten!"); | |
168 | ||
169 | // Ok(DisplayName(String::from("heya!"))) | |
170 | // } | |
171 | ||
172 | // async fn setting_getter( | |
173 | // _state: (), | |
174 | // _object: User, | |
175 | // ) -> Result<DisplayName, OperationError<anyhow::Error>> { | |
176 | // info!("OwO, setting gotten!"); | |
177 | ||
178 | // Ok(DisplayName(String::from("heya! (but from a setting)"))) | |
179 | // } |