aboutsummaryrefslogtreecommitdiff
path: root/event.c
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2017-05-08 22:06:47 +0200
committertomsmeding <tom.smeding@gmail.com>2017-05-08 22:08:56 +0200
commita7a0ce278e661bf5d3f2b47556d8c30469d2bd6c (patch)
treedef6c7b56df0b21351c4f1b0766163426ee47649 /event.c
parent886fc77026a2a805e5d166b2f87bd24720ad9ea4 (diff)
server: Add event system
Diffstat (limited to 'event.c')
-rw-r--r--event.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/event.c b/event.c
new file mode 100644
index 0000000..40eaff8
--- /dev/null
+++ b/event.c
@@ -0,0 +1,99 @@
+#include <string.h>
+#include "event.h"
+
+
+struct cbs_chain{
+ event_callback_t *cb;
+ struct cbs_chain *prev,*next;
+};
+
+struct cbs_chain *callbacks=NULL,*callbacks_last=NULL;
+
+
+static struct cbs_chain* find_chain_item(event_callback_t *cb){
+ struct cbs_chain *item=callbacks;
+ while(item&&item->cb!=cb)item=item->next;
+ return item;
+}
+
+
+void event_register(event_callback_t *cb){
+ struct cbs_chain *item=find_chain_item(cb);
+ if(item!=NULL){
+ debug("event_register: callback %p already registered!",cb);
+ return;
+ }
+ item=malloc(1,struct cbs_chain);
+ item->cb=cb;
+ item->prev=item->next=NULL;
+ if(callbacks){
+ item->prev=callbacks_last;
+ callbacks_last->next=item;
+ callbacks_last=item;
+ } else {
+ callbacks=callbacks_last=item;
+ }
+}
+
+void event_unregister(event_callback_t *cb){
+ struct cbs_chain *item=find_chain_item(cb);
+ if(item==NULL){
+ debug("event_unregister: callback %p was not registered!",cb);
+ return;
+ }
+ if(item->prev)item->prev->next=item->next;
+ if(item->next)item->next->prev=item->prev;
+ if(callbacks==item)callbacks=item->next;
+ if(callbacks_last==item)callbacks_last=item->prev;
+ free(item);
+}
+
+struct event_item* event_item_alloc(void){
+ struct event_item *event=malloc(1,struct event_item);
+ memset(event,0,sizeof(struct event_item));
+ return event;
+}
+
+void event_item_free(struct event_item *event){
+ if(event->message)free(event->message);
+ if(event->user)free(event->user);
+ if(event->room)free(event->room);
+ free(event);
+}
+
+void event_emit(const struct event_item *event){
+ for(struct cbs_chain *item=callbacks;item!=NULL;item=item->next){
+ item->cb(event);
+ }
+}
+
+void event_emit_message(i64 timestamp,const char *message,const char *user,const char *room){
+ struct event_item *event=event_item_alloc();
+ event->type=EVENT_MESSAGE;
+ event->timestamp=timestamp;
+ event->message=strdup(message);
+ event->user=strdup(user);
+ event->room=strdup(room);
+ event_emit(event);
+ event_item_free(event);
+}
+
+void event_emit_online(i64 timestamp,const char *user,i64 numonline){
+ struct event_item *event=event_item_alloc();
+ event->type=EVENT_ONLINE;
+ event->timestamp=timestamp;
+ event->user=strdup(user);
+ event->num=numonline;
+ event_emit(event);
+ event_item_free(event);
+}
+
+void event_emit_join(i64 timestamp,const char *user,const char *room){
+ struct event_item *event=event_item_alloc();
+ event->type=EVENT_JOIN;
+ event->timestamp=timestamp;
+ event->user=strdup(user);
+ event->room=strdup(room);
+ event_emit(event);
+ event_item_free(event);
+}