v2 / vlib / eventbus / eventbus.v
154 lines · 131 sloc · 4.3 KB · 4df08e9c8f8548c0107f3834927287074079fd88
Raw
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
15pub struct Registry[T] {
16mut:
17 events []EventHandler[T]
18}
19
20pub struct 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
67const dedup_buffer_len = 20
68
69// publish an event with provided Params & name.
70fn (mut pb Publisher[T]) publish(name T, sender voidptr, args voidptr) {
71 // println('Publisher.publish(name=${name} sender=${sender} args=${args})')
72 invalid := 0
73 mut handled_receivers := unsafe { [dedup_buffer_len]voidptr{init: &invalid} } // handle duplicate bugs TODO fix properly + perf
74 mut j := 0
75 mut found_onces := 0
76 for event in pb.registry.events {
77 if event.name == name {
78 if event.once {
79 found_onces++
80 }
81 if event.receiver in handled_receivers {
82 continue
83 }
84 event.handler(event.receiver, args, sender)
85 handled_receivers[j] = event.receiver
86 j = (j + 1) % dedup_buffer_len
87 }
88 }
89 if found_onces > 0 {
90 pb.registry.events = pb.registry.events.filter(!(it.name == name && it.once))
91 }
92}
93
94// clear_all clear all subscribers.
95fn (mut p Publisher[T]) clear_all() {
96 p.registry.events.clear()
97}
98
99// subscribe subscribe to an event `name`.
100pub fn (mut s Subscriber[T]) subscribe(name T, handler EventHandlerFn) {
101 s.registry.events << EventHandler[T]{
102 name: name
103 handler: handler
104 }
105}
106
107// subscribe_method subscribe to an event `name` and also set the `receiver` as a parameter.
108pub fn (mut s Subscriber[T]) subscribe_method(name T, handler EventHandlerFn, receiver voidptr) {
109 s.registry.events << EventHandler[T]{
110 name: name
111 handler: handler
112 receiver: receiver
113 }
114}
115
116// unsubscribe_method unsubscribe a receiver for only one method.
117pub fn (mut s Subscriber[T]) unsubscribe_method(name T, receiver voidptr) {
118 s.registry.events = s.registry.events.filter(!(it.name == name && it.receiver == receiver))
119}
120
121// unsubscribe_receiver unsubscribes a receiver from all events.
122pub fn (mut s Subscriber[T]) unsubscribe_receiver(receiver voidptr) {
123 s.registry.events = s.registry.events.filter(it.receiver != receiver)
124}
125
126// subscribe_once subscribe only once to an event `name`.
127pub fn (mut s Subscriber[T]) subscribe_once(name T, handler EventHandlerFn) {
128 s.registry.events << EventHandler[T]{
129 name: name
130 handler: handler
131 once: true
132 }
133}
134
135// is_subscribed check if we are subscribed to an event `name`.
136pub fn (s &Subscriber[T]) is_subscribed(name T) bool {
137 return s.registry.check_subscriber(name)
138}
139
140// is_subscribed_method checks whether a receiver was already subscribed for any events.
141pub fn (s &Subscriber[T]) is_subscribed_method(name T, receiver voidptr) bool {
142 return s.registry.events.any(it.name == name && it.receiver == receiver)
143}
144
145// unsubscribe unsubscribe from an event `name`.
146pub fn (mut s Subscriber[T]) unsubscribe(name T, handler EventHandlerFn) {
147 // v := voidptr(handler)
148 s.registry.events = s.registry.events.filter(!(it.name == name && it.handler == handler))
149}
150
151// Registry Methods
152fn (r &Registry[T]) check_subscriber(name T) bool {
153 return r.events.any(it.name == name)
154}
155