use wota for on machine message passing
This commit is contained in:
@@ -24,8 +24,6 @@ prosperon.dispatch = function(type, data) {
|
||||
var os = use_embed('os')
|
||||
var js = use_embed('js')
|
||||
|
||||
prosperon.on('exit', _ => { console.log('exiting') })
|
||||
|
||||
prosperon.on('SIGINT', function() {
|
||||
os.exit(1)
|
||||
})
|
||||
@@ -553,6 +551,7 @@ var util = use('util')
|
||||
var math = use('math')
|
||||
var crypto = use('crypto')
|
||||
var nota = use('nota')
|
||||
var wota = use('wota')
|
||||
|
||||
var HEADER = Symbol()
|
||||
|
||||
@@ -765,7 +764,7 @@ function actor_send(actor, message) {
|
||||
}
|
||||
|
||||
if (actor.__ACTORDATA__.id && os.mailbox_exist(actor.__ACTORDATA__.id)) {
|
||||
os.mailbox_push(actor.__ACTORDATA__.id, nota.encode(message))
|
||||
os.mailbox_push(actor.__ACTORDATA__.id, wota.encode(message))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -851,13 +850,15 @@ function handle_actor_disconnect(id) {
|
||||
delete peers[id]
|
||||
}
|
||||
|
||||
function handle_message(msg) {
|
||||
if (msg instanceof ArrayBuffer)
|
||||
msg = nota.decode(msg)
|
||||
function handle_local(msg) {
|
||||
console.log(`got an arraybuffer of length ${msg.byteLength}`)
|
||||
handle_message(wota.decode(msg))
|
||||
}
|
||||
|
||||
function handle_message(msg) {
|
||||
if (msg.target) {
|
||||
if (msg.target !== prosperon.id) {
|
||||
os.mailbox_push(msg.target, nota.encode(msg))
|
||||
os.mailbox_push(msg.target, wota.encode(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -913,7 +914,7 @@ var last_t = os.now()
|
||||
while (1) {
|
||||
if (portal) portal.service(handle_host, hang)
|
||||
if (contactor) contactor.service(handle_host, hang)
|
||||
os.mailbox_service(prosperon.id, handle_message)
|
||||
os.mailbox_service(prosperon.id, handle_local)
|
||||
var elapsed = os.now() - last_t
|
||||
last_t = os.now()
|
||||
for (var i in timers) {
|
||||
|
||||
43
scripts/modules/wota.js
Normal file
43
scripts/modules/wota.js
Normal file
@@ -0,0 +1,43 @@
|
||||
// wota
|
||||
var wota = this
|
||||
|
||||
var json = use('json')
|
||||
|
||||
var encode = wota.encode
|
||||
|
||||
function wota_tostring()
|
||||
{
|
||||
return json.encode(wota.decode(this))
|
||||
}
|
||||
|
||||
var wota_obj = {
|
||||
toString: wota_tostring
|
||||
}
|
||||
|
||||
wota.encode = function(obj, replacer)
|
||||
{
|
||||
var result = encode(obj, replacer)
|
||||
result.toString = wota_tostring
|
||||
return result
|
||||
}
|
||||
|
||||
wota.encode[prosperon.DOC] = `Convert a JavaScript value into a WOTA-encoded ArrayBuffer.
|
||||
|
||||
This function serializes JavaScript values (such as numbers, strings, booleans, arrays, objects, or ArrayBuffers) into the WOTA binary format. The resulting ArrayBuffer can be stored or transmitted and later decoded back into a JavaScript value.
|
||||
|
||||
:param value: The JavaScript value to encode (e.g., number, string, boolean, array, object, or ArrayBuffer).
|
||||
:param replacer: An optional function that alters the encoding behavior for specific values.
|
||||
:return: An ArrayBuffer containing the WOTA-encoded data.
|
||||
:throws: An error if no argument is provided or if a cyclic object is encountered.
|
||||
`
|
||||
|
||||
wota.decode[prosperon.DOC] = `Decode a WOTA-encoded ArrayBuffer into a JavaScript value.
|
||||
|
||||
This function deserializes a WOTA-formatted ArrayBuffer into its corresponding JavaScript representation, such as a number, string, boolean, array, object, or ArrayBuffer. If the input is invalid or empty, it returns undefined.
|
||||
|
||||
:param buffer: An ArrayBuffer containing WOTA-encoded data to decode.
|
||||
:param reviver: An optional function that transforms the decoded values.
|
||||
:return: The decoded JavaScript value (e.g., number, string, boolean, array, object, or ArrayBuffer), or undefined if no argument is provided.
|
||||
`
|
||||
|
||||
return wota
|
||||
@@ -7147,9 +7147,14 @@ JSC_CCALL(os_createthread,
|
||||
SDL_DetachThread(thread);
|
||||
)
|
||||
|
||||
struct message {
|
||||
void *data;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
typedef struct mailbox {
|
||||
SDL_Mutex *mutex;
|
||||
void **messages;
|
||||
struct message *messages;
|
||||
} mailbox;
|
||||
|
||||
static struct { char *key; mailbox value; } *mailboxes = NULL;
|
||||
@@ -7157,78 +7162,81 @@ static SDL_Mutex *mailboxes_mutex = NULL;
|
||||
|
||||
JSC_CCALL(os_mailbox_push,
|
||||
if (argc < 2) return JS_ThrowInternalError(js, "Need an actor and a message");
|
||||
char *id = JS_ToCString(js, argv[0]);
|
||||
void *data = NULL;
|
||||
if (JS_IsString(argv[1]))
|
||||
data = (void*)JS_ToCString(js, argv[1]);
|
||||
else if (JS_IsArrayBuffer(js, argv[1])) {
|
||||
if (!JS_IsArrayBuffer(js, argv[1])) return JS_ThrowInternalError(js, "Object to push into the mailbox must be an array buffer.");
|
||||
|
||||
const char *id = JS_ToCString(js, argv[0]);
|
||||
int mailbox_index = shgeti(mailboxes, id);
|
||||
JS_FreeCString(js, id);
|
||||
|
||||
if (mailbox_index == -1)
|
||||
return JS_ThrowInternalError(js, "No mailbox found for given ID");
|
||||
|
||||
size_t size;
|
||||
uint8_t *buf = JS_GetArrayBuffer(js, &size, argv[1]);
|
||||
data = malloc(size + 1);
|
||||
memcpy(data, buf, size);
|
||||
((char*)data)[size] = 0;
|
||||
} else return JS_ThrowTypeError(js, "Message must be string or ArrayBuffer");
|
||||
|
||||
int mailbox_index = shgeti(mailboxes, id);
|
||||
if (mailbox_index == -1) {
|
||||
if (!JS_IsString(argv[1])) free(data);
|
||||
JS_FreeCString(js, id);
|
||||
return JS_ThrowInternalError(js, "No mailbox found for given ID");
|
||||
}
|
||||
if (!buf) return JS_ThrowInternalError(js, "Could not get data from arraybuffer.");
|
||||
|
||||
void *data = malloc(size);
|
||||
if (!data) return JS_ThrowInternalError(js, "Memory allocation failed.");
|
||||
|
||||
memcpy(data,buf,size);
|
||||
|
||||
mailbox *mb = &mailboxes[mailbox_index].value;
|
||||
SDL_LockMutex(mb->mutex);
|
||||
arrput(mb->messages, data);
|
||||
struct message msg = {data, size};
|
||||
arrput(mb->messages, msg);
|
||||
SDL_UnlockMutex(mb->mutex);
|
||||
|
||||
JS_FreeCString(js, id);
|
||||
)
|
||||
|
||||
JSC_CCALL(os_mailbox_service,
|
||||
char *id = JS_ToCString(js, argv[0]);
|
||||
JSValue fn = JS_DupValue(js, argv[1]);
|
||||
void js_dofree(JSRuntime *rt, void *opaque, void *ptr)
|
||||
{
|
||||
js_free_rt(rt, ptr);
|
||||
}
|
||||
|
||||
JSC_CCALL(os_mailbox_service,
|
||||
if (!JS_IsFunction(js, argv[1])) return JS_ThrowInternalError(js, "Arg 2 must be a function");
|
||||
|
||||
const char *id = JS_ToCString(js, argv[0]);
|
||||
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");
|
||||
}
|
||||
|
||||
if (mb_index == -1) return JS_ThrowInternalError(js, "No mailbox found for given ID");
|
||||
|
||||
mailbox *mb = &mailboxes[mb_index].value;
|
||||
void **temp = NULL;
|
||||
struct message *temp = NULL;
|
||||
SDL_LockMutex(mb->mutex);
|
||||
int count = arrlen(mb->messages);
|
||||
if (count > 0) {
|
||||
arrsetlen(temp, count);
|
||||
memcpy(temp, mb->messages, sizeof(void*) * count);
|
||||
memcpy(temp, mb->messages, sizeof(*mb->messages) * count);
|
||||
arrsetlen(mb->messages, 0);
|
||||
}
|
||||
SDL_UnlockMutex(mb->mutex);
|
||||
|
||||
if (count == 0) return JS_UNDEFINED;
|
||||
|
||||
JSValue fn = JS_DupValue(js, argv[1]);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
void *data = temp[i];
|
||||
JSValue arg = JS_IsString(argv[1]) ? JS_NewString(js, (char*)data) : JS_NewArrayBufferCopy(js, data, strlen(data));
|
||||
JSValue arg = JS_NewArrayBuffer(js, temp[i].data, temp[i].size, js_dofree, NULL, 0);
|
||||
JSValue call = JS_Call(js, fn, JS_UNDEFINED, 1, &arg);
|
||||
uncaught_exception(js, call);
|
||||
JS_FreeValue(js, arg);
|
||||
free(data);
|
||||
JS_FreeValue(js,arg);
|
||||
}
|
||||
arrfree(temp);
|
||||
|
||||
JS_FreeCString(js, id);
|
||||
arrfree(temp);
|
||||
JS_FreeValue(js, fn);
|
||||
)
|
||||
|
||||
JSC_CCALL(os_mailbox_exist,
|
||||
char *id = JS_ToCString(js, argv[0]);
|
||||
const char *id = JS_ToCString(js, argv[0]);
|
||||
bool exists = shgeti(mailboxes, id) != -1;
|
||||
JS_FreeCString(js, id);
|
||||
return JS_NewBool(js, exists);
|
||||
)
|
||||
|
||||
JSC_CCALL(os_mailbox_start,
|
||||
char *id = JS_ToCString(js, argv[0]);
|
||||
const char *id = JS_ToCString(js, argv[0]);
|
||||
mailbox mb;
|
||||
mb.mutex = SDL_CreateMutex();
|
||||
mb.messages = NULL;
|
||||
@@ -7678,7 +7686,6 @@ static void signal_handler(int sig) {
|
||||
|
||||
JSContext *js = SDL_GetTLS(&js_id);
|
||||
|
||||
printf("dispatching to js %p\n", js);
|
||||
script_evalf(js, "prosperon.dispatch('%s')", str);
|
||||
}
|
||||
|
||||
|
||||
@@ -310,8 +310,8 @@ static JSValue js_wota_decode(JSContext *ctx, JSValueConst this_val, int argc, J
|
||||
}
|
||||
|
||||
static const JSCFunctionListEntry js_wota_funcs[] = {
|
||||
JS_CFUNC_DEF("encode", 1, js_wota_encode),
|
||||
JS_CFUNC_DEF("decode", 1, js_wota_decode),
|
||||
JS_CFUNC_DEF("encode", 2, js_wota_encode),
|
||||
JS_CFUNC_DEF("decode", 2, js_wota_decode),
|
||||
};
|
||||
|
||||
static int js_wota_init(JSContext *ctx, JSModuleDef *m)
|
||||
|
||||
@@ -5,4 +5,7 @@
|
||||
|
||||
JSValue js_wota_use(JSContext*);
|
||||
|
||||
void *value2wota(JSContext*, JSValue);
|
||||
JSValue wota2value(JSContext*, void*);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -180,6 +180,7 @@ void script_startup(int argc, char **argv) {
|
||||
|
||||
void script_stop(JSContext *js)
|
||||
{
|
||||
printf("STOPPING CONTEXT %p\n", js);
|
||||
return;
|
||||
JSValue *onexp = SDL_GetTLS(&on_exception);
|
||||
JS_FreeValue(js,*onexp);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
var os = use('os')
|
||||
|
||||
$_.delay(_ => {
|
||||
$_.start(e => {
|
||||
switch(e.type) {
|
||||
case "actor_started":
|
||||
@@ -15,4 +14,3 @@ $_.start(e => {
|
||||
$_.stop()
|
||||
}
|
||||
}, "tests/underling.js");
|
||||
}, 3)
|
||||
|
||||
@@ -8,4 +8,5 @@ os.createprocess(["./prosperon", "tests/portal.js"])
|
||||
|
||||
$_.delay(_ => {
|
||||
os.createprocess(["./prosperon", "tests/contact.js"])
|
||||
$_.stop()
|
||||
}, 0.2)
|
||||
|
||||
Reference in New Issue
Block a user