diff --git a/scripts/core/engine.js b/scripts/core/engine.js index 8f69554c..c6f93a0a 100644 --- a/scripts/core/engine.js +++ b/scripts/core/engine.js @@ -560,14 +560,7 @@ $_.clock[prosperon.DOC] = "takes a function input value that will eventually be var underlings = new Set() var overling = undefined - -var host = enet.create_host({ - address:"127.0.0.1", - port:0, - channels:0, - incoming_bandwidth:0, - outgoing_bandwidth:0 -}); +var root = undefined // set with the root of all actors globalThis.$_ = $_ @@ -577,11 +570,9 @@ var peers = {} // mapping of guids to peers var greeters = {} // mapping of underling guids to their system callback functions var peer2id = new WeakMap() // local bound peers to relevant id -$_.connection = function(callback, actor, config) { - var peer = peers[actor.id] - if (!peer) throw new Error(`Cannot get information from actor ${json.encode(actor)}`) - - callback({ +function peer_connection(peer) +{ + return { latency: peer.rtt, bandwidth: { incoming: peer.incoming_bandwidth, @@ -600,12 +591,27 @@ $_.connection = function(callback, actor, config) { latency_variance: peer.rtt_variance, packet_loss: peer.packet_loss, state: peer.state - }); + } +} + +$_.connection = function(callback, actor, config) { + var peer = peers[actor.id] + if (peer) { + callback(peer_connection(peer)) + return + } + + if (os.mailbox_exist(actor.id)) { + callback({type:"local"}) + return + } + + throw new Error(`Could not get connection information for ${actor}`) }; $_.connection[prosperon.DOC] = "takes a callback function, an actor object, and a configuration record for getting information about the status of a connection to the actor. The configuration record is used to request the sort of information that needs to be communicated." var portal = undefined -var pppfn +var portal_fn $_.portal = function(fn, port) { if (portal) @@ -620,11 +626,11 @@ $_.portal = function(fn, port) port, }) - pppfn = fn + portal_fn = fn } $_.portal[prosperon.DOC] = "starts apublic address that performs introduction services. It listens on a specified port for contacts by external actors that need to acquire an actor object. The function will receive the record containing the request. The record can have a reply sent through it. A portal can respond by beginning a new actor, or finding an existing actor, or by forwarding the contact message to another actor. This is how distributed Misty networks are bootstrapped." -function portal_fn(e) +function handle_portal(e) { switch (e.type) { case "connect": @@ -636,7 +642,7 @@ function portal_fn(e) break case "receive": - pppfn(e.data.data) + portal_fn(e.data.data) break } } @@ -669,9 +675,9 @@ $_.start = function(cb, prg, arg) var argv = [ "./prosperon", "spawn", - "--overling", host.port, "--id", id, - "--overlingid", prosperon.id + "--overling", prosperon.id, + "--root", root ] if (prg) @@ -682,7 +688,7 @@ $_.start = function(cb, prg, arg) underlings.add(id) - os.createprocess(argv) + os.createthread(argv); } $_.start[prosperon.DOC] = `The start function creates a new actor. The callback function receives messages about the new actor, starting with a message containing the new actor's address object. @@ -715,10 +721,17 @@ $_.unneeded = function(fn, seconds = ar) } $_.unneeded[prosperon.DOC] = `registers a function that is called when the actor has not received a message in the recent seconds. The default for seconds is the ar timer. This likely means that the actor is no longer needed. The actor should finish its work and then @.stop().` +var timers = [] +var timer_id = 0 + $_.delay = function(fn, seconds) { - var id = os.addtimer(fn, seconds); - return function() { os.removetimer(id); } + timers[timer_id++] = { + seconds, + fn + } + + return function() { delete timers[timer_id] } } $_.delay[prosperon.DOC] = `used to schedule the invocation of a function at a later time. Any value returned from the delayed invocation is ignored` @@ -749,12 +762,7 @@ function actor_send(actor, message) return } - try { - os.mailbox_push(actor.id, message) - } catch(e) { - } - - throw new Error (`Unable to send message to actor ${json.encode(actor)}`) + os.mailbox_push(actor.id, message) } // Map of reply IDs to functions @@ -802,15 +810,21 @@ if (!prosperon.args.id) prosperon.id = util.guid() else prosperon.id = prosperon.args.id; - -if (prosperon.args.overlingid) - overling = { id: prosperon.args.overlingid } + +if (prosperon.args.overling) + overling = { id: prosperon.args.overling } + +if (prosperon.args.root) + root = { id: prosperon.args.root } +else + root = { id: prosperon.id } // now can start the mailbox os.mailbox_start(prosperon.id); -if (prosperon.args.overling) - host.connect("localhost", prosperon.args.overling) +// send simple greet so overling knows it started +if (overling) + actor_send(overling, {type:'greet', id: prosperon.id}) if (prosperon.args.program) actor.spawn(prosperon.args.program) @@ -821,8 +835,7 @@ function destroyself() { if (overling) actor_send(overling, { type: "stopped" , id: prosperon.id}) - - host.flush() + os.exit(0) } @@ -853,6 +866,7 @@ function handle_actor_disconnect(id) function handle_message(msg) { + unneeded_timer() switch (msg.type) { case "user": if (msg.return) { @@ -883,13 +897,22 @@ function handle_message(msg) break case "contact": - if (pppfn) pppfn(msg.data) + if (portal_fn) portal_fn(msg.data) break case "stopped": handle_actor_disconnect(msg.id) break + + case "greet": + var greeter = greeters[msg.id] + if (greeter) greeter({ + type: "actor_started", + actor: { id: msg.id } + }) } + + unneeded_timer = $_.delay(unneeded_fn, unneeded_time) } function handle_connect(e) @@ -909,46 +932,24 @@ function handle_connect(e) e.peer.send({ id: prosperon.id }) } -var hang = 0.001 +var hang = 0.01 +var last_t = os.now() while (1) { - host.service(e => { - unneeded_timer() - switch(e.type) { - case "connect": - handle_connect(e); - break; - - case "receive": - if (e.data.id && !peers[e.data.id]) { - // we can hook them up - peers[e.data.id] = e.peer - peer2id.set(e.peer, e.data.id) - // first time they've been seen; if it has a system callback, run it now - var greeter = greeters[e.data.id] - if (greeter) - greeter({ - type: "actor_started", - actor: { id: e.data.id } - }) - } - handle_message(e.data) - break; - - case "disconnect": - var id = peer2id.get(e.peer) - if (!id) throw new Error('A peer disconnected but we had no ID associated with it.') - handle_actor_disconnect(id); - break; - } - unneeded_timer = $_.delay(unneeded_fn, unneeded_time) - }, hang); - if (portal) - portal.service(portal_fn, hang) + portal.service(handle_portal, hang) os.mailbox_service(prosperon.id, handle_message) + + var elapsed = os.now() - last_t + last_t = os.now() + for (var i in timers) { + var t = timers[i] + t.seconds -= elapsed + if (t.seconds <= 0) { + t.fn() + delete timers[i] + } + } } - - })() diff --git a/scripts/modules/js.js b/scripts/modules/js.js index 54ba4fcc..b4e70ebd 100644 --- a/scripts/modules/js.js +++ b/scripts/modules/js.js @@ -4,6 +4,8 @@ Provides functions for introspecting and configuring the QuickJS runtime engine. Includes debug info, memory usage, GC controls, code evaluation, etc. ` +js.rt_info[prosperon.DOC] = "Return internal QuickJS runtime info, such as object counts." + js.dump_shapes[prosperon.DOC] = ` :return: A debug string describing the internal shape hierarchy used by QuickJS. Use this for internal debugging of object shapes. diff --git a/scripts/modules/os.js b/scripts/modules/os.js index cd6e04ff..4473ba5f 100644 --- a/scripts/modules/os.js +++ b/scripts/modules/os.js @@ -25,10 +25,9 @@ os.battery_seconds[prosperon.DOC] = "Return the estimated remaining battery time os.power_state[prosperon.DOC] = "Return a string describing power status: 'on battery', 'charging', 'charged', etc." os.on[prosperon.DOC] = "Register a global callback for certain engine-wide or system-level events." -os.rt_info[prosperon.DOC] = "Return internal QuickJS runtime info, such as object counts." os.rusage[prosperon.DOC] = "Return resource usage stats for this process, if the platform supports it." os.mallinfo[prosperon.DOC] = "Return detailed memory allocation info (arena size, free blocks, etc.) on some platforms." os.env[prosperon.DOC] = "Fetch the value of a given environment variable, or undefined if it doesn't exist." os.system[prosperon.DOC] = "Execute a shell command using the system() call. Returns the command's exit code." -return os \ No newline at end of file +return os diff --git a/source/jsffi.c b/source/jsffi.c index f6671312..2cb5d5cc 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -28,7 +28,6 @@ #include "cgltf.h" #include "physfs.h" - #include "qjs_dmon.h" #include "qjs_nota.h" #include "qjs_wota.h" @@ -86,8 +85,6 @@ typedef struct tagMTRand { int32_t index; } MTRand; -static MTRand mrand; - #define UPPER_MASK 0x80000000 #define LOWER_MASK 0x7fffffff #define TEMPERING_MASK_B 0x9d2c5680 @@ -257,8 +254,6 @@ JSValue js_getproperty(JSContext *js, JSValue v, const char *prop) return ret; } -SDL_Window *global_window; - void free_gpu_buffer(JSRuntime *rt, void *opaque, void *ptr) { free(ptr); @@ -341,7 +336,24 @@ struct lrtb { float b; }; +typedef JSValue (*MODULEFN)(JSContext *js); + +typedef struct { + const char *name; + MODULEFN fn; +} ModuleEntry; + +typedef struct prosperon_rt { + MTRand mrand; + JSValue cycle_fn; + JSValue idx_buffer; + int idx_count; + ModuleEntry *module_registry; + JSValue *js_swapchains; +} prosperon_rt; + static SDL_GPUDevice *global_gpu; +static SDL_Window *global_window; SDL_GPUGraphicsPipelineTargetInfo js2SDL_GPUGraphicsPipelineTargetInfo(JSContext *js, JSValue v) { @@ -1517,14 +1529,12 @@ int point2segindex(HMM_Vec2 p, HMM_Vec2 *segs, double slop) { return best; } -static JSValue idx_buffer; -static int idx_count = 0; - JSValue make_quad_indices_buffer(JSContext *js, int quads) { + prosperon_rt *rt = JS_GetContextOpaque(js); int count = quads*6; - if (!JS_IsUndefined(idx_buffer) && idx_count >= count) - return JS_DupValue(js,idx_buffer); + if (!JS_IsUndefined(rt->idx_buffer) && rt->idx_count >= count) + return JS_DupValue(js,rt->idx_buffer); int verts = quads*4; uint16_t *indices = malloc(sizeof(*indices)*count); @@ -1537,12 +1547,12 @@ JSValue make_quad_indices_buffer(JSContext *js, int quads) indices[i+5] = v+1; } - if (!JS_IsUndefined(idx_buffer)) - JS_FreeValue(js,idx_buffer); + if (!JS_IsUndefined(rt->idx_buffer)) + JS_FreeValue(js,rt->idx_buffer); - idx_buffer = make_gpu_buffer(js,indices, sizeof(*indices)*count, JS_TYPED_ARRAY_UINT16, 1,0,1); - idx_count = count; - return JS_DupValue(js,idx_buffer); + rt->idx_buffer = make_gpu_buffer(js,indices, sizeof(*indices)*count, JS_TYPED_ARRAY_UINT16, 1,0,1); + rt->idx_count = count; + return JS_DupValue(js,rt->idx_buffer); } struct quad_buffers { @@ -2049,8 +2059,9 @@ JSC_CCALL(math_angledist, JSC_CCALL(math_length, return number2js(js,arr_vec_length(js,argv[0])); ) -double rand_range(double min, double max) +double rand_range(JSContext *js, double min, double max) { + MTRand mrand = ((prosperon_rt*)JS_GetContextOpaque(js))->mrand; return genRand(&mrand) * (max-min)+min; } @@ -2058,7 +2069,7 @@ JSC_CCALL(math_jitter, double n = js2number(js,argv[0]); double pct = js2number(js,argv[1]); - return number2js(js,n + (rand_range(-pct,pct)*n)); + return number2js(js,n + (rand_range(js,-pct,pct)*n)); ) JSC_CCALL(math_mean, @@ -2144,9 +2155,18 @@ JSC_CCALL(math_from_to, JS_SetPropertyUint32(js, ret, steps+1, vec22js(js,to)); ) -JSC_CCALL(math_rand, return JS_NewFloat64(js, genRand(&mrand))) -JSC_CCALL(math_randi, return JS_NewUint32(js, genRandLong(&mrand))) +JSC_CCALL(math_rand, + MTRand mrand = ((prosperon_rt*)JS_GetContextOpaque(js))->mrand; + return JS_NewFloat64(js, genRand(&mrand)) +) + +JSC_CCALL(math_randi, + MTRand mrand = ((prosperon_rt*)JS_GetContextOpaque(js))->mrand; + return JS_NewUint32(js, genRandLong(&mrand)) +) + JSC_CCALL(math_srand, + MTRand mrand = ((prosperon_rt*)JS_GetContextOpaque(js))->mrand; if (argc < 1) m_seedRand(&mrand, time(NULL)); else @@ -3060,11 +3080,8 @@ JSC_CCALL(SDL_Renderer_clear, ) JSC_CCALL(SDL_Renderer_present, -// SDL_Thread *thread; SDL_Renderer *ren = js2SDL_Renderer(js,self); -// thread = SDL_CreateThread(present_thread, "present", ren); SDL_RenderPresent(ren); -// return SDL_Thread2js(js,thread); ) JSC_CCALL(SDL_Renderer_draw_color, @@ -3529,8 +3546,6 @@ JSC_CCALL(gpu_set_swapchain, return JS_ThrowReferenceError(js, "Could not set: %s\n", SDL_GetError()); ) -static JSValue *js_swapchains; - JSC_CCALL(cmd_acquire_swapchain, SDL_GPUCommandBuffer *cmds = js2SDL_GPUCommandBuffer(js, self); Uint32 w,h; @@ -3538,6 +3553,8 @@ JSC_CCALL(cmd_acquire_swapchain, SDL_AcquireGPUSwapchainTexture(cmds,global_window, &texture, &w, &h); if (!texture) return JS_UNDEFINED; JSValue swap = JS_UNDEFINED; + + JSValue *js_swapchains = ((prosperon_rt*)JS_GetContextOpaque(js))->js_swapchains; for (int i = 0; i < arrlen(js_swapchains); i++) { if (js2SDL_GPUTexture(js,js_swapchains[i]) == texture) { @@ -6324,8 +6341,8 @@ JSC_CCALL(geometry_rect_inside, JSC_CCALL(geometry_rect_random, rect a = js2rect(js,argv[0]); return vec22js(js,(HMM_Vec2){ - a.x + rand_range(-0.5,0.5)*a.w, - a.y + rand_range(-0.5,0.5)*a.h + a.x + rand_range(js,-0.5,0.5)*a.w, + a.y + rand_range(js,-0.5,0.5)*a.h }); ) @@ -7126,7 +7143,8 @@ JSC_CCALL(os_createthread, JS_FreeValue(js, val); } SDL_Thread *thread = SDL_CreateThread(create_new_runtime, "newrt", &cmd); - if (!thread) return JS_ThrowInternalError(js, "Could not create a new thread: %s", SDL_GetError()) + if (!thread) return JS_ThrowInternalError(js, "Could not create a new thread: %s", SDL_GetError()); + SDL_DetachThread(thread); ) typedef struct mailbox { @@ -7141,18 +7159,21 @@ JSC_CCALL(os_mailbox_push, if (argc < 2) return JS_ThrowInternalError(js, "Need an actor and an array buffer."); char *id = JS_ToCString(js,argv[0]); void *nota = value2nota(js, argv[1]); + printf("Sending to %s\n", id); int mailbox_index = shgeti(mailboxes, id); if (mailbox_index == -1) { + printf("COULD NOT FIND MAILBLOX FOR %s\n", id); JS_FreeCString(js,id); return JS_ThrowInternalError(js, "No mailbox found for given ID."); } - mailbox mb = mailboxes[mailbox_index].value; + mailbox *mb = &mailboxes[mailbox_index].value; - SDL_LockMutex(mb.mutex); - arrput(mb.messages, nota); - SDL_UnlockMutex(mb.mutex); + SDL_LockMutex(mb->mutex); + arrput(mb->messages, nota); + printf("Added a letter, now the mailbox %s has %d\n", id, arrlen(mb->messages)); + SDL_UnlockMutex(mb->mutex); JS_FreeCString(js,id); ) @@ -7163,23 +7184,25 @@ JSC_CCALL(os_mailbox_service, // grab all from our mailbox and int mb_index = shgeti(mailboxes, id); if (mb_index == -1) { + printf("could not find mailbox for %s\n", id); JS_FreeCString(js,id); JS_FreeValue(js,fn); return JS_ThrowInternalError(js, "No mailbox found for given ID."); } - mailbox mb = mailboxes[mb_index].value; + mailbox *mb = &mailboxes[mb_index].value; void **temp = NULL; - SDL_LockMutex(mb.mutex); - int count = arrlen(mb.messages); + SDL_LockMutex(mb->mutex); + int count = arrlen(mb->messages); if (count > 0) { + printf("servicing %d letters for %s\n", count, id); arrsetlen(temp,count); - memcpy(temp, mb.messages, sizeof(void*) * count); - arrsetlen(mb.messages,0); + memcpy(temp, mb->messages, sizeof(void*) * count); + arrsetlen(mb->messages,0); } - SDL_UnlockMutex(mb.mutex); + SDL_UnlockMutex(mb->mutex); for (int i = 0; i < count; i++) { void *nota = temp[i]; @@ -7195,10 +7218,15 @@ JSC_CCALL(os_mailbox_service, // grab all from our mailbox and JS_FreeValue(js,fn); ) +JSC_CCALL(os_mailbox_exist, + char *id = JS_ToCString(js, argv[0]); + + return JS_NewBool(js, shgeti(mailboxes,id) != -1); +) + JSC_CCALL(os_mailbox_start, char *id = JS_ToCString(js,argv[0]); - void **letters = NULL; mailbox mb; mb.mutex = SDL_CreateMutex(); mb.messages = NULL; @@ -7211,65 +7239,6 @@ JSC_CCALL(os_mailbox_start, JS_FreeCString(js,id); ) -static SDL_TLSID timer_hash_tls = {0}; -typedef struct { SDL_TimerID key; JSValue *value; } TimerEntry; - -TimerEntry *get_timer_hash(void) { - return (TimerEntry *)SDL_GetTLS(&timer_hash_tls); -} - -Uint64 os_timer_cb(JSValue *fn, SDL_TimerID id, Uint64 delay) { - SDL_UserEvent event; - SDL_zero(event); - event.type = timer_cb_event; - event.data1 = fn; - SDL_PushEvent(&event); - - TimerEntry *timer_hash = get_timer_hash(); - hmdel(timer_hash, id); // Remove from hash table after pushing event - - return 0; // Returning 0 ensures the timer doesn’t repeat -} - -JSC_CCALL(os_addtimer, - JSValue *fn = malloc(sizeof(*fn)); - *fn = JS_DupValue(js, argv[0]); - double secs; - JS_ToFloat64(js, &secs, argv[1]); - - SDL_TimerID id = SDL_AddTimerNS(secs * 1000000000.0f, os_timer_cb, fn); - if (!id) { - JS_FreeValue(js, *fn); - free(fn); - return JS_ThrowInternalError(js, "Failed to add timer: %s", SDL_GetError()); - } - - TimerEntry *timer_hash = get_timer_hash(); - hmput(timer_hash, id, fn); - - return JS_NewUint32(js, id); -) - -JSC_CCALL(os_removetimer, - SDL_TimerID id; - JS_ToUint32(js, &id, argv[0]); - int rm = SDL_RemoveTimer(id); - if (!rm) { - return JS_ThrowReferenceError(js, "Could not remove timer id %u: %s\n", id, SDL_GetError()); - } - - TimerEntry *timer_hash = get_timer_hash(); - int index = hmgeti(timer_hash, id); - if (index != -1) { - JSValue *fn = timer_hash[index].value; - JS_FreeValue(js, *fn); - free(fn); - hmdel(timer_hash, id); - } - - return JS_UNDEFINED; -) - JSC_CCALL(os_waitevent, SDL_Event event; double secs; @@ -7320,7 +7289,6 @@ static const JSCFunctionListEntry js_os_funcs[] = { MIST_FUNC_DEF(os, on, 2), - MIST_FUNC_DEF(os, rt_info, 0), MIST_FUNC_DEF(os, rusage, 0), MIST_FUNC_DEF(os, mallinfo, 0), @@ -7328,25 +7296,23 @@ static const JSCFunctionListEntry js_os_funcs[] = { MIST_FUNC_DEF(os, env, 1), MIST_FUNC_DEF(os, system, 1), MIST_FUNC_DEF(os, createprocess, 0), - MIST_FUNC_DEF(os, addtimer, 2), - MIST_FUNC_DEF(os, removetimer, 1), MIST_FUNC_DEF(os, waitevent, 2), MIST_FUNC_DEF(os, mailbox_push, 2), MIST_FUNC_DEF(os, mailbox_service, 2), MIST_FUNC_DEF(os, mailbox_start, 1), - MIST_FUNC_DEF(os, createthread, 0), + MIST_FUNC_DEF(os, mailbox_exist, 1), + MIST_FUNC_DEF(os, createthread, 1), }; JSC_CCALL(js_dump_class, return js_get_object_class_distribution(js)) JSC_CCALL(js_dump_type_overheads, return js_get_object_type_overheads(js)) JSC_CCALL(js_dump_objects, return js_dump_objects(js)) -static JSValue cycle_fn; - void cycle_hook_call(JSContext *js, JSValue v) { - JS_FreeValue(js,JS_Call(js,cycle_fn,JS_UNDEFINED,1,&v)); + prosperon_rt *rt = JS_GetContextOpaque(js); + JS_FreeValue(js,JS_Call(js, rt->cycle_fn,JS_UNDEFINED,1,&v)); } JSC_CCALL(js_cycle_hook, @@ -7354,8 +7320,9 @@ JSC_CCALL(js_cycle_hook, js_debug_sethook(js,NULL,JS_HOOK_CYCLE); else { printf("SETTING DEBUG HOOK\n"); - JS_FreeValue(js,cycle_fn); - cycle_fn = JS_DupValue(js,argv[0]); + prosperon_rt *rt = JS_GetContextOpaque(js); + JS_FreeValue(js,rt->cycle_fn); + rt->cycle_fn = JS_DupValue(js,argv[0]); js_debug_sethook(js,cycle_hook_call, JS_HOOK_CYCLE); } ) @@ -7377,7 +7344,8 @@ static const JSCFunctionListEntry js_js_funcs[] = { MIST_FUNC_DEF(os, max_stacksize, 1), MIST_FUNC_DEF(os, memstate, 0), MIST_FUNC_DEF(os, gc, 0), - MIST_FUNC_DEF(os, eval, 2), + MIST_FUNC_DEF(os, eval, 2), + MIST_FUNC_DEF(os, rt_info, 0), }; static const JSCFunctionListEntry js_util_funcs[] = { @@ -7444,16 +7412,9 @@ static const JSCFunctionListEntry js_event_funcs[] = { MIST_FUNC_DEF(os, engine_input, 1), }; -typedef JSValue (*MODULEFN)(JSContext *js); - -typedef struct { - const char *name; - MODULEFN fn; -} ModuleEntry; - -static ModuleEntry *module_registry = NULL; - JSC_SCALL(os_use_embed, + prosperon_rt *rt = JS_GetContextOpaque(js); + ModuleEntry *module_registry = rt->module_registry; for (int i = 0; i < arrlen(module_registry); i++) { if (strcmp(str,module_registry[i].name) == 0) { ret = module_registry[i].fn(js); @@ -7715,13 +7676,13 @@ static void signal_handler(int sig) { } if (!str) return; - script_evalf("prosperon.dispatch('%s')", str); +// script_evalf("prosperon.dispatch('%s')", str); } static void exit_handler() { - script_evalf("prosperon.dispatch('exit')"); - script_stop(); +// script_evalf("prosperon.dispatch('exit')"); +// script_stop(); } #include "monocypher.h" @@ -7958,39 +7919,37 @@ JSValue js_imgui_use(JSContext *js); #define MISTLINE(NAME) (ModuleEntry){#NAME, js_##NAME##_use} -void ffi_setup() -{ - -} - void ffi_load(JSContext *js, int argc, char **argv) { - arrput(module_registry, MISTLINE(io)); - arrput(module_registry, MISTLINE(os)); - arrput(module_registry, MISTLINE(input)); - arrput(module_registry, MISTLINE(time)); - arrput(module_registry, MISTLINE(math)); - arrput(module_registry, MISTLINE(spline)); - arrput(module_registry, MISTLINE(geometry)); - arrput(module_registry, MISTLINE(graphics)); - arrput(module_registry, MISTLINE(js)); - arrput(module_registry, MISTLINE(util)); - arrput(module_registry, MISTLINE(video)); - arrput(module_registry, MISTLINE(event)); - arrput(module_registry, MISTLINE(soloud)); - arrput(module_registry, MISTLINE(layout)); - arrput(module_registry, MISTLINE(miniz)); - arrput(module_registry, MISTLINE(imgui)); - arrput(module_registry, MISTLINE(camera)); - arrput(module_registry, MISTLINE(debug)); - arrput(module_registry, MISTLINE(dmon)); - arrput(module_registry, MISTLINE(nota)); - arrput(module_registry, MISTLINE(enet)); - arrput(module_registry, MISTLINE(qr)); - arrput(module_registry, MISTLINE(wota)); - arrput(module_registry, MISTLINE(crypto)); + prosperon_rt *rt = calloc(1,sizeof(*rt)); + JS_SetContextOpaque(js, rt); + m_seedRand(&rt->mrand, time(NULL)); + arrput(rt->module_registry, MISTLINE(io)); + arrput(rt->module_registry, MISTLINE(os)); + arrput(rt->module_registry, MISTLINE(input)); + arrput(rt->module_registry, MISTLINE(time)); + arrput(rt->module_registry, MISTLINE(math)); + arrput(rt->module_registry, MISTLINE(spline)); + arrput(rt->module_registry, MISTLINE(geometry)); + arrput(rt->module_registry, MISTLINE(graphics)); + arrput(rt->module_registry, MISTLINE(js)); + arrput(rt->module_registry, MISTLINE(util)); + arrput(rt->module_registry, MISTLINE(video)); + arrput(rt->module_registry, MISTLINE(event)); + arrput(rt->module_registry, MISTLINE(soloud)); + arrput(rt->module_registry, MISTLINE(layout)); + arrput(rt->module_registry, MISTLINE(miniz)); + arrput(rt->module_registry, MISTLINE(imgui)); + arrput(rt->module_registry, MISTLINE(camera)); + arrput(rt->module_registry, MISTLINE(debug)); + arrput(rt->module_registry, MISTLINE(dmon)); + arrput(rt->module_registry, MISTLINE(nota)); + arrput(rt->module_registry, MISTLINE(enet)); + arrput(rt->module_registry, MISTLINE(qr)); + arrput(rt->module_registry, MISTLINE(wota)); + arrput(rt->module_registry, MISTLINE(crypto)); #ifdef TRACY_ENABLE - arrput(module_registry, MISTLINE(tracy)); + arrput(rt->module_registry, MISTLINE(tracy)); #endif JSValue globalThis = JS_GetGlobalObject(js); @@ -8059,8 +8018,6 @@ void ffi_load(JSContext *js, int argc, char **argv) { signal(SIGABRT, signal_handler); atexit(exit_handler); - m_seedRand(&mrand, time(NULL)); - JSValue args = JS_NewArray(js); for (int i = 0; i < argc; i++) JS_SetPropertyUint32(js,args, i, JS_NewString(js,argv[i])); @@ -8072,13 +8029,7 @@ void ffi_load(JSContext *js, int argc, char **argv) { JS_SetPropertyStr(js,globalThis,"prosperon", prosp); - idx_buffer = JS_UNDEFINED; - cycle_fn = JS_UNDEFINED; - JS_FreeValue(js,globalThis); - TimerEntry *timer_hash = NULL; // Initially empty hash table - SDL_SetTLS(&timer_hash_tls, timer_hash, NULL); // arrfree from stb_ds.h frees the array - SDL_Init(SDL_INIT_EVENTS); } diff --git a/source/script.c b/source/script.c index e1070361..3a102e11 100644 --- a/source/script.c +++ b/source/script.c @@ -58,8 +58,6 @@ static size_t js_tracy_malloc_usable_size(const void *ptr) #endif } -void tls_free(void *data) { free(data); } - static void *js_tracy_malloc(JSMallocState *s, size_t size) { void *ptr; @@ -145,7 +143,7 @@ void script_startup(int argc, char **argv) { rt = JS_NewRuntime(); #endif JSContext *js = JS_NewContextRaw(rt); - SDL_SetTLS(&js_id, js, NULL); + SDL_SetTLS(&js_id, js, script_stop); JS_AddIntrinsicBaseObjects(js); JS_AddIntrinsicEval(js); JS_AddIntrinsicRegExp(js); @@ -160,7 +158,7 @@ void script_startup(int argc, char **argv) { JSValue *onexp = malloc(sizeof(JSValue)); *onexp = JS_UNDEFINED; - SDL_SetTLS(&on_exception, onexp, tls_free); + SDL_SetTLS(&on_exception, onexp, NULL); ffi_load(js, argc, argv); @@ -180,16 +178,18 @@ void script_startup(int argc, char **argv) { free(eng); } -void script_stop(JSContext *js, JSRuntime *rt) +void script_stop(JSContext *js) { return; JSValue *onexp = SDL_GetTLS(&on_exception); JS_FreeValue(js,*onexp); + JSRuntime *rt = JS_GetRuntime(js); JS_FreeContext(js); JS_FreeRuntime(rt); - - rt = NULL; - js = NULL; + + free(rt); + free(js); + free(onexp); } void uncaught_exception(JSContext *js, JSValue v) @@ -221,9 +221,8 @@ void uncaught_exception(JSContext *js, JSValue v) JS_FreeValue(js,v); } -void script_evalf(const char *format, ...) +void script_evalf(JSContext *js, const char *format, ...) { - JSContext *js = SDL_GetTLS(&js_id); JSValue obj; va_list args; va_start(args, format); diff --git a/source/script.h b/source/script.h index cac37e9f..db4ffe21 100644 --- a/source/script.h +++ b/source/script.h @@ -6,10 +6,10 @@ extern SDL_TLSID on_exception; -void script_startup(); -void script_stop(); +void script_startup(int argc, char **argv); +void script_stop(JSContext*); -void script_evalf(const char *format, ...); +void script_evalf(JSContext *js, const char *format, ...); JSValue script_eval(JSContext *js, const char *file, const char *script); void uncaught_exception(JSContext *js, JSValue v); diff --git a/tests/overling.js b/tests/overling.js index d4cc52c6..52bba760 100644 --- a/tests/overling.js +++ b/tests/overling.js @@ -3,17 +3,13 @@ var os = use('os') $_.start(e => { switch(e.type) { case "actor_started": - console.log(`parent got system level actor_started msg`) console.log(json.encode(e)) $_.connection(e => console.log(json.encode(e)), e.actor) // get connection info $_.send(e.actor, {message: "Hello!"}) - $_.delay(_ => { - console.log(`sending stop message to ${json.encode(e.actor)}`) - $_.stop(e.actor) - }, 1); - $_.couple(e.actor) + + $_.stop(e.actor) } }, "tests/underling.js");