#ifndef CELL_H #define CELL_H #include #include "quickjs.h" #include "qjs_macros.h" #include "blob.h" #ifdef __cplusplus extern "C" { #endif // blob fns JSValue js_blob_use(JSContext *js); JSValue js_new_blob_stoned_copy(JSContext *js, void *data, size_t bytes); void *js_get_blob_data(JSContext *js, size_t *size, JSValue v); int js_is_blob(JSContext *js, JSValue v); #ifdef HAVE_MIMALLOC typedef struct mi_heap_s mi_heap_t; #endif /* Letter type for unified message queue */ typedef enum { LETTER_BLOB, /* Blob message */ LETTER_CALLBACK /* JSValue callback function */ } letter_type; typedef struct letter { letter_type type; union { blob *blob_data; /* For LETTER_BLOB */ JSValue callback; /* For LETTER_CALLBACK */ }; } letter; #define ACTOR_IDLE 0 // Actor not doing anything #define ACTOR_READY 1 // Actor ready for a turn #define ACTOR_RUNNING 2 // Actor taking a turn #define ACTOR_EXHAUSTED 3 // Actor waiting for GC #define ACTOR_RECLAIMING 4 // Actor running GC #define ACTOR_SLOW 5 // Actor going slowly; deprioritize extern int tracy_profiling_enabled; typedef struct cell_rt { JSContext *context; #ifdef HAVE_MIMALLOC mi_heap_t *heap; #endif JSValue idx_buffer; JSValue on_exception; JSValue message_handle; void *init_wota; /* Protects JSContext usage */ SDL_Mutex *mutex; /* for everything else */ SDL_Mutex *msg_mutex; /* For message queue and timers queue */ char *id; int idx_count; /* The “mailbox” for incoming messages + a dedicated lock for it: */ struct letter *letters; /* CHANGED FOR EVENTS: a separate lock for the actor->events queue */ struct { Uint32 key; JSValue value; } *timers; int state; Uint32 ar; // timer for unneeded double ar_secs; // time for unneeded JSValue unneeded; // fn to call before unneeded int disrupt; int main_thread_only; int affinity; JSAtom actor_sym; const char *name; // human friendly name } cell_rt; extern cell_rt *root_cell; // first actor in the system cell_rt *create_actor(void *wota); const char *register_actor(const char *id, cell_rt *actor, int mainthread, double ar); void actor_disrupt(cell_rt *actor); const char *send_message(const char *id, void *msg); Uint32 actor_timer_cb(cell_rt *actor, SDL_TimerID id, Uint32 interval); JSValue js_actor_delay(JSContext *js, JSValue self, int argc, JSValue *argv); JSValue js_actor_removetimer(JSContext *js, JSValue self, int argc, JSValue *argv); void actor_unneeded(cell_rt *actor, JSValue fn, double seconds); void script_startup(cell_rt *rt); int uncaught_exception(JSContext *js, JSValue v); int actor_exists(const char *id); cell_rt *get_actor(char *id); void set_actor_state(cell_rt *actor); void actor_clock(cell_rt *actor, JSValue fn); int JS_ArrayLength(JSContext *js, JSValue a); int js2bool(JSContext *js, JSValue v); JSValue bool2js(JSContext *js, int b); double js2number(JSContext *js, JSValue v); JSValue number2js(JSContext *js, double g); double cell_random(); void *js2wota(JSContext *js, JSValue v); JSValue wota2js(JSContext *js, void *v); #ifdef __cplusplus } #endif #endif