JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

Huge refactor to prep for moving the daemon over to the plugin architecture

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨5df753c

⁨giterated-plugins/giterated-plugin/src/new_stack/mod.rs⁩ - ⁨13235⁩ bytes
Raw
1 pub mod operation_walker;
2 pub mod runtime_handler;
3
4 use std::{
5 any::type_name, collections::HashMap, fmt::Debug, mem::transmute, ptr::null_mut, sync::Arc,
6 };
7
8 use giterated_models::{
9 error::OperationError, instance::Instance, object::GiteratedObject,
10 operation::GiteratedOperation,
11 };
12 use semver::Version;
13 use tracing::{debug, debug_span, field::DebugValue, span, trace, trace_span, warn, Level};
14
15 use crate::{
16 callback::{
17 OperationHandlerCallback, SettingChangeCallback, SettingGetterCallback,
18 ValueChangeCallback, ValueGetterCallback,
19 },
20 handle::{PluginHandle, PluginInitializationState},
21 vtable::{ObjectVtable, OperationVTable, SettingVtable, ValueVTable},
22 };
23
24 use self::operation_walker::OperationHandlerRules;
25
26 pub struct State<S>(pub S);
27
28 impl<S> std::ops::Deref for State<S> {
29 type Target = S;
30
31 fn deref(&self) -> &Self::Target {
32 &self.0
33 }
34 }
35
36 pub struct OperationState {
37 pub our_instance: Instance,
38 }
39
40 #[derive(Default)]
41 pub struct TypeMetadata {
42 pub objects: HashMap<&'static str, ObjectVtable>,
43 pub operations: HashMap<ObjectOperationPair<'static>, OperationVTable>,
44 pub settings: HashMap<ObjectSettingPair<'static>, SettingVtable>,
45 pub values: HashMap<ObjectValuePair<'static>, ValueVTable>,
46 }
47
48 impl TypeMetadata {
49 pub fn register_object(&mut self, object_kind: &'static str, vtable: ObjectVtable) {
50 trace!("Registering type metadata for {}", object_kind);
51
52 self.objects.insert(object_kind, vtable);
53 }
54
55 pub fn register_operation(
56 &mut self,
57 object_kind: &'static str,
58 operation_name: &'static str,
59 vtable: OperationVTable,
60 ) {
61 trace!(
62 "Registering operation metadata for {}::{}",
63 object_kind,
64 operation_name
65 );
66
67 self.operations.insert(
68 ObjectOperationPair {
69 object_kind,
70 operation_name,
71 },
72 vtable,
73 );
74 }
75
76 pub fn register_setting(
77 &mut self,
78 object_kind: &'static str,
79 setting_name: &'static str,
80 vtable: SettingVtable,
81 ) {
82 trace!("Registering setting {}::{}", object_kind, setting_name);
83
84 self.settings.insert(
85 ObjectSettingPair {
86 object_kind,
87 setting_name,
88 },
89 vtable,
90 );
91 }
92
93 pub fn register_value(
94 &mut self,
95 object_kind: &'static str,
96 value_name: &'static str,
97 vtable: ValueVTable,
98 ) {
99 trace!("Registering value {}::{}", object_kind, value_name);
100
101 self.values.insert(
102 ObjectValuePair {
103 object_kind,
104 value_name,
105 },
106 vtable,
107 );
108 }
109 }
110
111 #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
112 pub struct ObjectOperationPair<'s> {
113 pub object_kind: &'s str,
114 pub operation_name: &'s str,
115 }
116
117 impl<'s> ObjectOperationPair<'s> {
118 pub fn new(object_kind: &'s str, operation_name: &'s str) -> Self {
119 Self {
120 object_kind,
121 operation_name,
122 }
123 }
124 }
125
126 #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
127 pub struct ObjectSettingPair<'s> {
128 pub object_kind: &'s str,
129 pub setting_name: &'s str,
130 }
131
132 impl<'s> ObjectSettingPair<'s> {
133 pub fn new(object_kind: &'s str, setting_name: &'s str) -> Self {
134 Self {
135 object_kind,
136 setting_name,
137 }
138 }
139 }
140
141 #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
142 pub struct ObjectValuePair<'s> {
143 pub object_kind: &'s str,
144 pub value_name: &'s str,
145 }
146
147 impl<'s> ObjectValuePair<'s> {
148 pub fn new(object_kind: &'s str, value_name: &'s str) -> Self {
149 Self {
150 object_kind,
151 value_name,
152 }
153 }
154 }
155
156 #[derive(Clone, Copy)]
157 #[repr(C)]
158 pub struct PluginState {
159 pub inner: *mut (),
160 }
161
162 impl PluginState {
163 pub unsafe fn transmute_owned<T>(&mut self) -> Box<T> {
164 Box::from_raw(self.inner as *mut T)
165 }
166
167 pub unsafe fn transmute_ref<T>(&self) -> &T {
168 let ptr: *const T = transmute(self.inner);
169
170 ptr.as_ref().unwrap()
171 }
172 }
173
174 impl PluginState {
175 pub fn null() -> Self {
176 Self { inner: null_mut() }
177 }
178 }
179
180 #[derive(Default)]
181 pub struct Runtime {
182 plugins: Vec<(PluginMeta, PluginHandle)>,
183 handlers: RuntimeHandlers,
184 }
185
186 impl Runtime {
187 pub fn insert_plugin(&mut self, mut plugin: PluginHandle) {
188 let _guard = debug_span!("inserting plugin", meta = debug(&plugin.meta)).entered();
189
190 for (pair, callback) in &plugin.initialization.operation_handlers {
191 let _guard =
192 trace_span!("processing operation handler callbacks", pair = debug(pair)).entered();
193
194 if self
195 .handlers
196 .operation_handlers
197 .insert(*pair, (RuntimeDomain::from_plugin(&plugin), *callback))
198 .is_some()
199 {
200 warn!("Warning! Insertion of handler for overwrote a previous handler.")
201 }
202
203 trace!("Insertion of operation handler successful")
204 }
205
206 for (pair, callback) in &plugin.initialization.value_getters {
207 let _guard =
208 trace_span!("processing value getter callbacks", pair = debug(pair)).entered();
209
210 if self
211 .handlers
212 .value_getters
213 .insert(*pair, (RuntimeDomain::from_plugin(&plugin), *callback))
214 .is_some()
215 {
216 warn!("Warning! Insertion of handler for overwrote a previous handler.")
217 }
218
219 trace!("Insertion of operation handler successful")
220 }
221
222 for (pair, callback) in &plugin.initialization.setting_getters {
223 let _guard =
224 trace_span!("processing setting getter callbacks", pair = debug(pair)).entered();
225
226 if self
227 .handlers
228 .setting_getters
229 .insert(*pair, (RuntimeDomain::from_plugin(&plugin), *callback))
230 .is_some()
231 {
232 warn!("Warning! Insertion of setting handler for overwrote a previous handler.")
233 }
234
235 trace!("Insertion of setting handler successful")
236 }
237 }
238
239 pub fn handle(
240 &self,
241 object_kind: &str,
242 operation_name: &str,
243 object: &str,
244 operation_payload: &[u8],
245 ) -> Result<(), OperationError<()>> {
246 // let rules = self.handlers.handle_operation(object_kind, operation_name);
247
248 // rules.handle(object, operation_payload)
249
250 todo!()
251 }
252
253 pub fn handle_typed<O: GiteratedObject, D: GiteratedOperation<O>>(
254 &self,
255 object: O,
256 operation: D,
257 ) -> Result<D::Success, OperationError<D::Failure>> {
258 todo!()
259 }
260 }
261
262 #[derive(Default)]
263 pub struct RuntimeHandlers {
264 operation_handlers:
265 HashMap<ObjectOperationPair<'static>, (RuntimeDomain, OperationHandlerCallback)>,
266 value_getters: HashMap<ObjectValuePair<'static>, (RuntimeDomain, ValueGetterCallback)>,
267 setting_getters: HashMap<ObjectSettingPair<'static>, (RuntimeDomain, SettingGetterCallback)>,
268 value_change: HashMap<ObjectValuePair<'static>, (RuntimeDomain, ValueChangeCallback)>,
269 setting_change: HashMap<ObjectSettingPair<'static>, (RuntimeDomain, SettingChangeCallback)>,
270 }
271
272 unsafe impl Send for RuntimeHandlers {}
273 unsafe impl Sync for RuntimeHandlers {}
274
275 impl RuntimeHandlers {
276 pub fn operation_handler(
277 &mut self,
278 pair: ObjectOperationPair<'static>,
279 handler: OperationHandlerCallback,
280 domain: RuntimeDomain,
281 ) {
282 trace!(
283 "Inserting operation handler for {}::{}",
284 pair.object_kind,
285 pair.operation_name
286 );
287
288 // There can only be one handler per operation (at least for now?), send a warning if
289 // a newly registered handler overwrites the previous handler.
290 if self
291 .operation_handlers
292 .insert(pair, (domain, handler))
293 .is_some()
294 {
295 debug!("Warning! A newly inserted operation handler for {}::{} overwrites a previous handler.", pair.object_kind, pair.operation_name);
296 }
297 }
298
299 pub fn value_getter(
300 &mut self,
301 pair: ObjectValuePair<'static>,
302 handler: ValueGetterCallback,
303 domain: RuntimeDomain,
304 ) {
305 trace!(
306 "Inserting value getter for {}::{}",
307 pair.object_kind,
308 pair.value_name
309 );
310
311 if self.value_getters.insert(pair, (domain, handler)).is_some() {
312 debug!(
313 "Warning! A newly inserted value getter for {}::{} overwrites a previous handler.",
314 pair.object_kind, pair.value_name
315 );
316 }
317 }
318
319 pub fn setting_getter(
320 &mut self,
321 pair: ObjectSettingPair<'static>,
322 handler: SettingGetterCallback,
323 domain: RuntimeDomain,
324 ) {
325 trace!(
326 "Inserting setting getter for {}::{}",
327 pair.object_kind,
328 pair.setting_name
329 );
330
331 if self
332 .setting_getters
333 .insert(pair, (domain, handler))
334 .is_some()
335 {
336 debug!("Warning! A newly inserted setting getter for {}::{} overwrites a previous handler.", pair.object_kind, pair.setting_name);
337 }
338 }
339
340 pub fn value_change(
341 &mut self,
342 pair: ObjectValuePair<'static>,
343 handler: ValueChangeCallback,
344 domain: RuntimeDomain,
345 ) {
346 trace!(
347 "Inserting value change handler for {}::{}",
348 pair.object_kind,
349 pair.value_name
350 );
351
352 if self.value_change.insert(pair, (domain, handler)).is_some() {
353 debug!("Warning! A newly inserted value change handler for {}::{} overwrites a previous handler.", pair.object_kind, pair.value_name);
354 panic!("Not intended");
355 }
356 }
357
358 pub fn setting_change(
359 &mut self,
360 pair: ObjectSettingPair<'static>,
361 handler: SettingChangeCallback,
362 domain: RuntimeDomain,
363 ) {
364 trace!(
365 "Inserting setting change handler for {}::{}",
366 pair.object_kind,
367 pair.setting_name
368 );
369
370 if self
371 .setting_change
372 .insert(pair, (domain, handler))
373 .is_some()
374 {
375 debug!("Warning! A newly inserted setting change handler for {}::{} overwrites a previous handler.", pair.object_kind, pair.setting_name);
376 panic!("Not intended");
377 }
378 }
379 }
380
381 impl RuntimeHandlers {
382 pub fn handle_operation<'o>(
383 &'o self,
384 object_kind: &'o str,
385 operation_name: &'o str,
386 ) -> OperationHandlerRules<'o> {
387 OperationHandlerRules::new(object_kind, operation_name, self)
388 }
389 }
390
391 pub struct RuntimeDomain {
392 plugin: PluginHandle,
393 }
394
395 impl RuntimeDomain {
396 pub fn from_plugin(plugin: &PluginHandle) -> Self {
397 Self {
398 plugin: plugin.clone(),
399 }
400 }
401
402 pub fn object_vtable(&self, object_kind: &str) -> Option<ObjectVtable> {
403 self.plugin
404 .initialization
405 .type_metadata
406 .objects
407 .get(object_kind)
408 .copied()
409 }
410
411 pub fn operation_vtable(
412 &self,
413 object_kind: &str,
414 operation_name: &str,
415 ) -> Option<OperationVTable> {
416 self.plugin
417 .initialization
418 .type_metadata
419 .operations
420 .get(&ObjectOperationPair::new(object_kind, operation_name))
421 .copied()
422 }
423
424 pub fn setting_vtable(&self, object_kind: &str, setting_name: &str) -> Option<SettingVtable> {
425 self.plugin
426 .initialization
427 .type_metadata
428 .settings
429 .get(&ObjectSettingPair::new(object_kind, setting_name))
430 .copied()
431 }
432
433 pub fn value_vtable(&self, object_kind: &str, value_name: &str) -> Option<ValueVTable> {
434 self.plugin
435 .initialization
436 .type_metadata
437 .values
438 .get(&ObjectValuePair::new(object_kind, value_name))
439 .copied()
440 }
441 }
442
443 #[derive(Clone, Debug)]
444 pub struct PluginMeta {
445 pub name: String,
446 pub version: Version,
447 }
448
449 #[repr(C)]
450 pub struct FFIPluginMeta {
451 pub name: *const u8,
452 pub name_len: usize,
453 pub version: *const u8,
454 pub version_len: usize,
455 }
456
457 pub struct RuntimePlugin {
458 handle: PluginHandle,
459 type_metadata: Arc<TypeMetadata>,
460 }
461
462 impl RuntimePlugin {
463 pub fn plugin_meta(&self) -> PluginMeta {
464 let meta = unsafe { self.handle.raw.plugin_meta() };
465
466 let name = unsafe { std::slice::from_raw_parts(meta.name, meta.name_len) };
467 let version = unsafe { std::slice::from_raw_parts(meta.version, meta.version_len) };
468
469 let name = std::str::from_utf8(name).unwrap();
470 let version = std::str::from_utf8(version).unwrap();
471
472 PluginMeta {
473 name: String::from(name),
474 version: Version::parse(version).unwrap(),
475 }
476 }
477 }
478
479 pub enum HandlerError {
480 Failure(()),
481 Internal(()),
482 Unhandled,
483 }
484