aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/vlib/eventbus/eventbus.v
blob: 69cf1188a739e5c5a4dfaa35a9bae4b3da476e72 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
module eventbus

pub type EventHandlerFn = fn (receiver voidptr, args voidptr, sender voidptr)

pub struct Publisher {
mut:
	registry &Registry
}

pub struct Subscriber {
mut:
	registry &Registry
}

struct Registry {
mut:
	events []EventHandler
}

struct EventHandler {
	name     string
	handler  EventHandlerFn
	receiver voidptr = voidptr(0)
	once     bool
}

pub struct EventBus {
pub mut:
	registry   &Registry
	publisher  &Publisher
	subscriber &Subscriber
}

pub fn new() &EventBus {
	registry := &Registry{
		events: []
	}
	return &EventBus{registry, &Publisher{registry}, &Subscriber{registry}}
}

// EventBus Methods
pub fn (eb &EventBus) publish(name string, sender voidptr, args voidptr) {
	mut publisher := eb.publisher
	publisher.publish(name, sender, args)
}

pub fn (eb &EventBus) clear_all() {
	mut publisher := eb.publisher
	publisher.clear_all()
}

pub fn (eb &EventBus) has_subscriber(name string) bool {
	return eb.registry.check_subscriber(name)
}

// Publisher Methods
fn (mut pb Publisher) publish(name string, sender voidptr, args voidptr) {
	for event in pb.registry.events {
		if event.name == name {
			event.handler(event.receiver, args, sender)
		}
	}
	pb.registry.events = pb.registry.events.filter(!(it.name == name && it.once))
}

fn (mut p Publisher) clear_all() {
	p.registry.events.clear()
}

// Subscriber Methods
pub fn (mut s Subscriber) subscribe(name string, handler EventHandlerFn) {
	s.registry.events << EventHandler{
		name: name
		handler: handler
	}
}

pub fn (mut s Subscriber) subscribe_method(name string, handler EventHandlerFn, receiver voidptr) {
	s.registry.events << EventHandler{
		name: name
		handler: handler
		receiver: receiver
	}
}

// unsubscribe_method unsubscribe a receiver for only one method
pub fn (mut s Subscriber) unsubscribe_method(name string, receiver voidptr) {
	s.registry.events = s.registry.events.filter(!(it.name == name && it.receiver == receiver))
}

// unsubscribe_receiver unsubscribes a receiver from all events
pub fn (mut s Subscriber) unsubscribe_receiver(receiver voidptr) {
	s.registry.events = s.registry.events.filter(it.receiver != receiver)
}

pub fn (mut s Subscriber) subscribe_once(name string, handler EventHandlerFn) {
	s.registry.events << EventHandler{
		name: name
		handler: handler
		once: true
	}
}

pub fn (s &Subscriber) is_subscribed(name string) bool {
	return s.registry.check_subscriber(name)
}

// is_subscribed_method checks whether a receiver was already subscribed for any events
pub fn (s &Subscriber) is_subscribed_method(name string, receiver voidptr) bool {
	return s.registry.events.any(it.name == name && it.receiver == receiver)
}

pub fn (mut s Subscriber) unsubscribe(name string, handler EventHandlerFn) {
	// v := voidptr(handler)
	s.registry.events = s.registry.events.filter(!(it.name == name && it.handler == handler))
}

// Registry Methods
fn (r &Registry) check_subscriber(name string) bool {
	return r.events.any(it.name == name)
}