summaryrefslogtreecommitdiffstats
path: root/firmware/events.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2014-03-14 23:15:16 +0100
committerThomas Martitz <kugel@rockbox.org>2014-03-14 23:36:30 +0100
commit470989bd708d9a425dbbf2d83b8fcbd0a8d0f488 (patch)
treef3bef37bc0f8ff7da4beddad9903209ced1bc25a /firmware/events.c
parent50f0dd80d660b332a1739e07a630c2cef1b678c6 (diff)
downloadrockbox-470989bd708d9a425dbbf2d83b8fcbd0a8d0f488.tar.gz
rockbox-470989bd708d9a425dbbf2d83b8fcbd0a8d0f488.tar.bz2
rockbox-470989bd708d9a425dbbf2d83b8fcbd0a8d0f488.zip
events: Rework event subsystem (add_event, send_event) to be more versatile.
add_event_ex is added that takes an extra user_data pointer. This pointer is passed to the callback (add_event and add_event_ex have slightly different callbacks types). All callbacks also get the event id passed. Events added with add_event_ex must be removed with remove_event_ex because the user_data pointer must match in addition to the callback pointer. On the other add_event is simplified to omit the oneshort parameter which was almost always false (still there with add_event_ex). As a side effect the ata_idle_notify callbacks are changed as well, they do not take a data parameter anymore which was always NULL anyway. This commit also adds some documentation to events.h Change-Id: I13e29a0f88ef908f175b376d83550f9e0231f772
Diffstat (limited to 'firmware/events.c')
-rw-r--r--firmware/events.c61
1 files changed, 49 insertions, 12 deletions
diff --git a/firmware/events.c b/firmware/events.c
index 74172e1fa0..4a51e7ae87 100644
--- a/firmware/events.c
+++ b/firmware/events.c
@@ -28,30 +28,41 @@
struct sysevent {
unsigned short id;
bool oneshot;
- void (*callback)(void *data);
+ bool has_user_data;
+ union {
+ void (*callback)(unsigned short id, void *event_data);
+ struct {
+ void (*callback2)(unsigned short id, void *event_data, void *user_data);
+ void *user_data;
+ };
+ } handler;
};
static struct sysevent events[MAX_SYS_EVENTS];
-bool add_event(unsigned short id, bool oneshot, void (*handler)(void *data))
+static bool do_add_event(unsigned short id, bool oneshot, bool user_data_valid,
+ void *handler, void *user_data)
{
int i;
/* Check if the event already exists. */
for (i = 0; i < MAX_SYS_EVENTS; i++)
{
- if (events[i].callback == handler && events[i].id == id)
+ if (events[i].handler.callback == handler && events[i].id == id
+ && (!user_data_valid || (user_data == events[i].handler.callback)))
return false;
}
/* Try to find a free slot. */
for (i = 0; i < MAX_SYS_EVENTS; i++)
{
- if (events[i].callback == NULL)
+ if (events[i].handler.callback == NULL)
{
events[i].id = id;
events[i].oneshot = oneshot;
- events[i].callback = handler;
+ if ((events[i].has_user_data = user_data_valid))
+ events[i].handler.user_data = user_data;
+ events[i].handler.callback = handler;
return true;
}
}
@@ -60,33 +71,59 @@ bool add_event(unsigned short id, bool oneshot, void (*handler)(void *data))
return false;
}
-void remove_event(unsigned short id, void (*handler)(void *data))
+bool add_event(unsigned short id, void (*handler)(unsigned short id, void *data))
+{
+ return do_add_event(id, false, false, handler, NULL);
+}
+
+bool add_event_ex(unsigned short id, bool oneshot, void (*handler)(unsigned short id, void *event_data, void *user_data), void *user_data)
+{
+ return do_add_event(id, oneshot, true, handler, user_data);
+}
+
+void do_remove_event(unsigned short id, bool user_data_valid,
+ void *handler, void *user_data)
{
int i;
for (i = 0; i < MAX_SYS_EVENTS; i++)
{
- if (events[i].id == id && events[i].callback == handler)
+ if (events[i].id == id && events[i].handler.callback == handler
+ && (!user_data_valid || (user_data == events[i].handler.callback)))
{
- events[i].callback = NULL;
+ events[i].handler.callback = NULL;
return;
}
}
}
+void remove_event(unsigned short id, void (*handler)(unsigned short id, void *data))
+{
+ do_remove_event(id, false, handler, NULL);
+}
+
+void remove_event_ex(unsigned short id,
+ void (*handler)(unsigned short id, void *event_data, void *user_data),
+ void *user_data)
+{
+ do_remove_event(id, true, handler, user_data);
+}
+
void send_event(unsigned short id, void *data)
{
int i;
for (i = 0; i < MAX_SYS_EVENTS; i++)
{
- if (events[i].id == id && events[i].callback != NULL)
+ if (events[i].id == id && events[i].handler.callback != NULL)
{
- events[i].callback(data);
+ if (events[i].has_user_data)
+ events[i].handler.callback2(id, data, events[i].handler.user_data);
+ else
+ events[i].handler.callback(id, data);
if (events[i].oneshot)
- events[i].callback = NULL;
+ events[i].handler.callback = NULL;
}
}
}
-