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

ambee/giterated

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

Fucking whatever there you go

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨57c2ca5

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