multirheading mailboxes fixed
Some checks failed
Build and Deploy / build-linux (push) Successful in 1m20s
Build and Deploy / build-windows (CLANG64) (push) Failing after 10m58s
Build and Deploy / package-dist (push) Has been cancelled
Build and Deploy / deploy-itch (push) Has been cancelled
Build and Deploy / deploy-gitea (push) Has been cancelled

This commit is contained in:
2025-03-11 20:34:39 -05:00
parent c431f117e9
commit e86138ec00
7 changed files with 199 additions and 251 deletions

View File

@@ -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]
}
}
}
})()

View File

@@ -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.

View File

@@ -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
return os

View File

@@ -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 doesnt 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);
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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");