#ifndef PROSPERON_H #define PROSPERON_H #include #include "quickjs.h" #include "qjs_macros.h" #include "qjs_blob.h" #include "blob.h" /* Letter type for unified message queue */ typedef enum { LETTER_WOTA, /* Raw wota message */ LETTER_CALLBACK /* JSValue callback function */ } letter_type; typedef struct letter { letter_type type; union { void *wota_data; /* For LETTER_WOTA */ JSValue callback; /* For LETTER_CALLBACK */ }; } letter; #define STATE_VECTOR_LENGTH 624 #define STATE_VECTOR_M 397 #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 typedef JSValue (*MODULEFN)(JSContext *js); extern int tracy_profiling_enabled; typedef struct tagMTRand { uint32_t mt[STATE_VECTOR_LENGTH]; int32_t index; } MTRand; typedef struct { const char *name; MODULEFN fn; } ModuleEntry; typedef struct cell_rt { JSContext *context; JSValue idx_buffer; JSValue on_exception; JSValue message_handle; void *init_wota; ModuleEntry *module_registry; JSValue *js_swapchains; /* Protects JSContext usage */ SDL_Mutex *mutex; /* for everything else */ SDL_Mutex *msg_mutex; /* For message queue and timers queue */ char *id; MTRand mrand; 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 SDL_TLSID prosperon_id; 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); int JS_ArrayLength(JSContext *js, JSValue a); int prosperon_mount_core(void); #endif