Banjo API 1.0.0-rc.2
Low-level C99 game development API
Loading...
Searching...
No Matches
event_polling.c

Event handling using the polling pattern.

Event handling using the polling pattern.This demonstrates polling events from a queue instead of using callbacks. Polling gives you fine-grained control over when and how events are processed, which is useful for game loops and custom event prioritization.

The window is created resizable (BJ_WINDOW_FLAG_RESIZABLE): drag any edge to resize it. Resizing is not one of the queued event types, so it cannot be pulled from the poll loop like the input events. Instead we register a bj_set_resize_callback, exactly as event_callbacks.c does, which shows the two styles coexisting: input is polled from the queue, while a size change is delivered to a callback.

#include <banjo/app.h>
#include <banjo/main.h>
#include <banjo/error.h>
#include <banjo/event.h>
#include <banjo/log.h>
#include <banjo/memory.h>
#include <banjo/system.h>
#include <banjo/window.h>
typedef struct {
size_t cursor;
size_t button;
size_t key;
size_t enter;
size_t resize;
// Resize is not a queued event type, so even a polling program reacts to it
// through a callback. Registered per-window with bj_set_resize_callback, it
// receives the new width and height directly.
static void resize_callback(bj_window* p_window, int width, int height, void* data) {
++counter->resize;
bj_info("Resize event, window %p, %dx%d", (void*)p_window, width, height);
}
static void* setup(struct bj_app* app, void* init_data) {
(void)init_data;
event_counter* counter = bj_calloc(sizeof(event_counter));
bj_free(counter);
bj_quit_app(app, 1);
return 0;
}
window = bj_bind_window("Event Polling", 100, 100, 800, 600, BJ_WINDOW_FLAG_RESIZABLE, 0);
return counter;
}
static void step(struct bj_app* app, struct bj_tick_info tick, void* user_data) {
(void)tick;
event_counter* counter = (event_counter*)user_data;
// Poll events from the queue. bj_poll_events() fills the event structure
// and returns true if an event was available, false when the queue is empty.
// Process all queued events in a loop before continuing with your frame logic.
while (bj_poll_events(&e)) {
// Each event has a type field that determines which union member is valid.
switch (e.type) {
// Mouse cursor entering or leaving the window.
++counter->enter;
bj_info("Enter event, window %p, %s, (%d,%d)",
e.as.enter.enter ? "entered" : "left",
e.as.enter.x, e.as.enter.y
);
break;
// Mouse movement within the window.
++counter->cursor;
bj_info("Cursor event, window %p, (%d,%d)",
window, e.as.cursor.x, e.as.cursor.y
);
break;
// Keyboard input. Action can be PRESS, RELEASE, or REPEAT.
++counter->key;
const char* action_str = "pressed";
if (e.as.key.action != BJ_PRESS) {
action_str = e.as.key.action == BJ_RELEASE ? "released" : "repeated";
}
bj_info("Key 0x%04X (%s) Scancode 0x%04X (with no mods) was %s",
e.as.key.key, bj_key_name(e.as.key.key), e.as.key.scancode, action_str
);
// With polling, you manually check for keys like ESC and handle
// them explicitly, unlike with callbacks where you register handlers.
if (e.as.key.key == BJ_KEY_ESCAPE) {
}
break;
// Mouse button clicks. Button index and position are provided.
++counter->button;
bj_info("Button event, window %p, button %d, %s, (%d,%d)",
(void*)window, e.as.button.button,
e.as.button.action == BJ_PRESS ? "pressed" : "released",
e.as.button.x, e.as.button.y
);
break;
}
}
bj_quit_app(app, 0);
}
}
static void teardown(struct bj_app* app, void* user_data) {
(void)app;
event_counter* counter = (event_counter*)user_data;
bj_info("Total events: %ld cursor, %ld button, %ld key, %ld enter, %ld resize",
counter->cursor, counter->button, counter->key, counter->enter, counter->resize
);
bj_end();
bj_free(counter);
}
int main(int argc, char* argv[]) {
(void)argc; (void)argv;
return bj_run_app(setup, step, 0, teardown, 0);
}
Application lifecycle: callback-driven setup, step, and teardown.
int main(int argc, char *argv[])
Definition audio_pcm.c:177
static void step(struct bj_app *app, struct bj_tick_info tick, void *user_data)
Definition audio_pcm.c:144
static void teardown(struct bj_app *app, void *user_data)
Definition audio_pcm.c:170
bj_audio_play_note_data data
Definition audio_pcm.c:104
static void * setup(struct bj_app *app, void *init_data)
Definition audio_pcm.c:107
bj_window * window
Definition bitmap_blit.c:24
Recoverable error handling.
Sytem event management API.
void resize_callback(bj_window *p_window, int width, int height, void *data)
int bj_run_app(bj_app_setup_fn setup, bj_app_step_fn step, bj_app_fixed_step_fn fixed_step, bj_app_teardown_fn teardown, void *init_data)
Drive the application lifecycle.
void bj_quit_app(struct bj_app *app, int exit_code)
Signal the given application to exit on the next iteration.
Timing snapshot handed to the step and fixed-step callbacks.
Definition app.h:106
struct bj_window bj_window
Definition api.h:354
union bj_event::@102271004006361263344115053024230242311221140216 as
enum bj_event_type type
Type of event.
Definition event.h:455
const char * bj_key_name(int key)
Get the string name of a key.
bj_bool bj_poll_events(struct bj_event *event)
Poll the next pending event from the system queue.
@ BJ_KEY_ESCAPE
Esc key.
Definition event.h:176
@ BJ_EVENT_BUTTON
Mouse button.
Definition event.h:442
@ BJ_EVENT_KEY
Keyboard key.
Definition event.h:441
@ BJ_EVENT_ENTER
Mouse enter/leave.
Definition event.h:439
@ BJ_EVENT_CURSOR
Mouse move.
Definition event.h:440
@ BJ_PRESS
The key or button was pressed.
Definition event.h:392
@ BJ_RELEASE
The key or button was released.
Definition event.h:391
Represent a generic window-related event.
Definition event.h:453
#define bj_info(...)
Log a message using the BJ_LOG_INFO level.
Definition log.h:141
void * bj_calloc(size_t size)
Allocate size bytes of zero-initialised memory.
void bj_free(void *memory)
Free a previously allocated memory block.
bj_bool bj_begin(int systems, struct bj_error **error)
Initialises the system.
void bj_end(void)
De-initialises the system.
@ BJ_VIDEO_SYSTEM
Definition system.h:81
void bj_set_window_should_close(struct bj_window *window)
Flag a given window to be closed.
struct bj_window * bj_bind_window(const char *title, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t flags, struct bj_error **error)
Create a new struct bj_window with the specified attributes.
void bj_set_resize_callback(struct bj_window *window, bj_window_resize_fn fn, void *user_data)
Register the resize callback for window.
bj_bool bj_should_close_window(struct bj_window *window)
Get the close flag state of a window.
void bj_unbind_window(struct bj_window *window)
Deletes a struct bj_window object and releases associated memory.
@ BJ_WINDOW_FLAG_RESIZABLE
User may resize the window.
Definition window.h:190
Logging utility functions.
Portable main() replacement with platform-aware entry shim.
All memory-related functions, including custom allocators.
Header file for system interactions.
Header file for bj_window type.