#include #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,i64 replyid){ 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->replyid=replyid; 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); } void event_emit_leave(i64 timestamp,const char *user,const char *room){ struct event_item *event=event_item_alloc(); event->type=EVENT_LEAVE; event->timestamp=timestamp; event->user=strdup(user); event->room=strdup(room); event_emit(event); event_item_free(event); }