1use std::{fmt::Debug, path::Path, sync::Arc};
2
3use crate::prelude::*;
4use bytes_kman::TBytes;
5use libloading::{Library, Symbol};
6use serde::{Deserialize, Serialize};
7
8#[derive(Clone)]
9pub enum ControlFlow {
10 Run,
11 Pause,
12 Break,
13}
14
15#[derive(
16 Default,
17 Debug,
18 Clone,
19 Copy,
20 Serialize,
21 Deserialize,
22 PartialEq,
23 Eq,
24 PartialOrd,
25 Ord,
26 Hash,
27 bytes_kman::Bytes,
28)]
29pub struct ModuleId(pub u64);
30
31impl From<MRef> for ModuleId {
32 fn from(value: MRef) -> Self {
33 value.read().unwrap().uid
34 }
35}
36
37#[derive(Serialize, Deserialize)]
38pub struct RefModule {
39 #[serde(skip)]
40 pub session: Option<Box<dyn TSession>>,
41 pub uid: ModuleId,
42}
43
44impl Debug for RefModule {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 f.debug_struct("ModuleInfo").finish()
47 }
48}
49
50impl PartialEq for RefModule {
51 fn eq(&self, other: &Self) -> bool {
52 self.uid == other.uid
53 }
54}
55
56#[derive(Clone)]
57pub struct Module {
58 pub name: String,
59 pub desc: String,
60 pub module: Box<dyn TModule>,
61 pub proxy: usize,
62 pub settings: Data,
64 pub element_data: Data,
66 pub info: MRef,
67}
68
69impl Debug for Module {
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 f.debug_struct(&format!("Module {}", self.name))
72 .field("name", &self.name)
73 .field("desc", &self.desc)
74 .field("proxy", &self.proxy)
75 .field("settings", &self.settings)
76 .field("element_data", &self.element_data)
77 .finish()
78 }
79}
80
81pub trait TModule {
82 fn init(&self, info: MRef) -> Result<(), String>;
83
84 fn get_name(&self) -> String;
85 fn get_desc(&self) -> String;
86
87 fn init_settings(&self, data: &mut Data);
88 fn init_element_settings(&self, data: &mut Data);
89
90 fn init_element(&self, element_row: ERow);
91 fn step_element(
92 &self,
93 element_row: ERow,
94 control_flow: &mut ControlFlow,
95 storage: &mut Storage,
96 );
97
98 fn accept_extension(&self, filename: &str) -> bool;
99 fn accept_url(&self, url: String) -> bool;
100 fn accepted_protocols(&self) -> Vec<String>;
101
102 fn init_location(&self, location_ref: LRef, data: FileOrData);
103 fn step_location(
104 &self,
105 location_row: LRow,
106 control_flow: &mut ControlFlow,
107 storage: &mut Storage,
108 );
109
110 fn notify(&self, _ref: Ref, event: Event);
111
112 fn c(&self) -> Box<dyn TModule>;
113}
114
115impl Clone for Box<dyn TModule> {
116 fn clone(&self) -> Self {
117 self.c()
118 }
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize, bytes_kman::Bytes)]
122pub enum RawLibraryError {
123 NotFound,
124 DontHaveSymbolGetName,
125 DontHaveSymbolGetDesc,
126 DontHaveSymbolInit,
127 DontHaveSymbolInitSettings,
128 DontHaveSymbolInitElementSettings,
129 DontHaveSymbolInitElement,
130 DontHaveSymbolStepElement,
131 DontHaveSymbolAcceptExtension,
132 DontHaveSymbolAcceptUrl,
133 DontHaveSymbolAcceptedProtocols,
134 DontHaveSymbolInitLocation,
135 DontHaveSymbolStepLocation,
136 DontHaveSymbolNotify,
137}
138
139pub struct RawModule {
140 lib: &'static Library,
141
142 fn_init: Symbol<'static, fn(MRef) -> Result<(), String>>,
143
144 fn_get_name: Symbol<'static, fn() -> String>,
145 fn_get_desc: Symbol<'static, fn() -> String>,
146
147 fn_init_settings: Symbol<'static, fn(&mut Data)>,
148 fn_init_element_settings: Symbol<'static, fn(&mut Data)>,
149
150 fn_init_element: Symbol<'static, fn(ERow)>,
151 fn_init_location: Symbol<'static, fn(LRef, FileOrData)>,
152
153 fn_step_element: Symbol<'static, fn(ERow, &mut ControlFlow, &mut Storage)>,
154 fn_step_location: Symbol<'static, fn(LRow, &mut ControlFlow, &mut Storage)>,
155
156 fn_accept_extension: Symbol<'static, fn(&str) -> bool>,
157 fn_accept_url: Symbol<'static, fn(String) -> bool>,
158 fn_accepted_protocols: Symbol<'static, fn() -> Vec<String>>,
159
160 fn_notify: Symbol<'static, fn(Ref, Event)>,
161}
162
163impl RawModule {
164 pub fn new_module(path: &Path) -> Result<Box<dyn TModule>, RawLibraryError> {
165 match Self::new(path) {
166 Ok(module) => Ok(Box::new(Arc::new(module))),
167 Err(err) => Err(err),
168 }
169 }
170 pub fn new(path: &Path) -> Result<Self, RawLibraryError> {
171 let lib = unsafe { Library::new(path) };
172 if lib.is_err() {
173 return Err(RawLibraryError::NotFound);
174 }
175 let lib = Box::leak(Box::new(lib.unwrap()));
176
177 let fn_init = if let Ok(func) = unsafe { lib.get(b"init\0") } {
178 func
179 } else {
180 return Err(RawLibraryError::DontHaveSymbolInit);
181 };
182
183 let fn_get_name = if let Ok(func) = unsafe { lib.get(b"get_name\0") } {
184 func
185 } else {
186 return Err(RawLibraryError::DontHaveSymbolGetName);
187 };
188
189 let fn_get_desc = if let Ok(func) = unsafe { lib.get(b"get_desc\0") } {
190 func
191 } else {
192 return Err(RawLibraryError::DontHaveSymbolGetDesc);
193 };
194
195 let fn_init_settings = if let Ok(func) = unsafe { lib.get(b"init_settings\0") } {
196 func
197 } else {
198 return Err(RawLibraryError::DontHaveSymbolInitSettings);
199 };
200
201 let fn_init_element_settings =
202 if let Ok(func) = unsafe { lib.get(b"init_element_settings\0") } {
203 func
204 } else {
205 return Err(RawLibraryError::DontHaveSymbolInitElementSettings);
206 };
207
208 let fn_init_element = if let Ok(func) = unsafe { lib.get(b"init_element\0") } {
209 func
210 } else {
211 return Err(RawLibraryError::DontHaveSymbolInitElement);
212 };
213
214 let fn_step_element = if let Ok(func) = unsafe { lib.get(b"step_element\0") } {
215 func
216 } else {
217 return Err(RawLibraryError::DontHaveSymbolStepElement);
218 };
219
220 let fn_accept_extension = if let Ok(func) = unsafe { lib.get(b"accept_extension\0") } {
221 func
222 } else {
223 return Err(RawLibraryError::DontHaveSymbolAcceptExtension);
224 };
225
226 let fn_accept_url = if let Ok(func) = unsafe { lib.get(b"accept_url\0") } {
227 func
228 } else {
229 return Err(RawLibraryError::DontHaveSymbolAcceptUrl);
230 };
231
232 let fn_accepted_protocols = if let Ok(func) = unsafe { lib.get(b"accepted_protocols\0") } {
233 func
234 } else {
235 return Err(RawLibraryError::DontHaveSymbolAcceptedProtocols);
236 };
237
238 let fn_init_location = if let Ok(func) = unsafe { lib.get(b"init_location\0") } {
239 func
240 } else {
241 return Err(RawLibraryError::DontHaveSymbolInitLocation);
242 };
243
244 let fn_notify = if let Ok(func) = unsafe { lib.get(b"notify\0") } {
245 func
246 } else {
247 return Err(RawLibraryError::DontHaveSymbolNotify);
248 };
249
250 let fn_step_location = if let Ok(func) = unsafe { lib.get(b"step_location\0") } {
251 func
252 } else {
253 return Err(RawLibraryError::DontHaveSymbolStepLocation);
254 };
255
256 Ok(Self {
257 lib,
258 fn_init,
259 fn_get_name,
260 fn_get_desc,
261 fn_init_settings,
262 fn_init_element_settings,
263 fn_init_element,
264 fn_init_location,
265 fn_step_element,
266 fn_accept_extension,
267 fn_accept_url,
268 fn_accepted_protocols,
269 fn_notify,
270 fn_step_location,
271 })
272 }
273}
274
275impl Drop for RawModule {
276 fn drop(&mut self) {
277 let lib = unsafe { Box::from_raw((self.lib as *const _) as *mut Library) };
278 drop(lib)
279 }
280}
281
282impl TModule for Arc<RawModule> {
283 fn init(&self, info: MRef) -> Result<(), String> {
284 (*self.fn_init)(info)
285 }
286
287 fn get_name(&self) -> String {
288 (*self.fn_get_name)()
289 }
290
291 fn get_desc(&self) -> String {
292 (*self.fn_get_desc)()
293 }
294
295 fn init_settings(&self, data: &mut Data) {
296 (*self.fn_init_settings)(data)
297 }
298
299 fn init_element_settings(&self, data: &mut Data) {
300 (*self.fn_init_element_settings)(data)
301 }
302
303 fn init_element(&self, element: ERow) {
304 (*self.fn_init_element)(element)
305 }
306
307 fn step_element(&self, element: ERow, control_flow: &mut ControlFlow, storage: &mut Storage) {
308 (*self.fn_step_element)(element, control_flow, storage)
309 }
310
311 fn accept_extension(&self, filename: &str) -> bool {
312 (*self.fn_accept_extension)(filename)
313 }
314
315 fn accept_url(&self, url: String) -> bool {
316 (*self.fn_accept_url)(url)
317 }
318
319 fn accepted_protocols(&self) -> Vec<String> {
320 (*self.fn_accepted_protocols)()
321 }
322
323 fn init_location(&self, location: LRef, data: FileOrData) {
324 (*self.fn_init_location)(location, data)
325 }
326
327 fn notify(&self, info: Ref, event: Event) {
328 (*self.fn_notify)(info, event)
329 }
330
331 fn step_location(&self, location: LRow, control_flow: &mut ControlFlow, storage: &mut Storage) {
332 (*self.fn_step_location)(location, control_flow, storage)
333 }
334
335 fn c(&self) -> Box<dyn TModule> {
336 Box::new(self.clone())
337 }
338}
339
340pub trait TModuleInfo {
341 fn get_session(&self) -> Result<Box<dyn TSession>, SessionError>;
342
343 fn get_name(&self) -> Result<String, SessionError>;
344 fn set_name(&self, name: impl Into<String>) -> Result<(), SessionError>;
345 fn get_default_name(&self) -> Result<String, SessionError>;
346
347 fn get_desc(&self) -> Result<String, SessionError>;
348 fn set_desc(&self, desc: impl Into<String>) -> Result<(), SessionError>;
349 fn get_default_desc(&self) -> Result<String, SessionError>;
350
351 fn get_proxy(&self) -> Result<usize, SessionError>;
352 fn set_proxy(&self, proxy: usize) -> Result<(), SessionError>;
353
354 fn get_settings(&self) -> Result<Data, SessionError>;
355 fn set_settings(&self, settings: Data) -> Result<(), SessionError>;
356
357 fn get_element_settings(&self) -> Result<Data, SessionError>;
358 fn set_element_settings(&self, settings: Data) -> Result<(), SessionError>;
359
360 fn register_action(
361 &self,
362 name: String,
363 values: Vec<(String, Value)>,
364 callback: fn(MRef, values: Vec<Type>),
365 ) -> Result<(), SessionError>;
366 fn remove_action(&self, name: String) -> Result<(), SessionError>;
367 fn run_action(&self, name: String, data: Vec<Type>) -> Result<(), SessionError>;
368
369 fn step_element(
370 &self,
371 element_info: &ElementId,
372 control_flow: ControlFlow,
373 storage: Storage,
374 ) -> Result<(ControlFlow, Storage), SessionError>;
375 fn step_location(
376 &self,
377 location_info: &LocationId,
378 control_flow: ControlFlow,
379 storage: Storage,
380 ) -> Result<(ControlFlow, Storage), SessionError>;
381
382 fn accept_url(&self, url: String) -> Result<bool, SessionError>;
383 fn accept_extension(&self, filename: impl Into<String>) -> Result<bool, SessionError>;
384 fn accepted_protocols(&self) -> Result<Vec<String>, SessionError>;
385
386 fn init_element(&self, element_info: &ElementId) -> Result<(), SessionError>;
387 fn init_location(
388 &self,
389 location_info: &LocationId,
390 data: FileOrData,
391 ) -> Result<(), SessionError>;
392
393 fn notify(&self, info: ID, event: Event) -> Result<(), SessionError>;
394
395 fn id(&self) -> ModuleId;
396}
397
398impl TModuleInfo for MRef {
399 fn get_session(&self) -> Result<Box<dyn TSession>, SessionError> {
400 if let Some(session) = &self.read().unwrap().session {
401 return Ok(session.c());
402 }
403 Err(SessionError::InvalidSession)
404 }
405
406 fn get_name(&self) -> Result<String, SessionError> {
407 return self.get_session()?.module_get_name(&self.id());
408 }
409
410 fn set_name(&self, name: impl Into<String>) -> Result<(), SessionError> {
411 self.get_session()?.module_set_name(&self.id(), name.into())
412 }
413
414 fn get_default_name(&self) -> Result<String, SessionError> {
415 self.get_session()?.module_get_default_name(&self.id())
416 }
417
418 fn get_desc(&self) -> Result<String, SessionError> {
419 self.get_session()?.module_get_desc(&self.id())
420 }
421
422 fn set_desc(&self, desc: impl Into<String>) -> Result<(), SessionError> {
423 self.get_session()?.module_set_desc(&self.id(), desc.into())
424 }
425
426 fn get_default_desc(&self) -> Result<String, SessionError> {
427 self.get_session()?.module_get_default_desc(&self.id())
428 }
429
430 fn get_proxy(&self) -> Result<usize, SessionError> {
431 self.get_session()?.module_get_proxy(&self.id())
432 }
433
434 fn set_proxy(&self, proxy: usize) -> Result<(), SessionError> {
435 self.get_session()?.module_set_proxy(&self.id(), proxy)
436 }
437
438 fn get_settings(&self) -> Result<Data, SessionError> {
439 self.get_session()?.module_get_settings(&self.id())
440 }
441
442 fn set_settings(&self, settings: Data) -> Result<(), SessionError> {
443 self.get_session()?
444 .module_set_settings(&self.id(), settings)
445 }
446
447 fn get_element_settings(&self) -> Result<Data, SessionError> {
448 self.get_session()?.module_get_element_settings(&self.id())
449 }
450
451 fn set_element_settings(&self, settings: Data) -> Result<(), SessionError> {
452 self.get_session()?
453 .module_set_element_settings(&self.id(), settings)
454 }
455
456 fn register_action(
457 &self,
458 name: String,
459 values: Vec<(String, Value)>,
460 callback: fn(MRef, values: Vec<Type>),
461 ) -> Result<(), SessionError> {
462 self.get_session()?
463 .register_action(&self.id(), name, values, callback)
464 }
465
466 fn remove_action(&self, name: String) -> Result<(), SessionError> {
467 self.get_session()?.remove_action(&self.id(), name)
468 }
469
470 fn run_action(&self, name: String, data: Vec<Type>) -> Result<(), SessionError> {
471 self.get_session()?.run_action(&self.id(), name, data)
472 }
473
474 fn step_element(
475 &self,
476 element_info: &ElementId,
477 control_flow: ControlFlow,
478 storage: Storage,
479 ) -> Result<(ControlFlow, Storage), SessionError> {
480 self.get_session()?
481 .module_step_element(&self.id(), element_info, control_flow, storage)
482 }
483
484 fn step_location(
485 &self,
486 location_info: &LocationId,
487 control_flow: ControlFlow,
488 storage: Storage,
489 ) -> Result<(ControlFlow, Storage), SessionError> {
490 self.get_session()?
491 .module_step_location(&self.id(), location_info, control_flow, storage)
492 }
493
494 fn accept_url(&self, url: String) -> Result<bool, SessionError> {
495 self.get_session()?.module_accept_url(&self.id(), url)
496 }
497
498 fn accept_extension(&self, filename: impl Into<String>) -> Result<bool, SessionError> {
499 self.get_session()?
500 .module_accept_extension(&self.id(), &filename.into())
501 }
502
503 fn accepted_protocols(&self) -> Result<Vec<String>, SessionError> {
504 self.get_session()?.module_accepted_protocols(&self.id())
505 }
506
507 fn init_element(&self, element_info: &ElementId) -> Result<(), SessionError> {
508 self.get_session()?
509 .module_init_element(&self.id(), element_info)
510 }
511
512 fn init_location(
513 &self,
514 location_info: &LocationId,
515 data: FileOrData,
516 ) -> Result<(), SessionError> {
517 self.get_session()?
518 .module_init_location(&self.id(), location_info, data)
519 }
520
521 fn notify(&self, info: ID, event: Event) -> Result<(), SessionError> {
522 let session = self.get_session()?;
523 match info {
524 ID::Element(e) => session.element_notify(&e, event),
525 ID::Location(l) => session.location_notify(&l, event),
526 }
527 }
528
529 fn id(&self) -> ModuleId {
530 self.read().unwrap().uid
531 }
532}
533
534#[derive(Debug, Clone, Serialize, Deserialize, Hash, bytes_kman::Bytes)]
535pub struct ModuleInfo {
536 pub name: String,
537 pub desc: String,
538 pub module: u64,
540 pub id: ModuleId,
541 pub proxy: usize,
542 pub settings: Data,
543 pub element_data: Data,
544}