API Design
/* A cooperative task is a function that yields control back to the game loop
at defined points. Tasks resume where they left off next frame. */
/* Task states */
typedef enum {
SH_TASK_READY, /* Waiting to run */
SH_TASK_RUNNING, /* Currently executing */
SH_TASK_YIELDED, /* Yielded, will resume next frame */
SH_TASK_SLEEPING, /* Yielded with timer, resumes after N ms */
SH_TASK_DONE, /* Completed */
} sh_task_state_t;
/* Task handle (opaque) */
typedef struct sh_task sh_task_t;
/* Task function signature. Return 0 = done, 1 = yield (resume next frame). */
typedef int (*sh_task_fn)(sh_task_t *self, void *userdata);
/* Task scheduler (lives in game loop) */
typedef struct {
sh_task_t *tasks[16]; /* Max 16 concurrent tasks */
int count;
uint64_t frame_budget_ns; /* Max ns to spend on tasks per frame */
} sh_scheduler_t;
/* Initialize scheduler. budget_ns = 0 means no limit (run all ready tasks). */
void sh_scheduler_init(sh_scheduler_t *sched, uint64_t frame_budget_ns);
/* Create and enqueue a cooperative task. */
sh_task_t *sh_task_create(sh_scheduler_t *sched, sh_task_fn fn, void *userdata);
/* Yield current task (resume next frame). Call from within task function. */
void sh_task_yield(sh_task_t *self);
/* Yield current task for N milliseconds. */
void sh_task_sleep(sh_task_t *self, uint32_t ms);
/* Check if task is done. */
int sh_task_is_done(const sh_task_t *self);
/* Destroy a completed task. */
void sh_task_destroy(sh_task_t *task);
/* Run ready tasks. Call once per frame, typically after update() but before render().
Respects frame_budget_ns — stops running tasks if budget exceeded. */
void sh_scheduler_tick(sh_scheduler_t *sched);
/* Destroy scheduler and all tasks. */
void sh_scheduler_shutdown(sh_scheduler_t *sched);
/* --- Async I/O (uses KOS worker thread underneath) --- */
/* Request async file read. Returns immediately. Check sh_task_is_done(). */
sh_task_t *sh_async_read(sh_scheduler_t *sched,
const char *path,
void **out_data,
int *out_size);
/* Request async texture load (file read + VRAM upload). */
sh_task_t *sh_async_tex_load(sh_scheduler_t *sched,
const char *path,
sh_texture_t *out);