Last active
April 11, 2018 18:15
-
-
Save flibitijibibo/2dcc0989e5dbc290bd5b1749457738a6 to your computer and use it in GitHub Desktop.
I needed an equivalent to Win32's Event object, so here's an SDL version. Probably isn't good.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* SDL-based Event Object Copycat | |
* Written by Ethan "flibitijibibo" Lee | |
* | |
* Released under public domain. | |
* No warranty implied; use at your own risk. | |
*/ | |
#include <SDL2/SDL.h> | |
typedef struct EventObject EventObject; | |
EventObject* EventObject_Create(Uint8 manual, Uint8 initial); | |
void EventObject_Destroy(EventObject *obj); | |
Uint8 EventObject_Set(EventObject *obj); | |
Uint8 EventObject_Reset(EventObject *obj); | |
Uint8 EventObject_Wait(EventObject *obj, int ms); | |
#ifdef EVENTOBJECT_IMPL /* Define this in EXACTLY ONE FILE that includes this */ | |
struct EventObject | |
{ | |
SDL_cond *cond; | |
SDL_mutex *mutex; | |
Uint8 manual; | |
Uint8 value; | |
Uint8 threads; | |
}; | |
EventObject* EventObject_Create(Uint8 manual, Uint8 initial) | |
{ | |
EventObject *obj = (EventObject*) SDL_malloc(sizeof(EventObject)); | |
obj->mutex = SDL_CreateMutex(); | |
obj->cond = SDL_CreateCond(); | |
obj->manual = manual; | |
obj->value = (initial > 0) ? 0xFF : 0; | |
obj->threads = 0; | |
return obj; | |
} | |
void EventObject_Destroy(EventObject *obj) | |
{ | |
/* Signal all remaining threads */ | |
SDL_LockMutex(obj->mutex); | |
obj->value = 0xFF; | |
SDL_CondBroadcast(obj->cond); | |
/* Constantly lock/unlock to get threads outta here */ | |
while (obj->threads > 0) | |
{ | |
SDL_UnlockMutex(obj->mutex); | |
SDL_LockMutex(obj->mutex); | |
} | |
/* Destroy, finally. */ | |
SDL_DestroyCond(obj->cond); | |
SDL_UnlockMutex(obj->mutex); | |
SDL_DestroyMutex(obj->mutex); | |
SDL_free(obj); | |
} | |
Uint8 EventObject_Set(EventObject *obj) | |
{ | |
SDL_LockMutex(obj->mutex); | |
if (obj->manual) | |
{ | |
/* For manual events, signal all threads */ | |
obj->value = 0xFF; | |
SDL_CondBroadcast(obj->cond); | |
} | |
else | |
{ | |
/* For auto events, only give one thread a signal */ | |
obj->value += 1; | |
SDL_CondSignal(obj->cond); | |
} | |
SDL_UnlockMutex(obj->mutex); | |
return 1; | |
} | |
Uint8 EventObject_Reset(EventObject *obj) | |
{ | |
SDL_LockMutex(obj->mutex); | |
obj->value = 0; | |
SDL_UnlockMutex(obj->mutex); | |
return 1; | |
} | |
Uint8 EventObject_Wait(EventObject *obj, int ms) | |
{ | |
SDL_LockMutex(obj->mutex); | |
obj->threads += 1; | |
/* Initial check to see if we're already signaled */ | |
if (obj->value == 0xFF) | |
{ | |
obj->threads -= 1; | |
SDL_UnlockMutex(obj->mutex); | |
return 1; | |
} | |
if (obj->value > 0) | |
{ | |
obj->value -= 1; | |
obj->threads -= 1; | |
SDL_UnlockMutex(obj->mutex); | |
return 1; | |
} | |
/* Wait... */ | |
SDL_CondWaitTimeout( | |
obj->cond, | |
obj->mutex, | |
ms < 0 ? SDL_MUTEX_MAXWAIT : ms | |
); | |
/* Check for signal one last time... */ | |
if (obj->value == 0xFF) | |
{ | |
obj->threads -= 1; | |
SDL_UnlockMutex(obj->mutex); | |
return 1; | |
} | |
if (obj->value > 0) | |
{ | |
obj->value -= 1; | |
obj->threads -= 1; | |
SDL_UnlockMutex(obj->mutex); | |
return 1; | |
} | |
obj->threads -= 1; | |
SDL_UnlockMutex(obj->mutex); | |
return 0; /* Timed out. If not, what the hell? */ | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment