ewwii_plugin_api/lib.rs
1//! # ewwii_plugin_api - A plugin interface for ewwii
2//!
3//! `ewwii_plguin_api` is a shared list of traits
4//! that both ewwii and its plugins can use.
5//! This crate simplifies and provides a safe way for building
6//! plugins for ewwii.
7//!
8//! ## Example
9//!
10//! The following example shows how this crate shall be used to build ewwii plugins:
11//!
12//! ```rust
13//! use ewwii_plugin_api::{EwwiiAPI, Plugin, export_plugin};
14//!
15//! pub struct DummyStructure;
16//!
17//! impl Plugin for DummyStructure {
18//! // critical for ewwii to launch the plugin
19//! fn init(&self, host: &dyn EwwiiAPI) {
20//! // will be printed by the host
21//! host.log("Plugin says Hello!");
22//! }
23//! }
24//!
25//! // Critical for ewwii to load the plugin
26//! export_plugin!(DummyStructure);
27//! ```
28
29mod export_macros;
30
31pub mod example;
32pub mod rhai_backend;
33pub mod widget_backend;
34
35#[cfg(feature = "include-rhai")]
36pub use rhai;
37
38#[cfg(feature = "include-gtk4")]
39pub use gtk4;
40
41/// The shared trait defining the Ewwii plugin API
42pub trait EwwiiAPI: Send + Sync {
43 // == General Stuff == //
44 /// Print a message from the host
45 fn print(&self, msg: &str);
46 /// Log a message from the host
47 fn log(&self, msg: &str);
48 /// Log a warning from the host
49 fn warn(&self, msg: &str);
50 /// Log an error from the host
51 fn error(&self, msg: &str);
52
53 // == Rhai Manipulation Stuff == //
54 /// _(include-rhai)_ Perform actions on the latest rhai engine.
55 ///
56 /// # Example
57 ///
58 /// ```rust
59 /// use ewwii_plugin_api::{EwwiiAPI, Plugin};
60 ///
61 /// pub struct DummyStructure;
62 ///
63 /// impl Plugin for DummyStructure {
64 /// fn init(&self, host: &dyn EwwiiAPI) {
65 /// host.rhai_engine_action(Box::new(|eng| {
66 /// // eng = rhai::Engine
67 /// eng.set_max_expr_depths(128, 128);
68 /// }));
69 /// }
70 /// }
71 /// ```
72 #[cfg(feature = "include-rhai")]
73 fn rhai_engine_action(
74 &self,
75 f: Box<dyn FnOnce(&mut rhai::Engine) + Send>,
76 ) -> Result<(), String>;
77
78 /// _(include-rhai)_ Expose a function that rhai configuration can call.
79 ///
80 /// **NOTE:***
81 ///
82 /// Due to TypeID mismatches, methods like `register_type`, `register_fn`,
83 /// etc. won't work on the engine and may cause a crash. It is recommended
84 /// to use the `register_function` API to register a funtion which `api::slib`
85 /// can call to in rhai.
86 ///
87 /// # Example
88 ///
89 /// ```rust
90 /// use ewwii_plugin_api::{EwwiiAPI, Plugin};
91 /// use rhai::Dynamic;
92 ///
93 /// pub struct DummyStructure;
94 ///
95 /// impl Plugin for DummyStructure {
96 /// fn init(&self, host: &dyn EwwiiAPI) {
97 /// host.register_function("my_func".to_string(), Box::new(|args| {
98 /// // Do stuff
99 /// // - Perform things on the args (if needed)
100 /// // - And return a value
101 ///
102 /// Dynamic::default() // return empty
103 /// }));
104 /// }
105 /// }
106 /// ```
107 ///
108 /// This example will register a function with signature "my_func(Array)" in rhai.
109 ///
110 /// ## Example use in rhai
111 ///
112 /// ```js
113 /// print(my_func(["param1", "param2"]));
114 /// ```
115 #[cfg(feature = "include-rhai")]
116 fn register_function(
117 &self,
118 name: String,
119 namespace: rhai_backend::RhaiFnNamespace,
120 f: Box<
121 dyn Fn(rhai::Array) -> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> + Send + Sync,
122 >,
123 ) -> Result<(), String>;
124
125 // == Widget Rendering & Logic == //
126 /// Get the list of all widget id's
127 fn list_widget_ids(&self) -> Result<Vec<u64>, String>;
128
129 /// _(include-gtk4)_ Perform actions on the latest widget registry.
130 ///
131 /// # Example
132 ///
133 /// ```rust
134 /// use ewwii_plugin_api::{EwwiiAPI, Plugin};
135 ///
136 /// pub struct DummyStructure;
137 ///
138 /// impl Plugin for DummyStructure {
139 /// fn init(&self, host: &dyn EwwiiAPI) {
140 /// host.widget_reg_action(Box::new(|wrg| {
141 /// // wrg = widget_backend::WidgetRegistryRepr
142 /// // The gtk4::Widget can be modified here.
143 /// }));
144 /// }
145 /// }
146 /// ```
147 #[cfg(feature = "include-gtk4")]
148 fn widget_reg_action(
149 &self,
150 f: Box<dyn FnOnce(&mut widget_backend::WidgetRegistryRepr) + Send>,
151 ) -> Result<(), String>;
152}
153
154/// The API format that the plugin should follow.
155/// This trait should be implemented for a structure and
156/// that structure should be exported via FFI.
157///
158/// ## Example
159///
160/// ```rust
161/// use ewwii_plugin_api::{Plugin, EwwiiAPI, export_plugin};
162///
163/// struct MyStruct;
164///
165/// impl Plugin for MyStruct {
166/// fn init(&self, host: &dyn EwwiiAPI) {
167/// /* Implementation Skipped */
168/// }
169/// }
170///
171/// // Automatically does all the FFI related exports
172/// export_plugin!(MyStruct);
173/// ```
174pub trait Plugin: Send + Sync {
175 /// Function ran by host to startup plugin (and its a must-have for plugin loading)
176 fn init(&self, host: &dyn EwwiiAPI);
177}