intuicio_frontend_simpleton/library/
event.rs1use 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}