From d26bd78644544151b42600c5358d0fecc84b14f1 Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Mon, 12 Oct 2026 22:43:23 +0300 Subject: feat: implement modern Approach A app runner, unified events, notepad, and game examples --- tests/common/test_app.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 tests/common/test_app.c (limited to 'tests/common') diff --git a/tests/common/test_app.c b/tests/common/test_app.c new file mode 100644 index 0000000..661620c --- /dev/null +++ b/tests/common/test_app.c @@ -0,0 +1,134 @@ +#define _DEFAULT_SOURCE +#include "yasl/app.h" + +#include +#include +#include +#include + +struct test_state { + struct yasl_display *display; + struct yasl_surface *surface; + bool init_called; + bool frame_called; + bool user_event_called; + bool timer_called; + bool quit_called; + int frame_count; + yasl_timer_id timer_id; +}; + +static void *worker_thread(void *arg) +{ + struct test_state *state = arg; + usleep(50000); /* 50ms */ + bool ok = yasl_post_event(state->display, state->surface, 42, (void *)0x1234, 0); + assert(ok); + return NULL; +} + +static uint64_t on_timer(void *ud, yasl_timer_id id, uint64_t interval_ns) +{ + (void)id; + (void)interval_ns; + struct test_state *state = ud; + state->timer_called = true; + yasl_surface_request_frame(state->surface); + return 0; /* one-shot */ +} + +static int on_init(void *ud, struct yasl_display *d) +{ + struct test_state *state = ud; + state->display = d; + state->init_called = true; + + struct yasl_surface_spec spec = { + .title = "App Runner Test", + .size = {320, 240}, + }; + state->surface = yasl_surface_create_toplevel(d, &spec); + assert(state->surface != NULL); + + yasl_surface_set_pacing(state->surface, YASL_PACING_ON_DEMAND); + yasl_surface_set_mouse_mode(state->surface, YASL_MOUSE_RELATIVE); + yasl_surface_set_mouse_mode(state->surface, YASL_MOUSE_NORMAL); + + state->timer_id = yasl_app_add_timer(d, YASL_MS_TO_NS(20), on_timer, state); + assert(state->timer_id > 0); + + pthread_t thread; + int err = pthread_create(&thread, NULL, worker_thread, state); + assert(err == 0); + pthread_detach(thread); + + yasl_surface_request_frame(state->surface); + return YASL_APP_CONTINUE; +} + +static int on_event(void *ud, const struct yasl_event *ev) +{ + struct test_state *state = ud; + if (ev->type == YASL_EVENT_USER) { + assert(ev->user.type == 42); + assert(ev->user.payload == (void *)0x1234); + state->user_event_called = true; + yasl_surface_request_frame(state->surface); + } else if (ev->type == YASL_EVENT_WINDOW_CLOSE_REQUEST) { + return YASL_APP_QUIT; + } + return YASL_APP_CONTINUE; +} + +static void on_frame(void *ud, struct yasl_surface *s, struct yasl_frame_context *ctx) +{ + struct test_state *state = ud; + assert(s == state->surface); + assert(ctx->surface == s); + state->frame_called = true; + state->frame_count++; + + if (ctx->cpu.pixels) { + size_t count = (size_t)ctx->size.x * ctx->size.y; + for (size_t i = 0; i < count; i++) { + ctx->cpu.pixels[i] = 0xff204060; + } + bool ok = yasl_frame_present_cpu(ctx, NULL, 0); + assert(ok); + } + + if (state->user_event_called) { + yasl_surface_destroy(state->surface); + } +} + +static void on_quit(void *ud, struct yasl_display *d) +{ + (void)d; + struct test_state *state = ud; + state->quit_called = true; +} + +int main(void) +{ + struct test_state state = {0}; + struct yasl_app_desc desc = { + .app_id = "org.yasl.test.app", + .backend = YASL_BACKEND_AUTO, + .userdata = &state, + .init = on_init, + .event = on_event, + .frame = on_frame, + .quit = on_quit, + }; + + int res = yasl_run(&desc); + assert(res == 0); + assert(state.init_called); + assert(state.frame_called); + assert(state.user_event_called); + assert(state.timer_called); + assert(state.quit_called); + printf("App runner tests passed!\n"); + return 0; +} -- cgit v1.2.3