File GameFrameworkEvent.c
File List > engine > src > gameframework > GameFrameworkEvent.c
Go to the documentation of this file
#include "GameFrameworkEvent.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "StringKeyHashMap.h"
#include "AssertLib.h"
#include "Log.h"
#define EVENT_MAX_NAME_LEN 64
static struct HashMap gEventMap;
struct GameFrameworkEventListener
{
void* userData;
EventListenerFn eventFn;
struct GameFrameworkEventListener* pNext;
struct GameFrameworkEventListener* pPrev;
char eventName[EVENT_MAX_NAME_LEN];
};
struct GameFrameworkEvent
{
struct GameFrameworkEventListener* pListenerHead;
struct GameFrameworkEventListener* pListenerTail;
};
static struct GameFrameworkEventListener* AddListener(struct GameFrameworkEvent* pEvent, EventListenerFn listenerFn, void* pUser, char* eventName)
{
struct GameFrameworkEventListener* pListener = malloc(sizeof(struct GameFrameworkEventListener));
EASSERT(pListener);
memset(pListener, 0, sizeof(struct GameFrameworkEventListener));
strcpy(pListener->eventName, eventName);
pListener->eventFn = listenerFn;
pListener->userData = pUser;
if (!pEvent->pListenerTail)
{
EASSERT(!pEvent->pListenerHead);
pEvent->pListenerTail = pListener;
pEvent->pListenerHead = pListener;
pListener->pNext = NULL;
pListener->pPrev = NULL;
}
else
{
pEvent->pListenerTail->pNext = pListener;
pListener->pPrev = pEvent->pListenerTail;
pListener->pNext = NULL;
pEvent->pListenerTail = pListener;
}
return pListener;
}
struct GameFrameworkEventListener* Ev_SubscribeEvent(char* eventName, EventListenerFn listenerFn, void* pUser)
{
Log_Verbose("SUBSCRIBING TO EVENT %s", eventName);
EASSERT(strlen(eventName) < EVENT_MAX_NAME_LEN);
struct GameFrameworkEvent* pEvent = HashmapSearch(&gEventMap, eventName);
if (pEvent == NULL)
{
struct GameFrameworkEvent ev;
memset(&ev, 0, sizeof(struct GameFrameworkEvent));
pEvent = HashmapInsert(&gEventMap, eventName, &ev);
}
return AddListener(pEvent, listenerFn, pUser, eventName);
}
bool Ev_UnsubscribeEvent(struct GameFrameworkEventListener* pListener)
{
Log_Verbose("UNSUBSCRIBING TO EVENT %s", pListener->eventName);
struct GameFrameworkEvent* pEvent = HashmapSearch(&gEventMap, pListener->eventName);
if (pEvent)
{
if (pEvent->pListenerHead == pListener)
{
pEvent->pListenerHead = pListener->pNext;
}
if (pEvent->pListenerTail == pListener)
{
pEvent->pListenerTail = pListener->pPrev;
}
if (pListener->pNext)
{
pListener->pNext->pPrev = pListener->pPrev;
}
if (pListener->pPrev)
{
pListener->pPrev->pNext = pListener->pNext;
}
free(pListener);
return true;
}
else
{
Log_Warning("Ev_UnsubscribeEvent failed. Event name '%s'", pListener->eventName);
}
return false;
}
void Ev_FireEvent(char* eventName, void* eventArgs)
{
int i = 0;
Log_Verbose("FIRING EVENT %s", eventName);
struct GameFrameworkEvent* pEvent = HashmapSearch(&gEventMap, eventName);
if (pEvent)
{
struct GameFrameworkEventListener* pListener = pEvent->pListenerHead;
while (pListener)
{
pListener->eventFn(pListener->userData, eventArgs);
pListener = pListener->pNext;
Log_Verbose("%s DEBUG COUNT %i", eventName, i++);
}
}
}
void Ev_Init()
{
HashmapInit(&gEventMap, 16, sizeof(struct GameFrameworkEvent));
}
void* Ev_GetUserData(struct GameFrameworkEventListener* pListener)
{
return pListener->userData;
}