remove sdl dependency
This commit is contained in:
539
source/cell.c
539
source/cell.c
@@ -11,8 +11,6 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <SDL3/SDL_atomic.h>
|
||||
|
||||
#define WOTA_IMPLEMENTATION
|
||||
#include "wota.h"
|
||||
|
||||
@@ -50,148 +48,10 @@ int tracy_profiling_enabled = 0;
|
||||
|
||||
#define ENGINE "engine.cm"
|
||||
|
||||
static cell_rt **ready_queue = NULL;
|
||||
static SDL_Semaphore *ready_sem;
|
||||
static SDL_SpinLock queue_lock = 0;
|
||||
|
||||
static cell_rt **main_queue = NULL;
|
||||
static SDL_Semaphore *main_sem;
|
||||
static SDL_SpinLock main_queue_lock = 0;
|
||||
|
||||
static SDL_Mutex *actors_mutex = NULL;
|
||||
static struct { char *key; cell_rt *value; } *actors = NULL;
|
||||
|
||||
static qop_desc qop_core;
|
||||
static qop_file *qop_hashmap = NULL;
|
||||
cell_rt *root_cell = NULL;
|
||||
|
||||
static SDL_AtomicInt shutting_down;
|
||||
static SDL_AtomicInt runners_count;
|
||||
|
||||
static void exit_handler(void)
|
||||
{
|
||||
SDL_SetAtomicInt(&shutting_down, 1);
|
||||
|
||||
/* Signal all waiting threads */
|
||||
int count = SDL_GetAtomicInt(&runners_count);
|
||||
for (int i = 0; i < count; i++)
|
||||
SDL_SignalSemaphore(ready_sem);
|
||||
|
||||
/* Signal main thread in case it's waiting */
|
||||
SDL_SignalSemaphore(main_sem);
|
||||
|
||||
/* Wait for all runner threads to exit */
|
||||
while (SDL_GetAtomicInt(&runners_count) > 0) {
|
||||
SDL_Delay(10);
|
||||
}
|
||||
|
||||
if (ready_sem)
|
||||
SDL_DestroySemaphore(ready_sem);
|
||||
if (main_sem)
|
||||
SDL_DestroySemaphore(main_sem);
|
||||
if (actors_mutex)
|
||||
SDL_DestroyMutex(actors_mutex);
|
||||
|
||||
/* Clean up QOP resources */
|
||||
if (qop_hashmap) {
|
||||
free(qop_hashmap);
|
||||
qop_hashmap = NULL;
|
||||
}
|
||||
if (qop_core.data) {
|
||||
free(qop_core.data);
|
||||
qop_core.data = NULL;
|
||||
}
|
||||
qop_close(&qop_core);
|
||||
|
||||
SDL_Quit();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void actor_free(cell_rt *actor)
|
||||
{
|
||||
// Delete it out of actors first so it can no longer get messages
|
||||
SDL_LockMutex(actors_mutex);
|
||||
shdel(actors, actor->id);
|
||||
SDL_UnlockMutex(actors_mutex);
|
||||
|
||||
// If in a queue, remove it
|
||||
SDL_LockSpinlock(&queue_lock);
|
||||
for (int i = 0; i < arrlen(ready_queue); i++) {
|
||||
if (ready_queue[i] == actor) {
|
||||
arrdel(ready_queue, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
SDL_UnlockSpinlock(&queue_lock);
|
||||
|
||||
SDL_LockSpinlock(&main_queue_lock);
|
||||
for (int i = 0; i < arrlen(main_queue); i++) {
|
||||
if (main_queue[i] == actor) {
|
||||
arrdel(main_queue, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
SDL_UnlockSpinlock(&main_queue_lock);
|
||||
|
||||
// Do not go forward with actor destruction until the actor is completely free
|
||||
SDL_LockMutex(actor->msg_mutex);
|
||||
SDL_LockMutex(actor->mutex);
|
||||
|
||||
JSContext *js = actor->context;
|
||||
|
||||
JS_FreeValue(js, actor->idx_buffer);
|
||||
JS_FreeValue(js, actor->message_handle);
|
||||
JS_FreeValue(js, actor->on_exception);
|
||||
JS_FreeValue(js, actor->unneeded);
|
||||
JS_FreeAtom(js, actor->actor_sym);
|
||||
|
||||
SDL_RemoveTimer(actor->ar);
|
||||
|
||||
/* Free timer callbacks stored in actor */
|
||||
for (int i = 0; i < hmlen(actor->timers); i++) {
|
||||
JS_FreeValue(js, actor->timers[i].value);
|
||||
}
|
||||
|
||||
hmfree(actor->timers);
|
||||
|
||||
/* Free all letters in the queue */
|
||||
for (int i = 0; i < arrlen(actor->letters); i++) {
|
||||
if (actor->letters[i].type == LETTER_BLOB) {
|
||||
blob_destroy(actor->letters[i].blob_data);
|
||||
} else if (actor->letters[i].type == LETTER_CALLBACK) {
|
||||
JS_FreeValue(js, actor->letters[i].callback);
|
||||
}
|
||||
}
|
||||
|
||||
arrfree(actor->letters);
|
||||
|
||||
JSRuntime *rt = JS_GetRuntime(js);
|
||||
JS_SetInterruptHandler(rt, NULL, NULL);
|
||||
JS_FreeContext(js);
|
||||
JS_FreeRuntime(rt);
|
||||
free(actor->id);
|
||||
|
||||
SDL_UnlockMutex(actor->mutex);
|
||||
SDL_DestroyMutex(actor->mutex);
|
||||
SDL_UnlockMutex(actor->msg_mutex);
|
||||
SDL_DestroyMutex(actor->msg_mutex);
|
||||
|
||||
#ifdef HAVE_MIMALLOC
|
||||
mi_heap_destroy(actor->heap);
|
||||
#endif
|
||||
free(actor);
|
||||
|
||||
SDL_LockMutex(actors_mutex);
|
||||
if (shlen(actors) == 0)
|
||||
exit(0);
|
||||
SDL_UnlockMutex(actors_mutex);
|
||||
}
|
||||
|
||||
void js_dofree(JSRuntime *rt, void *opaque, void *ptr)
|
||||
{
|
||||
js_free_rt(rt, ptr);
|
||||
}
|
||||
|
||||
static size_t js_mi_malloc_usable_size(const void *ptr)
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
@@ -419,298 +279,6 @@ int prosperon_mount_core(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void actor_unneeded(cell_rt *actor, JSValue fn, double seconds)
|
||||
{
|
||||
if (actor->disrupt) return;
|
||||
JS_FreeValue(actor->context, actor->unneeded);
|
||||
|
||||
if (!JS_IsFunction(actor->context, fn)) {
|
||||
actor->unneeded = JS_NULL;
|
||||
goto END;
|
||||
}
|
||||
|
||||
actor->unneeded = JS_DupValue(actor->context, fn);
|
||||
actor->ar_secs = seconds;
|
||||
|
||||
END:
|
||||
if (actor->ar) {
|
||||
SDL_RemoveTimer(actor->ar);
|
||||
actor->ar = 0;
|
||||
}
|
||||
set_actor_state(actor);
|
||||
}
|
||||
|
||||
cell_rt *create_actor(void *wota)
|
||||
{
|
||||
cell_rt *actor = calloc(sizeof(*actor), 1);
|
||||
#ifdef HAVE_MIMALLOC
|
||||
actor->heap = mi_heap_new();
|
||||
#endif
|
||||
actor->init_wota = wota;
|
||||
actor->idx_buffer = JS_NULL;
|
||||
actor->message_handle = JS_NULL;
|
||||
actor->unneeded = JS_NULL;
|
||||
actor->on_exception = JS_NULL;
|
||||
actor->actor_sym = JS_ATOM_NULL;
|
||||
|
||||
arrsetcap(actor->letters, 5);
|
||||
|
||||
actor->mutex = SDL_CreateMutex(); /* Protects JSContext + state */
|
||||
actor->msg_mutex = SDL_CreateMutex(); /* Mailbox queue lock */
|
||||
|
||||
/* Lock actor->mutex while initializing JS runtime. */
|
||||
SDL_LockMutex(actor->mutex);
|
||||
script_startup(actor);
|
||||
set_actor_state(actor);
|
||||
SDL_UnlockMutex(actor->mutex);
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
cell_rt *get_actor(char *id)
|
||||
{
|
||||
SDL_LockMutex(actors_mutex);
|
||||
int idx = shgeti(actors, id);
|
||||
if (idx == -1) {
|
||||
SDL_UnlockMutex(actors_mutex);
|
||||
return NULL;
|
||||
}
|
||||
cell_rt *actor = actors[idx].value;
|
||||
SDL_UnlockMutex(actors_mutex);
|
||||
return actor;
|
||||
}
|
||||
|
||||
const char *register_actor(const char *id, cell_rt *actor, int mainthread, double ar)
|
||||
{
|
||||
SDL_LockMutex(actors_mutex);
|
||||
if (shgeti(actors, id) != -1) {
|
||||
SDL_UnlockMutex(actors_mutex);
|
||||
return "Actor with given ID already exists.";
|
||||
}
|
||||
actor->main_thread_only = mainthread;
|
||||
actor->id = strdup(id);
|
||||
actor->ar_secs = ar;
|
||||
shput(actors, id, actor);
|
||||
SDL_UnlockMutex(actors_mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *send_message(const char *id, void *msg)
|
||||
{
|
||||
cell_rt *target = get_actor(id);
|
||||
if (!target) {
|
||||
blob_destroy((blob *)msg);
|
||||
return "Could not get actor from id.";
|
||||
}
|
||||
|
||||
letter l;
|
||||
l.type = LETTER_BLOB;
|
||||
l.blob_data = (blob *)msg;
|
||||
|
||||
SDL_LockMutex(target->msg_mutex);
|
||||
|
||||
arrput(target->letters, l);
|
||||
if (target->ar) {
|
||||
SDL_RemoveTimer(target->ar);
|
||||
target->ar = 0;
|
||||
}
|
||||
SDL_UnlockMutex(target->msg_mutex);
|
||||
|
||||
set_actor_state(target);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Uint32 actor_remove_cb(cell_rt *actor, Uint32 id, Uint32 interval)
|
||||
{
|
||||
actor->disrupt = 1;
|
||||
|
||||
if (!JS_IsNull(actor->unneeded)) {
|
||||
SDL_LockMutex(actor->mutex);
|
||||
JSValue ret = JS_Call(actor->context, actor->unneeded, JS_NULL, 0, NULL);
|
||||
uncaught_exception(actor->context, ret);
|
||||
SDL_UnlockMutex(actor->mutex);
|
||||
}
|
||||
|
||||
actor_free(actor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Timer callback adds an event to the queue under evt_mutex. */
|
||||
Uint32 actor_delay_cb(cell_rt *actor, SDL_TimerID id, Uint32 interval)
|
||||
{
|
||||
SDL_LockMutex(actor->msg_mutex);
|
||||
int idx = hmgeti(actor->timers, id);
|
||||
if (idx == -1) goto END;
|
||||
|
||||
JSValue cb = actor->timers[idx].value;
|
||||
hmdel(actor->timers, id);
|
||||
actor_clock(actor, cb);
|
||||
JS_FreeValue(actor->context, cb);
|
||||
|
||||
END:
|
||||
SDL_UnlockMutex(actor->msg_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_actor_state(cell_rt *actor)
|
||||
{
|
||||
if (actor->disrupt) {
|
||||
actor_free(actor);
|
||||
return;
|
||||
}
|
||||
SDL_LockMutex(actor->msg_mutex);
|
||||
|
||||
switch(actor->state) {
|
||||
case ACTOR_RUNNING:
|
||||
case ACTOR_READY:
|
||||
if (actor->ar) {
|
||||
SDL_RemoveTimer(actor->ar);
|
||||
actor->ar = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTOR_IDLE:
|
||||
if (arrlen(actor->letters)) {
|
||||
actor->state = ACTOR_READY;
|
||||
if (actor->main_thread_only) {
|
||||
SDL_LockSpinlock(&main_queue_lock);
|
||||
arrput(main_queue, actor);
|
||||
SDL_UnlockSpinlock(&main_queue_lock);
|
||||
SDL_SignalSemaphore(main_sem);
|
||||
} else {
|
||||
SDL_LockSpinlock(&queue_lock);
|
||||
arrput(ready_queue, actor);
|
||||
SDL_UnlockSpinlock(&queue_lock);
|
||||
SDL_SignalSemaphore(ready_sem);
|
||||
}
|
||||
} else if (!arrlen(actor->letters) && !hmlen(actor->timers))
|
||||
actor->ar = SDL_AddTimerNS(actor->ar_secs*1e9, actor_remove_cb, actor);
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_UnlockMutex(actor->msg_mutex);
|
||||
}
|
||||
|
||||
void actor_turn(cell_rt *actor)
|
||||
{
|
||||
SDL_LockMutex(actor->mutex);
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
int entered = 0;
|
||||
if (tracy_profiling_enabled && TracyCIsConnected) {
|
||||
TracyCFiberEnter(actor->name);
|
||||
entered = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
actor->state = ACTOR_RUNNING;
|
||||
|
||||
TAKETURN:
|
||||
|
||||
SDL_LockMutex(actor->msg_mutex);
|
||||
JSValue result;
|
||||
if (!arrlen(actor->letters)) {
|
||||
SDL_UnlockMutex(actor->msg_mutex);
|
||||
goto ENDTURN;
|
||||
}
|
||||
letter l = actor->letters[0];
|
||||
arrdel(actor->letters, 0);
|
||||
SDL_UnlockMutex(actor->msg_mutex);
|
||||
|
||||
if (l.type == LETTER_BLOB) {
|
||||
// Create a JS blob from the C blob
|
||||
size_t size = l.blob_data->length / 8; // Convert bits to bytes
|
||||
JSValue arg = js_new_blob_stoned_copy(actor->context, l.blob_data->data, size);
|
||||
blob_destroy(l.blob_data);
|
||||
result = JS_Call(actor->context, actor->message_handle, JS_NULL, 1, &arg);
|
||||
uncaught_exception(actor->context, result);
|
||||
JS_FreeValue(actor->context, arg);
|
||||
} else if (l.type == LETTER_CALLBACK) {
|
||||
result = JS_Call(actor->context, l.callback, JS_NULL, 0, NULL);
|
||||
uncaught_exception(actor->context, result);
|
||||
JS_FreeValue(actor->context, l.callback);
|
||||
}
|
||||
|
||||
if (actor->disrupt) goto ENDTURN;
|
||||
|
||||
// If there are no waiting threads, bail. otherwise, try for another turn
|
||||
SDL_LockSpinlock(&queue_lock);
|
||||
int someone_else_waiting = (arrlen(ready_queue) > 0);
|
||||
SDL_UnlockSpinlock(&queue_lock);
|
||||
|
||||
if (!someone_else_waiting) goto TAKETURN;
|
||||
|
||||
ENDTURN:
|
||||
actor->state = ACTOR_IDLE;
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
if (tracy_profiling_enabled && entered)
|
||||
TracyCFiberLeave(actor->name);
|
||||
#endif
|
||||
|
||||
set_actor_state(actor);
|
||||
|
||||
SDL_UnlockMutex(actor->mutex);
|
||||
}
|
||||
|
||||
void actor_clock(cell_rt *actor, JSValue fn)
|
||||
{
|
||||
SDL_LockMutex(actor->msg_mutex);
|
||||
letter l;
|
||||
l.type = LETTER_CALLBACK;
|
||||
l.callback = JS_DupValue(actor->context, fn);
|
||||
arrput(actor->letters, l);
|
||||
SDL_UnlockMutex(actor->msg_mutex);
|
||||
set_actor_state(actor);
|
||||
}
|
||||
|
||||
/* JS function that schedules a timer. */
|
||||
JSValue js_actor_delay(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
if (!JS_IsFunction(js, argv[0]))
|
||||
return JS_ThrowReferenceError(js, "Argument must be a function.");
|
||||
|
||||
cell_rt *actor = JS_GetContextOpaque(js);
|
||||
double seconds;
|
||||
JS_ToFloat64(js, &seconds, argv[1]);
|
||||
if (seconds <= 0) {
|
||||
actor_clock(actor, argv[0]);
|
||||
return JS_NULL;
|
||||
}
|
||||
|
||||
SDL_LockMutex(actor->msg_mutex);
|
||||
uint32_t id = SDL_AddTimerNS(seconds*1e9, actor_delay_cb, actor);
|
||||
JSValue cb = JS_DupValue(js, argv[0]);
|
||||
hmput(actor->timers, id, cb);
|
||||
SDL_UnlockMutex(actor->msg_mutex);
|
||||
return JS_NewUint32(js, id);
|
||||
}
|
||||
|
||||
JSValue js_actor_removetimer(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
cell_rt *actor = JS_GetContextOpaque(js);
|
||||
uint32_t timer_id;
|
||||
JS_ToUint32(js, &timer_id, argv[0]);
|
||||
if (timer_id == -1) return JS_NULL;
|
||||
|
||||
SDL_RemoveTimer(timer_id);
|
||||
|
||||
JSValue cb = JS_NULL;
|
||||
|
||||
SDL_LockMutex(actor->msg_mutex);
|
||||
int id = hmgeti(actor->timers, timer_id);
|
||||
if (id != -1) {
|
||||
cb = actor->timers[id].value;
|
||||
hmdel(actor->timers, timer_id);
|
||||
}
|
||||
SDL_UnlockMutex(actor->msg_mutex);
|
||||
|
||||
JS_FreeValue(js,cb);
|
||||
|
||||
return JS_NULL;
|
||||
}
|
||||
|
||||
// Wrapper struct to keep the array pointer stable
|
||||
typedef struct {
|
||||
#ifdef TRACY_ENABLE
|
||||
@@ -720,10 +288,10 @@ typedef struct {
|
||||
#endif
|
||||
} tracy_stack_t;
|
||||
|
||||
// Global TLS ID for the Tracy stack
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
static SDL_TLSID tracy_stack_id = {0};
|
||||
|
||||
// Cleanup function for the wrapper struct
|
||||
static void tracy_cleanup_stack(void *value)
|
||||
{
|
||||
tracy_stack_t *stack = value;
|
||||
@@ -733,7 +301,6 @@ static void tracy_cleanup_stack(void *value)
|
||||
}
|
||||
}
|
||||
|
||||
// Get or initialize the thread-local Tracy stack
|
||||
static tracy_stack_t *get_tracy_stack(void)
|
||||
{
|
||||
tracy_stack_t *stack = SDL_GetTLS(&tracy_stack_id);
|
||||
@@ -748,7 +315,6 @@ static tracy_stack_t *get_tracy_stack(void)
|
||||
|
||||
void tracy_call_hook(JSContext *js, JSValue fn)
|
||||
{
|
||||
#ifdef TRACY_ENABLE
|
||||
if (!tracy_profiling_enabled)
|
||||
return;
|
||||
|
||||
@@ -760,21 +326,20 @@ void tracy_call_hook(JSContext *js, JSValue fn)
|
||||
arrput(stack->arr, ___tracy_emit_zone_begin_alloc(srcloc, 1));
|
||||
|
||||
free_js_debug_info(js, &debug);
|
||||
#endif
|
||||
}
|
||||
|
||||
void tracy_end_hook(JSContext *js, JSValue fn)
|
||||
{
|
||||
#ifdef TRACY_ENABLE
|
||||
if (!tracy_profiling_enabled)
|
||||
return;
|
||||
|
||||
tracy_stack_t *stack = get_tracy_stack();
|
||||
if (arrlen(stack->arr) > 0)
|
||||
___tracy_emit_zone_end(arrpop(stack->arr));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void actor_disrupt(cell_rt *crt)
|
||||
{
|
||||
crt->disrupt = 1;
|
||||
@@ -782,11 +347,6 @@ void actor_disrupt(cell_rt *crt)
|
||||
actor_free(crt);
|
||||
}
|
||||
|
||||
static int actor_interrupt_cb(JSRuntime *rt, cell_rt *crt)
|
||||
{
|
||||
return SDL_GetAtomicInt(&shutting_down) || crt->disrupt;
|
||||
}
|
||||
|
||||
JSValue js_os_use(JSContext *js);
|
||||
|
||||
void script_startup(cell_rt *prt)
|
||||
@@ -884,49 +444,6 @@ void script_startup(cell_rt *prt)
|
||||
set_actor_state(crt);
|
||||
}
|
||||
|
||||
int uncaught_exception(JSContext *js, JSValue v)
|
||||
{
|
||||
cell_rt *rt = JS_GetContextOpaque(js);
|
||||
SDL_LockMutex(rt->mutex);
|
||||
|
||||
if (!JS_HasException(js)) {
|
||||
JS_FreeValue(js,v);
|
||||
SDL_UnlockMutex(rt->mutex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
JSValue exp = JS_GetException(js);
|
||||
JSValue ret = JS_Call(js, rt->on_exception, JS_NULL, 1, &exp);
|
||||
JS_FreeValue(js,ret);
|
||||
JS_FreeValue(js, exp);
|
||||
JS_FreeValue(js,v);
|
||||
SDL_UnlockMutex(rt->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int actor_runner(void *data)
|
||||
{
|
||||
SDL_AddAtomicInt(&runners_count, 1);
|
||||
|
||||
while (!SDL_GetAtomicInt(&shutting_down)) {
|
||||
SDL_WaitSemaphore(ready_sem);
|
||||
SDL_LockSpinlock(&queue_lock);
|
||||
|
||||
cell_rt *actor = NULL;
|
||||
if (arrlen(ready_queue) > 0) {
|
||||
actor = ready_queue[0];
|
||||
arrdel(ready_queue, 0);
|
||||
}
|
||||
SDL_UnlockSpinlock(&queue_lock);
|
||||
|
||||
if (actor)
|
||||
actor_turn(actor);
|
||||
}
|
||||
|
||||
SDL_AddAtomicInt(&runners_count, -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void signal_handler(int sig)
|
||||
{
|
||||
const char *str = NULL;
|
||||
@@ -943,33 +460,6 @@ static void signal_handler(int sig)
|
||||
exit_handler();
|
||||
}
|
||||
|
||||
static void add_runners(int n)
|
||||
{
|
||||
/* Launch runner threads */
|
||||
for (int i = 0; i < n; i++) {
|
||||
char threadname[128];
|
||||
snprintf(threadname, sizeof(threadname), "actor runner %d", i);
|
||||
SDL_Thread *thread = SDL_CreateThread(actor_runner, threadname, NULL);
|
||||
SDL_DetachThread(thread);
|
||||
/* Thread is detached, no need to track */
|
||||
}
|
||||
}
|
||||
|
||||
static void loop()
|
||||
{
|
||||
while (!SDL_GetAtomicInt(&shutting_down)) {
|
||||
SDL_WaitSemaphore(main_sem);
|
||||
SDL_LockSpinlock(&main_queue_lock);
|
||||
cell_rt *actor = NULL;
|
||||
if (arrlen(main_queue) > 0) {
|
||||
actor = main_queue[0];
|
||||
arrdel(main_queue, 0);
|
||||
}
|
||||
SDL_UnlockSpinlock(&main_queue_lock);
|
||||
actor_turn(actor);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int profile_enabled = 0;
|
||||
@@ -1009,13 +499,7 @@ int main(int argc, char **argv)
|
||||
wota_write_text(&startwota, actor_argv[i]);
|
||||
|
||||
/* Initialize synchronization primitives */
|
||||
ready_sem = SDL_CreateSemaphore(0);
|
||||
main_sem = SDL_CreateSemaphore(0);
|
||||
actors_mutex = SDL_CreateMutex();
|
||||
SDL_SetAtomicInt(&shutting_down, 0);
|
||||
SDL_SetAtomicInt(&runners_count, 0);
|
||||
|
||||
add_runners(SDL_GetNumLogicalCPUCores());
|
||||
actor_initialize();
|
||||
|
||||
root_cell = create_actor(startwota.data);
|
||||
|
||||
@@ -1025,22 +509,11 @@ int main(int argc, char **argv)
|
||||
signal(SIGSEGV, signal_handler);
|
||||
signal(SIGABRT, signal_handler);
|
||||
|
||||
loop();
|
||||
actor_loop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int actor_exists(const char *id)
|
||||
{
|
||||
SDL_LockMutex(actors_mutex);
|
||||
int idx = shgeti(actors,id);
|
||||
SDL_UnlockMutex(actors_mutex);
|
||||
if (idx == -1)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int JS_ArrayLength(JSContext *js, JSValue a)
|
||||
{
|
||||
JSValue length = JS_GetPropertyStr(js, a, "length");
|
||||
|
||||
Reference in New Issue
Block a user