forked from BenjaminSoelberg/openchronos-ng-elf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmessagebus.c
101 lines (84 loc) · 3.23 KB
/
messagebus.c
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
/**
messagebus.c: openchronos-ng messaging system
Copyright (C) 2012 Angelo Arrifano <[email protected]>
Copyright (C) 2016 Benjamin Sølberg <[email protected]>
http://github.com/BenjaminSoelberg/openchronos-ng-elf
This file is part of openchronos-ng.
openchronos-ng is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
openchronos-ng is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
#include "messagebus.h"
/* the message bus */
static struct sys_messagebus *messagebus;
/***************************************************************************
************************* THE SYSTEM MESSAGE BUS **************************
**************************************************************************/
void sys_messagebus_register(void (*callback)(enum sys_message),
enum sys_message listens)
{
struct sys_messagebus **p = &messagebus;
while (*p) {
/* Set p to address of next pointer */
p = &(*p)->next;
}
*p = malloc(sizeof(struct sys_messagebus));
(*p)->next = NULL;
(*p)->fn = callback;
(*p)->listens = listens;
}
void sys_messagebus_unregister_all(void (*callback)(enum sys_message))
{
sys_messagebus_unregister(callback, 0);
}
void sys_messagebus_unregister(void (*callback)(enum sys_message),
enum sys_message listens)
{
struct sys_messagebus *p = messagebus, *pp = NULL;
while (p) {
if (p->fn == callback && (listens == 0 || p->listens == listens)) {
if (!pp) { // If 1. element
// Remove first element by pointing to the next
messagebus = p->next;
// Free element
free(p);
// Set current pointer to point to new first element
p = messagebus;
// Keep pp the same (NULL)
} else { // If 2. or later element
// Remove element by pointing previous to the next
pp->next = p->next;
// Free element
free(p);
// Set current pointer to point to next element
p = pp->next;
// Keep pp the same
}
} else {
// Set pp (previous pointer) to current element
pp = p;
// Set p (current pointer) to next element
p = p->next;
}
}
}
void send_events(enum sys_message msg)
{
struct sys_messagebus *p = messagebus;
while (p) {
/* notify listener if he registered for any of these messages */
enum sys_message filtered_msg = msg & p->listens;
if (filtered_msg) {
p->fn(filtered_msg);
}
/* move to next */
p = p->next;
}
}