plugin_interfaces/
symbols.rs1use crate::callbacks::HostCallbacks;
2use crate::metadata::{PluginInstanceContext, PluginMetadataFFI};
3use std::os::raw::c_char;
4
5pub struct PluginWrapper {
7 pub handler: Box<dyn crate::handler::PluginHandler>,
8 pub context: Option<PluginInstanceContext>,
9}
10
11#[repr(C)]
14pub struct PluginInterface {
15 pub plugin_ptr: *mut std::ffi::c_void,
16 pub initialize:
17 unsafe extern "C" fn(*mut std::ffi::c_void, HostCallbacks, PluginMetadataFFI) -> i32,
18 pub update_ui: unsafe extern "C" fn(
19 *mut std::ffi::c_void,
20 *const std::ffi::c_void,
21 *mut std::ffi::c_void,
22 ) -> i32,
23 pub on_mount: unsafe extern "C" fn(*mut std::ffi::c_void) -> i32,
24 pub on_dispose: unsafe extern "C" fn(*mut std::ffi::c_void) -> i32,
25 pub on_connect: unsafe extern "C" fn(*mut std::ffi::c_void) -> i32,
26 pub on_disconnect: unsafe extern "C" fn(*mut std::ffi::c_void) -> i32,
27 pub handle_message:
28 unsafe extern "C" fn(*mut std::ffi::c_void, *const c_char, *mut *mut c_char) -> i32,
29 pub get_metadata: unsafe extern "C" fn(*mut std::ffi::c_void) -> PluginMetadataFFI,
30 pub destroy: unsafe extern "C" fn(*mut std::ffi::c_void),
31}
32
33pub type CreatePluginFn = unsafe extern "C" fn() -> *mut PluginInterface;
36
37pub type DestroyPluginFn = unsafe extern "C" fn(*mut PluginInterface);
40
41pub const CREATE_PLUGIN_SYMBOL: &[u8] = b"create_plugin";
43pub const DESTROY_PLUGIN_SYMBOL: &[u8] = b"destroy_plugin";
44
45pub fn create_plugin_interface_from_handler(
48 handler: Box<dyn crate::handler::PluginHandler>,
49) -> *mut PluginInterface {
50 use std::ffi::{CStr, CString};
51
52 let wrapper = PluginWrapper {
53 handler,
54 context: None,
55 };
56 let wrapper_ptr = Box::into_raw(Box::new(wrapper)) as *mut std::ffi::c_void;
57
58 unsafe extern "C" fn initialize_wrapper(
60 ptr: *mut std::ffi::c_void,
61 callbacks: HostCallbacks,
62 metadata_ffi: PluginMetadataFFI,
63 ) -> i32 {
64 let wrapper = &mut *(ptr as *mut PluginWrapper);
65
66 let metadata = crate::metadata::convert_ffi_to_metadata(metadata_ffi);
68
69 match wrapper.handler.initialize(callbacks, metadata) {
70 Ok(context) => {
71 wrapper.context = Some(context);
72 0
73 }
74 Err(_) => -1,
75 }
76 }
77
78 unsafe extern "C" fn update_ui_wrapper(
79 ptr: *mut std::ffi::c_void,
80 ctx_ptr: *const std::ffi::c_void,
81 ui_ptr: *mut std::ffi::c_void,
82 ) -> i32 {
83 let wrapper = &mut *(ptr as *mut PluginWrapper);
84 let ctx = &*(ctx_ptr as *const crate::pluginui::Context);
85 let ui = &mut *(ui_ptr as *mut crate::pluginui::Ui);
86
87 if let Some(plugin_context) = &wrapper.context {
88 wrapper.handler.update_ui(ctx, ui, plugin_context);
89 }
90 0
91 }
92
93 unsafe extern "C" fn on_mount_wrapper(ptr: *mut std::ffi::c_void) -> i32 {
94 let wrapper = &mut *(ptr as *mut PluginWrapper);
95
96 if let Some(plugin_context) = &wrapper.context {
97 match wrapper.handler.on_mount(plugin_context) {
98 Ok(_) => 0,
99 Err(_) => -1,
100 }
101 } else {
102 -1
103 }
104 }
105
106 unsafe extern "C" fn on_dispose_wrapper(ptr: *mut std::ffi::c_void) -> i32 {
107 let wrapper = &mut *(ptr as *mut PluginWrapper);
108 if let Some(plugin_context) = &wrapper.context {
109 match wrapper.handler.on_dispose(plugin_context) {
110 Ok(_) => 0,
111 Err(_) => -1,
112 }
113 } else {
114 -1
115 }
116 }
117
118 unsafe extern "C" fn on_connect_wrapper(ptr: *mut std::ffi::c_void) -> i32 {
119 let wrapper = &mut *(ptr as *mut PluginWrapper);
120 if let Some(plugin_context) = &wrapper.context {
121 match wrapper.handler.on_connect(plugin_context) {
122 Ok(_) => 0,
123 Err(_) => -1,
124 }
125 } else {
126 -1
127 }
128 }
129
130 unsafe extern "C" fn on_disconnect_wrapper(ptr: *mut std::ffi::c_void) -> i32 {
131 let wrapper = &mut *(ptr as *mut PluginWrapper);
132 if let Some(plugin_context) = &wrapper.context {
133 match wrapper.handler.on_disconnect(plugin_context) {
134 Ok(_) => 0,
135 Err(_) => -1,
136 }
137 } else {
138 -1
139 }
140 }
141
142 unsafe extern "C" fn handle_message_wrapper(
143 ptr: *mut std::ffi::c_void,
144 message: *const c_char,
145 result: *mut *mut c_char,
146 ) -> i32 {
147 let wrapper = &mut *(ptr as *mut PluginWrapper);
148 let message_str = CStr::from_ptr(message).to_string_lossy();
149
150 if let Some(plugin_context) = &wrapper.context {
151 match wrapper.handler.handle_message(&message_str, plugin_context) {
152 Ok(response) => {
153 let response_cstring = CString::new(response).unwrap();
154 *result = response_cstring.into_raw();
155 0
156 }
157 Err(_) => -1,
158 }
159 } else {
160 -1
161 }
162 }
163
164 unsafe extern "C" fn get_metadata_wrapper(ptr: *mut std::ffi::c_void) -> PluginMetadataFFI {
165 let wrapper = &*(ptr as *mut PluginWrapper);
166 if let Some(plugin_context) = &wrapper.context {
167 let metadata = wrapper.handler.get_metadata(plugin_context);
168 metadata.to_ffi()
169 } else {
170 PluginMetadataFFI {
172 id: std::ptr::null(),
173 disabled: false,
174 name: std::ptr::null(),
175 description: std::ptr::null(),
176 version: std::ptr::null(),
177 author: std::ptr::null(),
178 library_path: std::ptr::null(),
179 config_path: std::ptr::null(),
180 instance_id: std::ptr::null(),
181 }
182 }
183 }
184
185 unsafe extern "C" fn destroy_wrapper(ptr: *mut std::ffi::c_void) {
186 let _ = Box::from_raw(ptr as *mut PluginWrapper);
187 }
188
189 let interface = PluginInterface {
190 plugin_ptr: wrapper_ptr,
191 initialize: initialize_wrapper,
192 update_ui: update_ui_wrapper,
193 on_mount: on_mount_wrapper,
194 on_dispose: on_dispose_wrapper,
195 on_connect: on_connect_wrapper,
196 on_disconnect: on_disconnect_wrapper,
197 handle_message: handle_message_wrapper,
198 get_metadata: get_metadata_wrapper,
199 destroy: destroy_wrapper,
200 };
201
202 Box::into_raw(Box::new(interface))
203}