intuicio_frontend_simpleton/library/
event.rs

1use crate::{Array, Function, Reference};
2use intuicio_core::{context::Context, registry::Registry, IntuicioStruct};
3use intuicio_derive::{intuicio_method, intuicio_methods, IntuicioStruct};
4
5use super::{closure::Closure, promise::Promise};
6
7#[derive(IntuicioStruct, Default)]
8#[intuicio(name = "Event", module_name = "event", override_send = false)]
9pub struct Event {
10    #[intuicio(ignore)]
11    pub persistent: Array,
12    #[intuicio(ignore)]
13    pub oneshot: Array,
14}
15
16#[intuicio_methods(module_name = "event")]
17impl Event {
18    #[intuicio_method()]
19    pub fn bind(mut event: Reference, target: Reference) -> Reference {
20        let mut event = event.write::<Event>().unwrap();
21        if target.read::<Promise>().is_some() {
22            event.oneshot.push(target);
23        } else {
24            event.persistent.push(target);
25        }
26        Reference::null()
27    }
28
29    #[intuicio_method()]
30    pub fn bind_once(mut event: Reference, target: Reference) -> Reference {
31        let mut event = event.write::<Event>().unwrap();
32        event.oneshot.push(target);
33        Reference::null()
34    }
35
36    #[intuicio_method()]
37    pub fn unbind(mut event: Reference, target: Reference) -> Reference {
38        let mut event = event.write::<Event>().unwrap();
39        if target.is_null() {
40            event.persistent.clear();
41            event.oneshot.clear();
42        } else {
43            while let Some(index) = event
44                .persistent
45                .iter()
46                .position(|item| crate::library::reflect::are_same_impl(item, &target))
47            {
48                event.persistent.swap_remove(index);
49            }
50            while let Some(index) = event
51                .oneshot
52                .iter()
53                .position(|item| crate::library::reflect::are_same_impl(item, &target))
54            {
55                event.oneshot.swap_remove(index);
56            }
57        }
58        Reference::null()
59    }
60
61    fn dispatch_impl(
62        context: &mut Context,
63        registry: &Registry,
64        target: Reference,
65        arguments: Reference,
66    ) {
67        if target.read::<Function>().is_some() {
68            crate::library::reflect::call(context, registry, target, arguments);
69        } else if target.read::<Closure>().is_some() {
70            Closure::call(context, registry, target, arguments);
71        } else if target.read::<Promise>().is_some() {
72            Promise::resolve(context, registry, target, arguments);
73        }
74    }
75
76    #[intuicio_method(use_context, use_registry)]
77    pub fn dispatch(
78        context: &mut Context,
79        registry: &Registry,
80        mut event: Reference,
81        arguments: Reference,
82    ) -> Reference {
83        assert!(arguments.read::<Array>().is_some());
84        let mut event = event.write::<Event>().unwrap();
85        for target in &event.persistent {
86            Self::dispatch_impl(context, registry, target.clone(), arguments.clone())
87        }
88        for target in &event.oneshot {
89            Self::dispatch_impl(context, registry, target.clone(), arguments.clone())
90        }
91        event.oneshot.clear();
92        Reference::null()
93    }
94}
95
96pub fn install(registry: &mut Registry) {
97    registry.add_type(Event::define_struct(registry));
98    registry.add_function(Event::bind__define_function(registry));
99    registry.add_function(Event::bind_once__define_function(registry));
100    registry.add_function(Event::unbind__define_function(registry));
101    registry.add_function(Event::dispatch__define_function(registry));
102}