Trying to normalize event handling somewhat. More to go before it's simple.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3685 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
2021-11-07 22:28:58 +00:00
parent 68cf3efcde
commit 18c90214a8
5 changed files with 284 additions and 149 deletions

View File

@ -335,37 +335,6 @@ static JSValue _tf_ssb_connect(JSContext* context, JSValueConst this_val, int ar
return JS_UNDEFINED;
}
static void _tf_ssb_call_callback(tf_ssb_t* ssb, const char* name, void* user_data)
{
JSContext* context = tf_ssb_get_context(ssb);
JSValue global = JS_GetGlobalObject(context);
JSValue ssbo = JS_GetPropertyStr(context, global, "ssb");
JSValue callback = JS_GetPropertyStr(context, ssbo, name);
if (JS_IsFunction(context, callback))
{
JSValue args = JS_UNDEFINED;
JSValue response = JS_Call(context, callback, JS_UNDEFINED, 0, &args);
tf_util_report_error(context, response);
if (tf_task_get(context))
{
tf_task_run_jobs(tf_task_get(context));
}
JS_FreeValue(context, response);
}
JS_FreeValue(context, ssbo);
JS_FreeValue(context, global);
}
static void _tf_ssb_broadcasts_changed(tf_ssb_t* ssb, void* user_data)
{
_tf_ssb_call_callback(ssb, "onBroadcastsChanged", user_data);
}
static void _tf_ssb_connections_changed(tf_ssb_t* ssb, tf_ssb_change_t change, tf_ssb_connection_t* connection, void* user_data)
{
_tf_ssb_call_callback(ssb, "onConnectionsChanged", user_data);
}
static JSValue _tf_ssb_rpc_send_json(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
JSValue connection_val = JS_GetPropertyStr(context, this_val, "connection");
@ -440,13 +409,13 @@ void _tf_ssb_on_rpc(tf_ssb_connection_t* connection, uint8_t flags, int32_t requ
JS_FreeValue(context, object);
}
static void _tf_ssb_rpc_js_value_cleanup(tf_ssb_t* ssb, void* user_data)
static void _tf_ssb_cleanup_value(tf_ssb_t* ssb, void* user_data)
{
JSValue callback = JS_MKPTR(JS_TAG_OBJECT, user_data);
JS_FreeValue(tf_ssb_get_context(ssb), callback);
}
static JSValue _tf_ssb_register_rpc(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
static JSValue _tf_ssb_add_rpc(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
if (!JS_IsArray(context, argv[0]))
@ -477,7 +446,7 @@ static JSValue _tf_ssb_register_rpc(JSContext* context, JSValueConst this_val, i
JS_FreeValue(context, value);
}
tf_ssb_register_rpc(ssb, name, _tf_ssb_on_rpc, _tf_ssb_rpc_js_value_cleanup, JS_VALUE_GET_PTR(JS_DupValue(context, argv[1])));
tf_ssb_add_rpc_callback(ssb, name, _tf_ssb_on_rpc, _tf_ssb_cleanup_value, JS_VALUE_GET_PTR(JS_DupValue(context, argv[1])));
for (int i = 0; i < length; i++)
{
@ -487,7 +456,7 @@ static JSValue _tf_ssb_register_rpc(JSContext* context, JSValueConst this_val, i
return JS_UNDEFINED;
}
static void _tf_ssb_on_blob_want_added(tf_ssb_t* ssb, const char* id, void* user_data)
static void _tf_ssb_on_blob_want_added_callback(tf_ssb_t* ssb, const char* id, void* user_data)
{
JSContext* context = tf_ssb_get_context(ssb);
JSValue callback = JS_MKPTR(JS_TAG_OBJECT, user_data);
@ -498,24 +467,7 @@ static void _tf_ssb_on_blob_want_added(tf_ssb_t* ssb, const char* id, void* user
JS_FreeValue(context, string);
}
static void _tf_ssb_cleanup_value(tf_ssb_t* ssb, void* user_data)
{
JSValue callback = JS_MKPTR(JS_TAG_OBJECT, user_data);
JS_FreeValue(tf_ssb_get_context(ssb), callback);
}
static JSValue _tf_ssb_register_blob_want_added(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
if (!JS_IsFunction(context, argv[0]))
{
return JS_ThrowTypeError(context, "Expected argument 1 to be a function.");
}
tf_ssb_register_blob_want_added(ssb, _tf_ssb_on_blob_want_added, _tf_ssb_cleanup_value, JS_VALUE_GET_PTR(JS_DupValue(context, argv[0])));
return JS_UNDEFINED;
}
static void _tf_ssb_rpc_on_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_change_t change, tf_ssb_connection_t* connection, void* user_data)
static void _tf_ssb_on_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_change_t change, tf_ssb_connection_t* connection, void* user_data)
{
JSContext* context = tf_ssb_get_context(ssb);
JSValue callback = JS_MKPTR(JS_TAG_OBJECT, user_data);
@ -557,18 +509,13 @@ static void _tf_ssb_rpc_on_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_ch
JS_FreeValue(context, response);
}
static JSValue _tf_ssb_register_connections_changed(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
static void _tf_ssb_on_broadcasts_changed_callback(tf_ssb_t* ssb, void* user_data)
{
printf("register connections changed\n");
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
if (!JS_IsFunction(context, argv[0]))
{
return JS_ThrowTypeError(context, "Expected argument 1 to be a function.");
}
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, argv[0]));
printf("registering %p TAG=%d\n", ptr, JS_VALUE_GET_TAG(argv[0]));
tf_ssb_add_connections_changed_callback(ssb, _tf_ssb_rpc_on_connections_changed_callback, _tf_ssb_rpc_js_value_cleanup, ptr);
return JS_UNDEFINED;
JSContext* context = tf_ssb_get_context(ssb);
JSValue callback = JS_MKPTR(JS_TAG_OBJECT, user_data);
JSValue response = JS_Call(context, callback, JS_UNDEFINED, 1, &JS_UNDEFINED);
tf_util_report_error(context, response);
JS_FreeValue(context, response);
}
void tf_ssb_run_file(JSContext* context, const char* file_name)
@ -632,6 +579,82 @@ void tf_ssb_run_file(JSContext* context, const char* file_name)
free(source);
}
static JSValue _tf_ssb_add_event_listener(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
const char* event_name = JS_ToCString(context, argv[0]);
JSValue callback = argv[1];
JSValue result = JS_UNDEFINED;
if (!event_name)
{
result = JS_ThrowTypeError(context, "Expected argument 1 to be a string event name.");
}
else if (!JS_IsFunction(context, callback))
{
result = JS_ThrowTypeError(context, "Expected argument 2 to be a function.");
}
else
{
if (strcmp(event_name, "connections") == 0)
{
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
tf_ssb_add_connections_changed_callback(ssb, _tf_ssb_on_connections_changed_callback, _tf_ssb_cleanup_value, ptr);
}
else if (strcmp(event_name, "broadcasts") == 0)
{
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
tf_ssb_add_broadcasts_changed_callback(ssb, _tf_ssb_on_broadcasts_changed_callback, _tf_ssb_cleanup_value, ptr);
}
else if (strcmp(event_name, "blob_want_added") == 0)
{
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
tf_ssb_add_blob_want_added_callback(ssb, _tf_ssb_on_blob_want_added_callback, _tf_ssb_cleanup_value, ptr);
}
}
JS_FreeCString(context, event_name);
return result;
}
static JSValue _tf_ssb_remove_event_listener(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
const char* event_name = JS_ToCString(context, argv[0]);
JSValue callback = argv[1];
JSValue result = JS_UNDEFINED;
if (!event_name)
{
result = JS_ThrowTypeError(context, "Expected argument 1 to be a string event name.");
}
else if (!JS_IsFunction(context, callback))
{
result = JS_ThrowTypeError(context, "Expected argument 2 to be a function.");
}
else
{
if (strcmp(event_name, "connections") == 0)
{
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
tf_ssb_remove_connections_changed_callback(ssb, _tf_ssb_on_connections_changed_callback, ptr);
}
else if (strcmp(event_name, "broadcasts") == 0)
{
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
tf_ssb_remove_broadcasts_changed_callback(ssb, _tf_ssb_on_broadcasts_changed_callback, ptr);
}
else if (strcmp(event_name, "blob_want_added") == 0)
{
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
tf_ssb_remove_blob_want_added_callback(ssb, _tf_ssb_on_blob_want_added_callback, ptr);
}
}
JS_FreeCString(context, event_name);
return result;
}
void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
{
JS_NewClassID(&_tf_ssb_classId);
@ -644,9 +667,6 @@ void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
fprintf(stderr, "Failed to register ssb.\n");
}
tf_ssb_set_broadcasts_changed_callback(ssb, _tf_ssb_broadcasts_changed, NULL);
tf_ssb_add_connections_changed_callback(ssb, _tf_ssb_connections_changed, NULL, NULL);
JSValue global = JS_GetGlobalObject(context);
JSValue object = JS_NewObjectClass(context, _tf_ssb_classId);
JS_SetPropertyStr(context, global, "ssb", object);
@ -663,9 +683,11 @@ void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
JS_SetPropertyStr(context, object, "storeMessage", JS_NewCFunction(context, _tf_ssb_storeMessage, "storeMessage", 1));
JS_SetPropertyStr(context, object, "getBroadcasts", JS_NewCFunction(context, _tf_ssb_getBroadcasts, "getBroadcasts", 0));
JS_SetPropertyStr(context, object, "connect", JS_NewCFunction(context, _tf_ssb_connect, "connect", 1));
JS_SetPropertyStr(context, object, "registerRpc", JS_NewCFunction(context, _tf_ssb_register_rpc, "registerRpc", 2));
JS_SetPropertyStr(context, object, "registerBlobWantAdded", JS_NewCFunction(context, _tf_ssb_register_blob_want_added, "registerBlobWantAdded", 1));
JS_SetPropertyStr(context, object, "registerConnectionsChanged", JS_NewCFunction(context, _tf_ssb_register_connections_changed, "registerConnectionsChanged", 1));
JS_SetPropertyStr(context, object, "addRpc", JS_NewCFunction(context, _tf_ssb_add_rpc, "addRpc", 2));
JS_SetPropertyStr(context, object, "addEventListener", JS_NewCFunction(context, _tf_ssb_add_event_listener, "addEventListener", 2));
JS_SetPropertyStr(context, object, "removeEventListener", JS_NewCFunction(context, _tf_ssb_remove_event_listener, "removeEventListener", 2));
JS_FreeValue(context, global);