From 9e58f6539ef0366de514e205ba4472d0a6c4a7f8 Mon Sep 17 00:00:00 2001 From: luboslenco Date: Wed, 7 Aug 2024 22:48:08 +0200 Subject: [PATCH] Make hello_world plugin work --- armorpaint/assets/plugins/hello_world.js | 22 +-- base/sources/console.ts | 1 + base/sources/plugin.ts | 16 ++- base/sources/plugin_api.c | 164 ++++++++++++++++++++++- base/sources/tab_plugins.ts | 4 +- base/sources/ui_base.ts | 4 +- 6 files changed, 185 insertions(+), 26 deletions(-) diff --git a/armorpaint/assets/plugins/hello_world.js b/armorpaint/assets/plugins/hello_world.js index a91f1fcf..d90514fb 100644 --- a/armorpaint/assets/plugins/hello_world.js +++ b/armorpaint/assets/plugins/hello_world.js @@ -1,31 +1,31 @@ let plugin = plugin_create(); +let h0 = zui_handle_create(); let h1 = zui_handle_create(); let h2 = zui_handle_create(); let h3 = zui_handle_create(); let h4 = zui_handle_create(); let h5 = zui_handle_create(); let h6 = zui_handle_create(); -let h7 = zui_handle_create(); -plugin.draw_ui = function(ui) { - if (zui_panel(h1, "My Plugin")) { +plugin_notify_on_ui(plugin, function() { + if (zui_panel(h0, "My Plugin")) { zui_text("Label"); - zui_textInput(h7, "Text Input"); + zui_text_input(h1, "Text Input"); if (zui_button("Button")) { - console.error("Hello"); + console_info("Hello"); } - zui_row([1/2, 1/2]); + zui_row([1 / 2, 1 / 2]); zui_button("Button A"); zui_button("Button B"); - zui_combo(h5, ["Item 1", "Item 2"], "Combo"); - zui_row([1/2, 1/2]); - zui_slider(h2, "Slider", 0, 1, true); + zui_combo(h2, ["Item 1", "Item 2"], "Combo"); + zui_row([1 / 2, 1 / 2]); zui_slider(h3, "Slider", 0, 1, true); - zui_check(h4, "Check"); + zui_slider(h4, "Slider", 0, 1, true); + zui_check(h5, "Check"); zui_radio(h6, 0, "Radio 1"); zui_radio(h6, 1, "Radio 2"); zui_radio(h6, 2, "Radio 3"); } -} +}); diff --git a/base/sources/console.ts b/base/sources/console.ts index 5a687731..4291d7d8 100644 --- a/base/sources/console.ts +++ b/base/sources/console.ts @@ -69,6 +69,7 @@ function console_log(s: string) { } function console_trace(s: string) { + krom_log(s); base_redraw_console(); array_insert(console_last_traces, 0, s); if (console_last_traces.length > 100) { diff --git a/base/sources/plugin.ts b/base/sources/plugin.ts index 7422362c..7afcf499 100644 --- a/base/sources/plugin.ts +++ b/base/sources/plugin.ts @@ -1,9 +1,9 @@ type plugin_t = { - draw_ui?: (ui: zui_t)=>void; - draw?: ()=>void; - update?: ()=>void; - delete?: ()=>void; + on_ui?: any; // JSValue * + on_draw?: any; // JSValue * + on_update?: any; // JSValue * + on_delete?: any; // JSValue * version?: string; name?: string; }; @@ -27,8 +27,12 @@ function plugin_start(plugin: string) { function plugin_stop(plugin: string) { let p: plugin_t = map_get(plugin_map, plugin); - if (p != null && p.delete != null) { - p.delete(); + if (p.on_delete != null) { + js_call(p.on_delete); } map_delete(plugin_map, plugin); } + +function plugin_notify_on_ui(plugin: plugin_t, f: any): void { + plugin.on_ui = f; +} diff --git a/base/sources/plugin_api.c b/base/sources/plugin_api.c index edbea5bd..bd34900c 100644 --- a/base/sources/plugin_api.c +++ b/base/sources/plugin_api.c @@ -1,18 +1,172 @@ +#include +#include #include "quickjs/quickjs.h" +#include "quickjs/quickjs-libc.h" +#include "zui.h" +#include "iron_array.h" extern JSRuntime *js_runtime; extern JSContext *js_ctx; -void console_log(char *s); +#define MAKE_FN(name)\ + static JSValue js_##name(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) -static JSValue js_console_log(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { - console_log(JS_ToCString(ctx, argv[0])); - return JS_UNDEFINED; +#define MAKE_VOID_FN(name)\ + void name();\ + MAKE_FN(name) {\ + name();\ + return JS_UNDEFINED;\ + } + +#define MAKE_PTR_FN(name)\ + void *name();\ + MAKE_FN(name) {\ + int64_t result = (int64_t)name();\ + return JS_NewInt64(ctx, result);\ + } + +#define MAKE_VOID_FN_STR(name)\ + void name(char *s);\ + MAKE_FN(name) {\ + char *s = (char *)JS_ToCString(ctx, argv[0]);\ + name(s);\ + return JS_UNDEFINED;\ + } + +#define MAKE_VOID_FN_PTR_CB(name)\ + void name(void *p0, void *p1);\ + MAKE_FN(name) {\ + int64_t p0;\ + JS_ToInt64(ctx, &p0, argv[0]);\ + JSValue *p1 = malloc(sizeof(JSValue));\ + JSValue dup = JS_DupValue(ctx, argv[1]);\ + memcpy(p1, &dup, sizeof(JSValue));\ + name((void *)p0, p1);\ + return JS_UNDEFINED;\ + } + +#define BIND_FN(name, argc)\ + JS_SetPropertyStr(js_ctx, global_obj, #name, JS_NewCFunction(js_ctx, js_##name, #name, argc)) + +// These could be auto-generated by minits +MAKE_VOID_FN_STR(console_log) +MAKE_VOID_FN_STR(console_info) +MAKE_PTR_FN(plugin_create) +MAKE_VOID_FN_PTR_CB(plugin_notify_on_ui) + +MAKE_FN(zui_handle_create) { + int64_t result = (int64_t)zui_handle_create(); + return JS_NewInt64(ctx, result); +} + +MAKE_FN(zui_panel) { + int64_t p; + JS_ToInt64(ctx, &p, argv[0]); + char *s = (char *)JS_ToCString(ctx, argv[1]); + bool result = zui_panel((void *)p, s, false, false); + return JS_NewBool(ctx, result); +} + +MAKE_FN(zui_button) { + char *s = (char *)JS_ToCString(ctx, argv[0]); + bool result = zui_button(s, ZUI_ALIGN_CENTER, ""); + return JS_NewBool(ctx, result); +} + +MAKE_FN(zui_text) { + char *s = (char *)JS_ToCString(ctx, argv[0]); + zui_text(s, ZUI_ALIGN_LEFT, 0); + return JS_UNDEFINED; +} + +MAKE_FN(zui_text_input) { + int64_t p; + JS_ToInt64(ctx, &p, argv[0]); + char *s = (char *)JS_ToCString(ctx, argv[1]); + zui_text_input((void *)p, s, ZUI_ALIGN_LEFT, true, false); + return JS_UNDEFINED; +} + +MAKE_FN(zui_slider) { + int64_t p; + JS_ToInt64(ctx, &p, argv[0]); + char *s = (char *)JS_ToCString(ctx, argv[1]); + zui_slider((void *)p, s, 0, 1, true, 100, true, ZUI_ALIGN_LEFT, true); + return JS_UNDEFINED; +} + +MAKE_FN(zui_check) { + int64_t p; + JS_ToInt64(ctx, &p, argv[0]); + char *s = (char *)JS_ToCString(ctx, argv[1]); + zui_check((void *)p, s, ""); + return JS_UNDEFINED; +} + +MAKE_FN(zui_radio) { + int64_t p; + JS_ToInt64(ctx, &p, argv[0]); + int32_t pos; + JS_ToInt32(ctx, &pos, argv[1]); + char *s = (char *)JS_ToCString(ctx, argv[2]); + zui_radio((void *)p, pos, s, ""); + return JS_UNDEFINED; +} + +MAKE_FN(zui_row) { + JSValue val_len = JS_GetPropertyStr(ctx, argv[0], "length"); + int len; + JS_ToInt32(ctx, &len, val_len); + f32_array_t *ratios = f32_array_create(len); + for (int i = 0; i < len; ++i) { + JSValue val = JS_GetPropertyUint32(ctx, argv[0], i); + double f; + JS_ToFloat64(ctx, &f, val); + ratios->buffer[i] = f; + } + zui_row(ratios); + return JS_UNDEFINED; +} + +MAKE_FN(zui_combo) { + int64_t p; + JS_ToInt64(ctx, &p, argv[0]); + + JSValue val_len = JS_GetPropertyStr(ctx, argv[1], "length"); + int len; + JS_ToInt32(ctx, &len, val_len); + char_ptr_array_t *texts = any_array_create(len); + for (int i = 0; i < len; ++i) { + JSValue val = JS_GetPropertyUint32(ctx, argv[1], i); + char *s = (char *)JS_ToCString(ctx, val); + texts->buffer[i] = s; + } + + char *label = (char *)JS_ToCString(ctx, argv[2]); + + zui_combo((void *)p, texts, label, true, ZUI_ALIGN_LEFT, true); + return JS_UNDEFINED; } void plugin_api_init() { JSValue global_obj = JS_GetGlobalObject(js_ctx); - JS_SetPropertyStr(js_ctx, global_obj, "console_log", JS_NewCFunction(js_ctx, js_console_log, "console_log", 1)); + + BIND_FN(console_log, 1); + BIND_FN(console_info, 1); + BIND_FN(plugin_create, 0); + BIND_FN(plugin_notify_on_ui, 2); + + BIND_FN(zui_handle_create, 0); + BIND_FN(zui_panel, 2); + BIND_FN(zui_button, 1); + BIND_FN(zui_text, 1); + BIND_FN(zui_text_input, 2); + BIND_FN(zui_slider, 5); + BIND_FN(zui_check, 2); + BIND_FN(zui_radio, 3); + BIND_FN(zui_row, 1); + BIND_FN(zui_combo, 3); + JS_FreeValue(js_ctx, global_obj); } diff --git a/base/sources/tab_plugins.ts b/base/sources/tab_plugins.ts index f838067e..5a1f8b0f 100644 --- a/base/sources/tab_plugins.ts +++ b/base/sources/tab_plugins.ts @@ -24,8 +24,8 @@ function tab_plugins_draw(htab: zui_handle_t) { let keys: string[] = map_keys(plugin_map); for (let i: i32 = 0; i < keys.length; ++i) { let p: plugin_t = map_get(plugin_map, keys[i]); - if (p.draw_ui != null) { - p.draw_ui(ui); + if (p.on_ui != null) { + js_call(p.on_ui); } } } diff --git a/base/sources/ui_base.ts b/base/sources/ui_base.ts index e1134917..6c6b79d0 100644 --- a/base/sources/ui_base.ts +++ b/base/sources/ui_base.ts @@ -275,8 +275,8 @@ function ui_base_update() { let keys: string[] = map_keys(plugin_map); for (let i: i32 = 0; i < keys.length; ++i) { let p: plugin_t = map_get(plugin_map, keys[i]); - if (p.update != null) { - p.update(); + if (p.on_update != null) { + js_call(p.on_update); } }