#include "qjs_actor.h" #include "jsffi.h" #include "qjs_macros.h" #include "qjs_wota.h" #include "cell.h" #include #include #include // External function declarations JSValue js_actor_delay(JSContext *js, JSValue self, int argc, JSValue *argv); JSValue js_actor_removetimer(JSContext *js, JSValue self, int argc, JSValue *argv); cell_rt *js2actor(JSContext *js, JSValue v) { if (!JS_IsObject(v)) return NULL; cell_rt *crt = JS_GetContextOpaque(js); JSValue actor_data = JS_GetPropertyStr(js, v, "__ACTORDATA__"); if (JS_IsUndefined(actor_data)) { JS_FreeValue(js, actor_data); return NULL; } JSValue id_val = JS_GetPropertyStr(js, actor_data, "id"); JS_FreeValue(js, actor_data); if (JS_IsUndefined(id_val)) { JS_FreeValue(js, id_val); return NULL; } const char *id = JS_ToCString(js, id_val); JS_FreeValue(js, id_val); if (!id) return NULL; cell_rt *actor = get_actor((char*)id); JS_FreeCString(js, id); return actor; } JSValue actor2js(JSContext *js, cell_rt *actor) { if (!actor) return JS_NULL; JSValue actor_obj = JS_NewObject(js); if (JS_IsException(actor_obj)) return actor_obj; JSValue actor_data = JS_NewObject(js); if (JS_IsException(actor_data)) { JS_FreeValue(js, actor_obj); return actor_data; } JS_SetPropertyStr(js, actor_data, "id", JS_NewString(js, actor->id)); /* TODO: If the actor has network info, we could add address and port here */ /* JS_SetPropertyStr(js, actor_data, "address", JS_NewString(js, actor->address)); */ /* JS_SetPropertyStr(js, actor_data, "port", JS_NewInt32(js, actor->port)); */ cell_rt *crt = JS_GetContextOpaque(js); JS_SetPropertyStr(js, actor_obj, "__ACTORDATA__", actor_data); return actor_obj; } JSC_CCALL(os_createactor, void *startup = value2wota(js, argv[0], JS_UNDEFINED); create_actor(startup); ) JSC_CCALL(os_mailbox_push, if (argc < 2) return JS_ThrowInternalError(js, "Need an actor and a message"); if (!JS_IsObject(argv[1])) return JS_ThrowInternalError(js, "Object to push must be an object."); const char *id = JS_ToCString(js, argv[0]); int exist = actor_exists(id); JS_FreeCString(js,id); if (!exist) return JS_ThrowInternalError(js, "No mailbox found for given ID"); void *data = value2wota(js, argv[1], JS_UNDEFINED); const char *err = send_message(id, data); if (err) { free(data); return JS_ThrowInternalError(js, "Could not send message: %s", err); } ) JSC_CCALL(os_register_actor, cell_rt *rt = JS_GetContextOpaque(js); const char *id = JS_ToCString(js, argv[0]); double ar; JS_ToFloat64(js, &ar, argv[3]); const char *err = register_actor(id, rt, JS_ToBool(js, argv[2]), ar); if (err) return JS_ThrowInternalError(js, "Could not register actor: %s", err); rt->message_handle = JS_DupValue(js, argv[1]); rt->context = js; JS_FreeCString(js, id); ) JSC_CCALL(os_mailbox_exist, const char *id = JS_ToCString(js, argv[0]); int exist = actor_exists(id); JS_FreeCString(js, id); return JS_NewBool(js, exist); ) JSC_CCALL(os_unneeded, cell_rt *actor = JS_GetContextOpaque(js); SDL_LockMutex(actor->msg_mutex); JS_FreeValue(js, actor->unneeded); if (!JS_IsFunction(js, argv[0])) { actor->unneeded = JS_UNDEFINED; goto END; } actor->unneeded = JS_DupValue(js, argv[0]); JS_ToFloat64(js, &actor->ar_secs, argv[1]); END: if (actor->ar) { SDL_RemoveTimer(actor->ar); actor->ar = 0; } set_actor_state(actor); SDL_UnlockMutex(actor->msg_mutex); ) JSC_CCALL(actor_disrupt, cell_rt *crt = JS_GetContextOpaque(js); actor_disrupt(crt); ) JSC_SCALL(actor_setname, cell_rt *rt = JS_GetContextOpaque(js); rt->name = strdup(str); ) JSC_CCALL(actor_testfn, cell_rt *crt = js2actor(js, argv[0]); printf("actor? %p\n", crt); ) JSC_CCALL(actor_on_exception, cell_rt *rt = JS_GetContextOpaque(js); JS_FreeValue(js, rt->on_exception); rt->on_exception = JS_DupValue(js,argv[0]); ) static const JSCFunctionListEntry js_actor_funcs[] = { MIST_FUNC_DEF(os, createactor, 1), MIST_FUNC_DEF(os, mailbox_push, 2), MIST_FUNC_DEF(os, mailbox_exist, 1), MIST_FUNC_DEF(actor, delay, 2), MIST_FUNC_DEF(actor, removetimer, 1), MIST_FUNC_DEF(os, register_actor, 4), MIST_FUNC_DEF(os, unneeded, 2), MIST_FUNC_DEF(actor, disrupt, 0), MIST_FUNC_DEF(actor, setname, 1), MIST_FUNC_DEF(actor, testfn, 1), MIST_FUNC_DEF(actor, on_exception, 1), }; JSValue js_actor_use(JSContext *js) { JSValue mod = JS_NewObject(js); JS_SetPropertyFunctionList(js,mod,js_actor_funcs,countof(js_actor_funcs)); return mod; }