In particular, I'm trying to learn Haskell's foreign function interface by writing a binding to the Allegro game library. In Allegro's native C, the main event loop looks something like this:
// initialize event struct
ALLEGRO_EVENT event;
// main loop
while (running) {
if (al_get_next_event(event_queue, &event)) {
// process event here ...
}
}
Using ghc and hsc2hs, I can write a foreign function call like:
foreign import ccall "allegro5/allegro.h al_get_next_event"
alGetNextEvent :: EventQueue -> Ptr (Event) -> IO (CInt)
where EventQueue
is a pointer to an opaque structure and Event
is a Storable
instance based off of C's ALLEGRO_EVENT
.
Ideally, for the user-facing Haskell function, I would like to have a type signature like
getNextEvent :: EventQueue -> Maybe Event
which would abstract away initializing the ALLEGRO_EVENT
struct and boolean return value.
My question is, how should I write this function to maximize memory efficiency? I could malloc a new pointer to Event
inside the method and use that, but since I'm working with C-based data, I want to make sure I'm re-using existing space and not constantly allocating new structs. I also want to avoid having the user malloc the struct and pass it in to every call.
Any advice?