threading
Some checks failed
Build and Deploy / package-dist (push) Blocked by required conditions
Build and Deploy / deploy-itch (push) Blocked by required conditions
Build and Deploy / deploy-gitea (push) Blocked by required conditions
Build and Deploy / build-linux (push) Failing after 55s
Build and Deploy / build-windows (CLANG64) (push) Failing after 10m50s
Some checks failed
Build and Deploy / package-dist (push) Blocked by required conditions
Build and Deploy / deploy-itch (push) Blocked by required conditions
Build and Deploy / deploy-gitea (push) Blocked by required conditions
Build and Deploy / build-linux (push) Failing after 55s
Build and Deploy / build-windows (CLANG64) (push) Failing after 10m50s
This commit is contained in:
@@ -633,12 +633,12 @@ function portal_fn(e)
|
||||
break
|
||||
|
||||
case "receive":
|
||||
pppfn(e.data)
|
||||
pppfn(e.data.data)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var peer2contact = new WeakMap()
|
||||
var peer2contact = new WeakMap() //
|
||||
$_.contact = function(callback, record)
|
||||
{
|
||||
if (!callback) throw new Error('Contact requires a callback function')
|
||||
@@ -649,15 +649,15 @@ $_.contact = function(callback, record)
|
||||
record
|
||||
})
|
||||
}
|
||||
$_.contact[prosperon.DOC] = "The contact function sends a message to a portal on another machine to obtain an actor object.
|
||||
$_.contact[prosperon.DOC] = `The contact function sends a message to a portal on another machine to obtain an actor object.
|
||||
|
||||
The callback is a function with a actor input and a reason input. If successful, actor is bound to an actor object. If not successful, actor is null and reason may contain an explanation."
|
||||
The callback is a function with a actor input and a reason input. If successful, actor is bound to an actor object. If not successful, actor is null and reason may contain an explanation.`
|
||||
|
||||
$_.receiver = function(fn)
|
||||
{
|
||||
receive_fn = fn;
|
||||
}
|
||||
$_.receiver[prosperon.DOC] = "registers a function that will receive all messages sent to the actor except for delay events, reply messages (which are sent to the send callback), the unneeded message, and portal contact messages."
|
||||
$_.receiver[prosperon.DOC] = `registers a function that will receive all messages sent to the actor except for delay events, reply messages (which are sent to the send callback), the unneeded message, and portal contact messages.`
|
||||
|
||||
$_.start = function(cb, prg, arg)
|
||||
{
|
||||
@@ -678,13 +678,13 @@ $_.start = function(cb, prg, arg)
|
||||
|
||||
os.createprocess(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.
|
||||
$_.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.
|
||||
|
||||
The program text identifies the executable in the program shop that the new actor runs.
|
||||
|
||||
The arguments array contains up to four arguments of type logical, number, text, or actor address object.
|
||||
|
||||
The current actor is the overling of the new actor, and it is notified when the new actor stops. The new actor is an underling of the current actor."
|
||||
The current actor is the overling of the new actor, and it is notified when the new actor stops. The new actor is an underling of the current actor.`
|
||||
|
||||
$_.stop = function(actor)
|
||||
{
|
||||
@@ -693,7 +693,7 @@ $_.stop = function(actor)
|
||||
|
||||
actor_send(actor, {type:"stop"})
|
||||
}
|
||||
$_.stop[prosperon.DOC] = "The stop function stops an underling."
|
||||
$_.stop[prosperon.DOC] = `The stop function stops an underling.`
|
||||
|
||||
var unneeded_fn = $_.stop
|
||||
var unneeded_time = ar
|
||||
@@ -704,14 +704,14 @@ $_.unneeded = function(fn, seconds = ar)
|
||||
unneeded_fn = fn
|
||||
unneeded_time = seconds
|
||||
}
|
||||
$_.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()."
|
||||
$_.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().`
|
||||
|
||||
$_.delay = function(fn, seconds)
|
||||
{
|
||||
var id = os.addtimer(fn, seconds);
|
||||
return function() { os.removetimer(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"
|
||||
$_.delay[prosperon.DOC] = `used to schedule the invocation of a function at a later time. Any value returned from the delayed invocation is ignored`
|
||||
|
||||
// Set of actor guids
|
||||
var couplings = new Set()
|
||||
@@ -720,7 +720,7 @@ $_.couple = function(actor)
|
||||
{
|
||||
couplings.add(actor.id)
|
||||
}
|
||||
$_.couple[prosperon.DOC] = "causes this actor to stop when another actor stops."
|
||||
$_.couple[prosperon.DOC] = `causes this actor to stop when another actor stops.`
|
||||
|
||||
// Shuffles the message to the actor with whatever means available
|
||||
function actor_send(actor, message)
|
||||
@@ -775,9 +775,9 @@ $_.send = function(actor, message, reply)
|
||||
|
||||
actor_send(actor, send)
|
||||
}
|
||||
$_.send[prosperon.DOC] = "sends a message to another actor. The left expression must resolve to an actor address object or a message object that is expecting a reply because it was sent with a callback. The right expression is a record containing the outgoing message. The outgoing message record must not contain functions or patterns or cyclic structures.
|
||||
$_.send[prosperon.DOC] = `sends a message to another actor. The left expression must resolve to an actor address object or a message object that is expecting a reply because it was sent with a callback. The right expression is a record containing the outgoing message. The outgoing message record must not contain functions or patterns or cyclic structures.
|
||||
|
||||
If a callback function is included, then the callback function will receive the reply, not the receiver function."
|
||||
If a callback function is included, then the callback function will receive the reply, not the receiver function.`
|
||||
|
||||
var cmd = use('cmd')
|
||||
cmd.process(prosperon.argv)
|
||||
@@ -787,6 +787,9 @@ if (!prosperon.args.id)
|
||||
else
|
||||
prosperon.id = prosperon.args.id;
|
||||
|
||||
// now can start the mailbox
|
||||
os.mailbox_start(prosperon.id);
|
||||
|
||||
if (prosperon.args.overling)
|
||||
host.connect("localhost", prosperon.args.overling)
|
||||
|
||||
@@ -855,9 +858,8 @@ function handle_message(e)
|
||||
break
|
||||
|
||||
case "contact":
|
||||
if (pppfn) pppfn(e.data)
|
||||
if (pppfn) pppfn(e.data.data)
|
||||
break
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
111
source/jsffi.c
111
source/jsffi.c
@@ -7025,11 +7025,12 @@ JSC_CCALL(os_rects_to_sprites,
|
||||
)
|
||||
|
||||
JSC_CCALL(os_on,
|
||||
on_exception = JS_DupValue(js,argv[1]);
|
||||
JSValue *onexp = SDL_GetTLS(&on_exception);
|
||||
*onexp = JS_DupValue(js,argv[1]);
|
||||
)
|
||||
|
||||
JSC_CCALL(os_clean_transforms,
|
||||
clean_all();
|
||||
clean_all(js);
|
||||
)
|
||||
|
||||
JSC_CCALL(os_totalmem, return number2js(js, SDL_GetSystemRAM()))
|
||||
@@ -7154,6 +7155,91 @@ JSC_CCALL(os_createprocess,
|
||||
return JS_ThrowReferenceError(js, "Unable to create process: %s\n", SDL_GetError());
|
||||
)
|
||||
|
||||
int create_new_runtime(void *data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
JSC_CCALL(os_createthread,
|
||||
SDL_Thread *thread = SDL_CreateThread(create_new_runtime, "newrt", NULL);
|
||||
)
|
||||
|
||||
typedef struct mailbox {
|
||||
SDL_mutex *mutex;
|
||||
void **messages;
|
||||
} mailbox;
|
||||
|
||||
static struct { char *key; mailbox value; } *mailboxes = NULL;
|
||||
|
||||
JSC_CCALL(os_mailbox_push,
|
||||
if (argc < 2) return JS_ThrowInternalError(js, "Need an actor and an array buffer.");
|
||||
char *id = JS_GetCString(js,argv[0]);
|
||||
void *nota = value2nota(js, argv[1]);
|
||||
|
||||
int mailbox_index = shgeti(mailboxes, id);
|
||||
if (mailbox_index == -1) {
|
||||
JS_FreeCString(js,id);
|
||||
return JS_ThrowInternalError(js, "No mailbox found for given ID.");
|
||||
}
|
||||
|
||||
mailbox mb = mailboxes[mailbox_index].value;
|
||||
|
||||
SDL_LockMutex(mb.mutex);
|
||||
arrput(mb.messages, nota);
|
||||
SDL_UnlockMutex(mb.mutex);
|
||||
|
||||
JS_FreeCString(js,id);
|
||||
)
|
||||
|
||||
JSC_CCALL(os_mailbox_service, // grab all from our mailbox and
|
||||
char *id = JS_GetCString(js,argv[0]);
|
||||
JSValue fn = JS_DupValue(js,argv[1]);
|
||||
|
||||
int mb_index = shgeti(mailboxes, id);
|
||||
if (mb_index == -1) {
|
||||
JS_FreeCString(js,id);
|
||||
JS_FreeValue(js,fn);
|
||||
return JS_ThrowInternalError(js, "No mailbox found for given ID.");
|
||||
}
|
||||
|
||||
mailbox mb = mailboxes[mb_index].value;
|
||||
|
||||
void **temp = NULL;
|
||||
SDL_LockMutex(mb.mutex);
|
||||
int count = arrlen(mb.messages);
|
||||
if (count > 0) {
|
||||
arrsetlen(temp,count);
|
||||
memcpy(temp, mb.messages, sizeof(void*) * count);
|
||||
arrsetlen(mb.messages,0);
|
||||
}
|
||||
|
||||
SDL_UnlockMutex(mb.mutex);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
void *nota = temp[i];
|
||||
JSValue obj = nota2value(js, nota);
|
||||
free(nota);
|
||||
JSValue call = JS_Call(js, fn, JS_UNDEFINED, 1, &obj); // todo: need to free obj here?
|
||||
uncaught_exception(js, call);
|
||||
JS_FreeValue(js,obj);
|
||||
}
|
||||
arrfree(temp);
|
||||
|
||||
JS_FreeCString(js,id);
|
||||
JS_FreeCString(js,fn);
|
||||
)
|
||||
|
||||
JSC_CCALL(os_mailbox_start,
|
||||
char *id = JS_GetCString(js,argv[0]);
|
||||
|
||||
void **letters = NULL;
|
||||
mailbox mb;
|
||||
mb.mutex = SDL_CreateMutex();
|
||||
mb.messages = NULL;
|
||||
shput(mailboxes, id, mb);
|
||||
JS_FreeCString(js,id);
|
||||
)
|
||||
|
||||
struct { SDL_TimerID key; JSValue *value; } *timer_hash = NULL;
|
||||
|
||||
Uint64 os_timer_cb(JSValue *fn, SDL_TimerID id, Uint64 delay)
|
||||
@@ -7460,13 +7546,6 @@ bool rtree_iter(const NUMTYPE *min, const NUMTYPE *max, const JSValue *data, str
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool rtree_array_iter(const NUMTYPE *min, const NUMTYPE *max, const JSValue *data, sprite **arr)
|
||||
{
|
||||
sprite *sp = js2sprite(global_js, *data);
|
||||
arrput(*arr, *sp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
JSC_CCALL(rtree_query,
|
||||
rtree *tree = js2rtree(js,self);
|
||||
rect r = js2rect(js,argv[0]);
|
||||
@@ -7485,13 +7564,6 @@ JSC_CCALL(rtree_query,
|
||||
data.n = 0;
|
||||
rtree_search(tree, min, max, rtree_iter, &data);
|
||||
ret = data.arr;
|
||||
|
||||
/*
|
||||
sprite *arr = NULL;
|
||||
rtree_search(tree, min, max, rtree_array_iter, &arr);
|
||||
ret = JS_NewArrayBufferCopy(js,arr,arrlen(arr)*sizeof(*arr));
|
||||
arrfree(arr);
|
||||
*/
|
||||
)
|
||||
|
||||
struct rtree_each
|
||||
@@ -7897,6 +7969,11 @@ 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));
|
||||
@@ -8079,8 +8156,6 @@ void ffi_load(JSContext *js, int argc, char **argv) {
|
||||
|
||||
fill_event_atoms(js);
|
||||
|
||||
global_js = js;
|
||||
|
||||
signal(SIGINT, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
signal(SIGSEGV, signal_handler);
|
||||
|
||||
@@ -231,6 +231,40 @@ static void nota_encode_value(NotaEncodeContext *enc, JSValueConst val)
|
||||
}
|
||||
}
|
||||
|
||||
void *value2nota(JSContext *ctx, JSValue v)
|
||||
{
|
||||
NotaEncodeContext enc_s, *enc = &enc_s;
|
||||
enc->ctx = ctx;
|
||||
enc->visitedStack = JS_NewArray(ctx); // empty array initially
|
||||
enc->cycle = 0;
|
||||
|
||||
nota_buffer_init(&enc->nb, 128);
|
||||
|
||||
nota_encode_value(enc, argv[0]);
|
||||
|
||||
if (enc->cycle) {
|
||||
JS_FreeValue(ctx, enc->visitedStack);
|
||||
nota_buffer_free(&enc->nb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JS_FreeValue(ctx, enc->visitedStack);
|
||||
|
||||
void* dataPtr = enc->nb.data; // pointer to the raw data
|
||||
enc->nb.data = NULL;
|
||||
nota_buffer_free(&enc->nb);
|
||||
|
||||
return dataPtr;
|
||||
}
|
||||
|
||||
JSValue nota2value(JSContext *js, char *nota)
|
||||
{
|
||||
if (!nota) return JS_UNDEFINED;
|
||||
JSValue ret;
|
||||
js_do_nota_decode(js, &ret, nota);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static JSValue js_nota_encode(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||
{
|
||||
if (argc < 1)
|
||||
|
||||
@@ -5,4 +5,7 @@
|
||||
|
||||
JSValue js_nota_use(JSContext*);
|
||||
|
||||
#endif
|
||||
void *value2nota(JSContext*, JSValue);
|
||||
JSValue nota2value(JSContext*, void*);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,12 +22,8 @@
|
||||
|
||||
#include "physfs.h"
|
||||
|
||||
static JSContext *js = NULL;
|
||||
static JSRuntime *rt = NULL;
|
||||
|
||||
JSContext *global_js = NULL;
|
||||
|
||||
JSValue on_exception;
|
||||
SDL_TLSID on_exception = {0};
|
||||
SDL_TLSID js_id = {0};
|
||||
|
||||
#define ENGINE "scripts/core/engine.js"
|
||||
|
||||
@@ -62,6 +58,8 @@ 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;
|
||||
@@ -139,14 +137,15 @@ static const JSMallocFunctions tracy_malloc_funcs = {
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void script_startup(int argc, char **argv) {
|
||||
JSRuntime *rt;
|
||||
#ifdef TRACY_ENABLE
|
||||
rt = JS_NewRuntime2(&tracy_malloc_funcs, NULL);
|
||||
#else
|
||||
rt = JS_NewRuntime();
|
||||
#endif
|
||||
js = JS_NewContextRaw(rt);
|
||||
JSContext *js = JS_NewContextRaw(rt);
|
||||
SDL_SetTLS(&js_id, js, NULL);
|
||||
JS_AddIntrinsicBaseObjects(js);
|
||||
JS_AddIntrinsicEval(js);
|
||||
JS_AddIntrinsicRegExp(js);
|
||||
@@ -159,7 +158,9 @@ void script_startup(int argc, char **argv) {
|
||||
JS_AddIntrinsicOperators(js);
|
||||
JS_EnableBignumExt(js, 1);
|
||||
|
||||
on_exception = JS_UNDEFINED;
|
||||
JSValue *onexp = malloc(sizeof(JSValue));
|
||||
*onexp = JS_UNDEFINED;
|
||||
SDL_SetTLS(&on_exception, onexp, tls_free);
|
||||
|
||||
ffi_load(js, argc, argv);
|
||||
|
||||
@@ -179,12 +180,13 @@ void script_startup(int argc, char **argv) {
|
||||
free(eng);
|
||||
}
|
||||
|
||||
void script_stop()
|
||||
void script_stop(JSContext *js, JSRuntime *rt)
|
||||
{
|
||||
return;
|
||||
JSValue *onexp = SDL_GetTLS(&on_exception);
|
||||
JS_FreeValue(js,*onexp);
|
||||
JS_FreeContext(js);
|
||||
JS_FreeRuntime(rt);
|
||||
JS_FreeValue(js,on_exception);
|
||||
|
||||
rt = NULL;
|
||||
js = NULL;
|
||||
@@ -196,10 +198,12 @@ void uncaught_exception(JSContext *js, JSValue v)
|
||||
JS_FreeValue(js,v);
|
||||
return;
|
||||
}
|
||||
|
||||
JSValue *onexp = SDL_GetTLS(&on_exception);
|
||||
|
||||
if (!JS_IsUndefined(on_exception)) {
|
||||
if (!JS_IsUndefined(*onexp)) {
|
||||
JSValue ex = JS_GetException(js);
|
||||
JSValue ret = JS_Call(js, on_exception, JS_UNDEFINED, 1, &ex);
|
||||
JSValue ret = JS_Call(js, *onexp, JS_UNDEFINED, 1, &ex);
|
||||
JS_FreeValue(js,ret);
|
||||
JS_FreeValue(js,ex);
|
||||
} else {
|
||||
@@ -219,6 +223,7 @@ void uncaught_exception(JSContext *js, JSValue v)
|
||||
|
||||
void script_evalf(const char *format, ...)
|
||||
{
|
||||
JSContext *js = SDL_GetTLS(&js_id);
|
||||
JSValue obj;
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
#define SCRIPT_H
|
||||
|
||||
#include "quickjs.h"
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
extern JSValue on_exception;
|
||||
extern SDL_TLSID on_exception;
|
||||
|
||||
void script_startup();
|
||||
void script_stop();
|
||||
@@ -11,6 +12,5 @@ void script_stop();
|
||||
void script_evalf(const char *format, ...);
|
||||
JSValue script_eval(JSContext *js, const char *file, const char *script);
|
||||
void uncaught_exception(JSContext *js, JSValue v);
|
||||
extern JSContext *global_js;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,7 @@ void transform_free(JSRuntime *rt, transform *t) {
|
||||
if (dirties[i] == t) arrdelswap(dirties, i);
|
||||
}
|
||||
|
||||
void transform_clean(transform *t)
|
||||
void transform_clean(JSContext *js, transform *t)
|
||||
{
|
||||
if (!t->dirty) return;
|
||||
t->dirty = 0;
|
||||
@@ -51,19 +51,19 @@ void transform_clean(transform *t)
|
||||
|
||||
for (int i = 0; i < arrlen(t->children); i++) {
|
||||
t->children[i]->dirty = 1;
|
||||
transform_clean(t->children[i]);
|
||||
transform_clean(js, t->children[i]);
|
||||
}
|
||||
|
||||
if (!JS_IsUndefined(t->change_hook)) {
|
||||
JSValue ret = JS_Call(global_js, t->change_hook, JS_DupValue(global_js,t->self), 0, NULL);
|
||||
JS_FreeValue(global_js,ret);
|
||||
JSValue ret = JS_Call(js, t->change_hook, JS_DupValue(js,t->self), 0, NULL);
|
||||
JS_FreeValue(js,ret);
|
||||
}
|
||||
}
|
||||
|
||||
void clean_all()
|
||||
void clean_all(JSContext *js)
|
||||
{
|
||||
for (int i = 0; i < arrlen(dirties); i++)
|
||||
transform_clean(dirties[i]);
|
||||
transform_clean(js, dirties[i]);
|
||||
|
||||
arrsetlen(dirties,0);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ typedef struct transform {
|
||||
JSValue change_hook;
|
||||
} transform;
|
||||
|
||||
void clean_all();
|
||||
void clean_all(JSContext *js);
|
||||
|
||||
transform *make_transform();
|
||||
void transform_free(JSRuntime *rt,transform *t);
|
||||
|
||||
@@ -4,6 +4,7 @@ var password = "abc123"
|
||||
|
||||
$_.portal(e => {
|
||||
console.log(`got message with password ${e.password}`)
|
||||
console.log(json.encode(e))
|
||||
if (e.password !== password)
|
||||
throw new Error("Password does not match.");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user