v / vlib / eventbus
Raw file | 150 loc (128 sloc) | 2.98 KB | Latest commit hash 8b962f844
1module eventbus
2
3pub type EventHandlerFn = fn (receiver voidptr, args voidptr, sender voidptr)
4
5pub struct Publisher[T] {
6mut:
7 registry &Registry[T] = unsafe { nil }
8}
9
10pub struct Subscriber[T] {
11mut:
12 registry &Registry[T] = unsafe { nil }
13}
14
15struct Registry[T] {
16mut:
17 events []EventHandler[T]
18}
19
20struct EventHandler[T] {
21 name T
22 handler EventHandlerFn = unsafe { nil }
23 receiver voidptr = unsafe { nil }
24 once bool
25}
26
27pub struct EventBus[T] {
28pub mut:
29 registry &Registry[T] = unsafe { nil }
30 publisher &Publisher[T] = unsafe { nil }
31 subscriber &Subscriber[T] = unsafe { nil }
32}
33
34// EventBus.new[T] create a new eventbus with event type T.
35pub fn EventBus.new[T]() &EventBus[T] {
36 registry := &Registry[T]{
37 events: []
38 }
39 return &EventBus[T]{registry, &Publisher[T]{registry}, &Subscriber[T]{registry}}
40}
41
42// new[T] create a new eventbus with event type T.
43pub fn new[T]() &EventBus[T] {
44 registry := &Registry[T]{
45 events: []
46 }
47 return &EventBus[T]{registry, &Publisher[T]{registry}, &Subscriber[T]{registry}}
48}
49
50// publish publishes an event with provided Params & name.
51pub fn (eb &EventBus[T]) publish(name T, sender voidptr, args voidptr) {
52 mut publisher := eb.publisher
53 publisher.publish(name, sender, args)
54}
55
56// clear_all clears all subscribers.
57pub fn (eb &EventBus[T]) clear_all() {
58 mut publisher := eb.publisher
59 publisher.clear_all()
60}
61
62// has_subscriber check if a subscriber to an event exists.
63pub fn (eb &EventBus[T]) has_subscriber(name T) bool {
64 return eb.registry.check_subscriber(name)
65}
66
67// publish publish an event with provided Params & name.
68fn (mut pb Publisher[T]) publish(name T, sender voidptr, args voidptr) {
69 // println('Publisher.publish(name=${name} sender=${sender} args=${args})')
70 mut handled_receivers := [20]voidptr{} // handle duplicate bugs TODO fix properly + perf
71 // is_key_down := name == 'on_key_down'
72 mut j := 0
73 for i, event in pb.registry.events {
74 if event.name == name {
75 // if is_key_down {
76 if event.receiver in handled_receivers {
77 continue
78 }
79 //}
80 // println('got ${i + 1} name=${name} event.receiver=${event.receiver}')
81 event.handler(event.receiver, args, sender)
82 // handled_receivers << event.receiver
83 handled_receivers[j] = event.receiver
84 j++
85 }
86 }
87 pb.registry.events = pb.registry.events.filter(!(it.name == name && it.once))
88}
89
90// clear_all clear all subscribers.
91fn (mut p Publisher[T]) clear_all() {
92 p.registry.events.clear()
93}
94
95// subscribe subscribe to an event `name`.
96pub fn (mut s Subscriber[T]) subscribe(name T, handler EventHandlerFn) {
97 s.registry.events << EventHandler[T]{
98 name: name
99 handler: handler
100 }
101}
102
103// subscribe_method subscribe to an event `name` and also set the `receiver` as a parameter.
104pub fn (mut s Subscriber[T]) subscribe_method(name T, handler EventHandlerFn, receiver voidptr) {
105 s.registry.events << EventHandler[T]{
106 name: name
107 handler: handler
108 receiver: receiver
109 }
110}
111
112// unsubscribe_method unsubscribe a receiver for only one method.
113pub fn (mut s Subscriber[T]) unsubscribe_method(name T, receiver voidptr) {
114 s.registry.events = s.registry.events.filter(!(it.name == name && it.receiver == receiver))
115}
116
117// unsubscribe_receiver unsubscribes a receiver from all events.
118pub fn (mut s Subscriber[T]) unsubscribe_receiver(receiver voidptr) {
119 s.registry.events = s.registry.events.filter(it.receiver != receiver)
120}
121
122// subscribe_once subscribe only once to an event `name`.
123pub fn (mut s Subscriber[T]) subscribe_once(name T, handler EventHandlerFn) {
124 s.registry.events << EventHandler[T]{
125 name: name
126 handler: handler
127 once: true
128 }
129}
130
131// is_subscribed check if we are subscribed to an event `name`.
132pub fn (s &Subscriber[T]) is_subscribed(name T) bool {
133 return s.registry.check_subscriber(name)
134}
135
136// is_subscribed_method checks whether a receiver was already subscribed for any events.
137pub fn (s &Subscriber[T]) is_subscribed_method(name T, receiver voidptr) bool {
138 return s.registry.events.any(it.name == name && it.receiver == receiver)
139}
140
141// unsubscribe unsubscribe from an event `name`.
142pub fn (mut s Subscriber[T]) unsubscribe(name T, handler EventHandlerFn) {
143 // v := voidptr(handler)
144 s.registry.events = s.registry.events.filter(!(it.name == name && it.handler == handler))
145}
146
147// Registry Methods
148fn (r &Registry[T]) check_subscriber(name T) bool {
149 return r.events.any(it.name == name)
150}