Mercurial > molko
changeset 643:993d9ccedcf6
core: repair js load
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sun, 17 Dec 2023 11:27:54 +0100 |
parents | 05b585720d3b |
children | 6d0f4edb79f8 |
files | libmlk-core/mlk/core/js/js-painter.c libmlk-core/mlk/core/js/js-sprite.c libmlk-core/mlk/core/js/js.c libmlk-core/mlk/core/js/js.h mlk-run/mlk-run.c |
diffstat | 5 files changed, 172 insertions(+), 201 deletions(-) [+] |
line wrap: on
line diff
--- a/libmlk-core/mlk/core/js/js-painter.c Sun Dec 17 09:50:36 2023 +0100 +++ b/libmlk-core/mlk/core/js/js-painter.c Sun Dec 17 11:27:54 2023 +0100 @@ -45,16 +45,6 @@ } static duk_ret_t -mlk_js_painter_new(duk_context *ctx) -{ - if (!duk_is_constructor_call(ctx)) - return duk_error(ctx, DUK_ERR_TYPE_ERROR, "Painter must be new-constructed"); - - - return 0; -} - -static duk_ret_t mlk_js_painter_clear(duk_context *ctx) { (void)ctx; @@ -88,7 +78,7 @@ } else return duk_error(ctx, DUK_ERR_ERROR, "Object or 4 numbers expected"); - mlk_painter_draw_line(x1, y2, x2, y2); + mlk_painter_draw_line(x1, y1, x2, y2); return 0; } @@ -183,7 +173,7 @@ return 0; } -static const duk_function_list_entry methods[] = { +static const duk_function_list_entry functions[] = { { "clear", mlk_js_painter_clear, 0 }, { "drawLine", mlk_js_painter_drawLine, DUK_VARARGS }, { "drawPoint", mlk_js_painter_drawPoint, DUK_VARARGS }, @@ -194,7 +184,7 @@ }; void -js_painter_load(duk_context *ctx) +mlk_js_painter_load(duk_context *ctx) { assert(ctx); @@ -205,7 +195,7 @@ duk_push_c_function(ctx, mlk_js_painter_getColor, 0); duk_push_c_function(ctx, mlk_js_painter_setColor, 1); duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); - duk_put_function_list(ctx, -1, methods); + duk_put_function_list(ctx, -1, functions); duk_put_prop_string(ctx, -2, "Painter"); duk_pop(ctx); }
--- a/libmlk-core/mlk/core/js/js-sprite.c Sun Dec 17 09:50:36 2023 +0100 +++ b/libmlk-core/mlk/core/js/js-sprite.c Sun Dec 17 11:27:54 2023 +0100 @@ -101,7 +101,7 @@ mlk_js_sprite_finish(duk_context *ctx) { duk_get_prop_string(ctx, 0, SYMBOL); - free(duk_to_pointer(ctx, -1)); + mlk_alloc_free(duk_to_pointer(ctx, -1)); duk_pop(ctx); duk_del_prop_string(ctx, 0, SYMBOL); duk_del_prop_string(ctx, 0, TEXTURE_REF); @@ -112,7 +112,7 @@ static duk_ret_t mlk_js_sprite_draw(duk_context *ctx) { - struct sprite *sprite = mlk_js_sprite_this(ctx); + struct mlk_sprite *sprite = mlk_js_sprite_this(ctx); unsigned int r, c; int x, y; @@ -148,7 +148,7 @@ struct mlk_sprite * mlk_js_sprite_require(duk_context *ctx, duk_idx_t index) { - struct sprite *sp; + struct mlk_sprite *sp; duk_get_prop_string(ctx, index, SYMBOL); sp = duk_to_pointer(ctx, -1); @@ -166,7 +166,7 @@ assert(ctx); duk_push_global_object(ctx); - duk_get_prop_string(ctx, -1, "Molko"); + duk_get_prop_string(ctx, -1, "Mlk"); duk_push_c_function(ctx, mlk_js_sprite_new, 3); duk_push_object(ctx); duk_put_function_list(ctx, -1, methods);
--- a/libmlk-core/mlk/core/js/js.c Sun Dec 17 09:50:36 2023 +0100 +++ b/libmlk-core/mlk/core/js/js.c Sun Dec 17 11:27:54 2023 +0100 @@ -17,35 +17,31 @@ */ #include <assert.h> -#include <libgen.h> -#include <limits.h> #include <string.h> #include <mlk/core/alloc.h> #include <mlk/core/err.h> #include <mlk/core/panic.h> #include <mlk/core/trace.h> +#include <mlk/core/vfs.h> #include <duktape.h> #include <duk_module.h> +#include "js-animation.h" +#include "js-clock.h" +#include "js-event.h" +#include "js-font.h" +#include "js-music.h" +#include "js-painter.h" +#include "js-sound.h" +#include "js-sprite.h" +#include "js-texture.h" +#include "js-util.h" +#include "js-window.h" #include "js.h" -static duk_ret_t -js_print(duk_context *ctx) -{ - puts(duk_require_string(ctx, 0)); - - return 0; -} - -static duk_ret_t -js_trace(duk_context *ctx) -{ - mlk_tracef("%s", duk_require_string(ctx, 0)); - - return 0; -} +#define JS_REF DUK_HIDDEN_SYMBOL("mlk::js") static void * wrap_malloc(void *udata, duk_size_t size) @@ -60,7 +56,17 @@ { (void)udata; - return mlk_alloc_resize(oldptr, size); + void *ptr = NULL; + + if (oldptr) { + if (!size) + mlk_alloc_free(oldptr); + else + ptr = mlk_alloc_resize(oldptr, size); + } else if (size) + ptr = mlk_alloc_new(1, size); + + return ptr; } static void @@ -79,40 +85,83 @@ mlk_panicf("%s", msg); } -#if 0 +static char * +read_all(struct mlk_js *js, const char *filename, size_t *len) +{ + struct mlk_vfs_file *file; + char *text; + + if (!(file = mlk_vfs_open(js->vfs, filename, "r"))) + return NULL; -static duk_ret_t -search(duk_context *ctx) + text = mlk_vfs_file_read_all(file, len); + mlk_vfs_file_finish(file); + + return text; +} + +static struct mlk_js * +mlk_js_this(duk_context *ctx) { - char path[PATH_MAX] = {}; - char *ret; + struct mlk_js *js; duk_push_global_stash(ctx); - duk_get_prop_string(ctx, -1, DUK_HIDDEN_SYMBOL("molko::base")); - snprintf(path, sizeof (path), "%s/%s.js", duk_to_string(ctx, -1), duk_require_string(ctx, 0)); - duk_pop_n(ctx, 2); + duk_get_prop_string(ctx, -1, JS_REF); + js = duk_to_pointer(ctx, -1); + duk_pop(ctx); + + if (!js) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "Not a Javascript context"); + + return js; +} + +static duk_ret_t +mlk_js_print(duk_context *ctx) +{ + puts(duk_require_string(ctx, 0)); + + return 0; +} - if (!(ret = readall(path))) - duk_error(ctx, DUK_ERR_ERROR, "%s", error()); +static duk_ret_t +mlk_js_trace(duk_context *ctx) +{ + mlk_tracef("%s", duk_require_string(ctx, 0)); + + return 0; +} - duk_push_string(ctx, ret); - free(ret); +static duk_ret_t +mlk_js_modSearch(duk_context *ctx) +{ + struct mlk_js *js; + const char *filename; + char *text; + size_t textsz; + + js = mlk_js_this(ctx); + filename = duk_require_string(ctx, 0); + + if (!(text = read_all(js, filename, &textsz))) + duk_error(ctx, DUK_ERR_ERROR, "%s", mlk_err()); + + duk_push_lstring(ctx, text, textsz); + free(text); return 1; } static void -setup_module(struct js *js) +setup_module(struct mlk_js *js) { duk_module_duktape_init(js->handle); duk_get_global_string(js->handle, "Duktape"); - duk_push_c_function(js->handle, search, 4); + duk_push_c_function(js->handle, mlk_js_modSearch, 4); duk_put_prop_string(js->handle, -2, "modSearch"); duk_pop(js->handle); } -#endif - static void setup_global(struct mlk_js *js) { @@ -120,44 +169,48 @@ duk_push_global_object(js->handle); duk_push_object(js->handle); duk_put_prop_string(js->handle, -2, "Mlk"); - duk_push_c_function(js->handle, js_print, 1); + duk_push_c_function(js->handle, mlk_js_print, 1); duk_put_prop_string(js->handle, -2, "print"); - duk_push_c_function(js->handle, js_trace, 1); + duk_push_c_function(js->handle, mlk_js_trace, 1); duk_put_prop_string(js->handle, -2, "trace"); duk_pop(js->handle); } static void -setup_properties(struct mlk_js *js) +setup_internal(struct mlk_js *js) { + duk_push_global_stash(js->handle); + /* Store a reference to this pointer. */ - duk_push_global_stash(js->handle); duk_push_pointer(js->handle, js); - duk_put_prop_string(js->handle, -2, DUK_HIDDEN_SYMBOL("mlk::pointer")); + duk_put_prop_string(js->handle, -2, JS_REF); + duk_pop(js->handle); } -#if 0 static void -setup_base(struct mlk_js *js, const char *path) +setup_core(struct mlk_js *js) { - char base[PATH_MAX] = {}; - - snprintf(base, sizeof (base), "%s", path); - snprintf(base, sizeof (base), "%s", dirname(base)); - - duk_push_global_stash(js->handle); - duk_push_string(js->handle, base); - duk_put_prop_string(js->handle, -2, DUK_HIDDEN_SYMBOL("mlk::base")); - duk_pop(js->handle); + mlk_js_animation_load(js->handle); + mlk_js_clock_load(js->handle); + mlk_js_event_load(js->handle); + mlk_js_font_load(js->handle); + mlk_js_music_load(js->handle); + mlk_js_painter_load(js->handle); + mlk_js_sound_load(js->handle); + mlk_js_sprite_load(js->handle); + mlk_js_texture_load(js->handle); + mlk_js_util_load(js->handle); + mlk_js_window_load(js->handle); } -#endif int -js_init(struct mlk_js *js) +mlk_js_init(struct mlk_js *js, struct mlk_vfs *vfs) { assert(js); + assert(vfs); + js->vfs = vfs; js->handle = duk_create_heap(wrap_malloc, wrap_realloc, wrap_free, NULL, wrap_fatal); @@ -166,49 +219,42 @@ return -1; } -#if 0 + setup_internal(js); + setup_global(js); setup_module(js); -#endif - setup_global(js); - setup_properties(js); + setup_core(js); return 0; } -#if 0 -bool -js_open(struct js *js, const char *path) +int +mlk_js_run(struct mlk_js *js, const char *main) { assert(js); - assert(path); - - char *text = readall(path); - bool ret = true; + assert(main); - if (!text) - return false; + int line, rv = -1; + char *text; + size_t textsz; - setup_base(js, path); - - if (duk_peval_string(js->handle, text) != 0) { - int ln; + if (!(text = read_all(js, main, &textsz))) + return -1; + if (duk_peval_lstring(js->handle, text, textsz) != 0) { duk_get_prop_string(js->handle, -1, "lineNumber"); - ln = duk_to_int(js->handle, -1); + line = duk_to_int(js->handle, -1); duk_pop(js->handle); - errorf("%d: %s", ln, duk_safe_to_string(js->handle, -1)); - ret = false; - } + mlk_errf("%d: %s", line, duk_safe_to_string(js->handle, -1)); + } else + rv = 0; - free(text); - duk_pop(js->handle); + mlk_alloc_free(text); - return ret; + return rv; } -#endif void -js_finish(struct mlk_js *js) +mlk_js_finish(struct mlk_js *js) { assert(js);
--- a/libmlk-core/mlk/core/js/js.h Sun Dec 17 09:50:36 2023 +0100 +++ b/libmlk-core/mlk/core/js/js.h Sun Dec 17 11:27:54 2023 +0100 @@ -19,16 +19,29 @@ #ifndef MLK_CORE_JS_H #define MLK_CORE_JS_H +#define MLK_CORE_JS_MAIN "main.js" + struct mlk_js { + /** + * (read-write, borrowed) + * + * VFS used to load resources. + */ + struct mlk_vfs *vfs; void *handle; }; +struct mlk_vfs; + #if defined(__cplusplus) extern "C" { #endif int -mlk_js_init(struct mlk_js *js); +mlk_js_init(struct mlk_js *js, struct mlk_vfs *vfs); + +int +mlk_js_run(struct mlk_js *js, const char *main); void mlk_js_finish(struct mlk_js *js);
--- a/mlk-run/mlk-run.c Sun Dec 17 09:50:36 2023 +0100 +++ b/mlk-run/mlk-run.c Sun Dec 17 11:27:54 2023 +0100 @@ -18,7 +18,7 @@ #include <stdio.h> #include <stdlib.h> -#include <limits.h> +#include <string.h> #include <duktape.h> #include <duk_module.h> @@ -32,6 +32,8 @@ #include <mlk/core/vfs-zip.h> #include <mlk/core/vfs.h> +#include <mlk/core/js/js.h> + union { struct mlk_vfs_dir dir; @@ -43,60 +45,8 @@ /* VFS loader to support zip and directories when loading game. */ static struct mlk_vfs *vfs; -/* Javascript context. */ -static duk_context *ctx; - -static duk_ret_t -modsearch(duk_context *ctx) -{ - char path[MLK_PATH_MAX] = {}, *data; - struct mlk_vfs_file *file; - size_t datasz; - - snprintf(path, sizeof (path), "%s.js", duk_require_string(ctx, 0)); - - if ((file = mlk_vfs_open(vfs, path, "r")) < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", mlk_err()); - if (!(data = mlk_vfs_file_read_all(file, &datasz))) { - mlk_vfs_file_finish(file); - return duk_error(ctx, DUK_ERR_ERROR, "%s", mlk_err()); - } - - mlk_vfs_file_finish(file); - duk_push_lstring(ctx, data, datasz); - free(data); - - return 1; -} - -static void -core_bind(duk_context *ctx) -{ -#if 0 - /* Brings Mlk global object. */ - mlk_js_core_bind(ctx, &vfs); - - js_action_bind(ctx); - js_action_stack_bind(ctx); - js_animation_bind(ctx); - js_clock_bind(ctx); - js_color_bind(ctx); - js_drawable_bind(ctx); - js_drawable_stack_bind(ctx); - js_event_bind(ctx); - js_font_bind(ctx); - js_game_bind(ctx); - js_music_bind(ctx); - js_painter_bind(ctx); - js_panic_bind(ctx); - js_sound_bind(ctx); - js_sprite_bind(ctx); - js_state_bind(ctx); - js_texture_bind(ctx); - js_trace_bind(ctx); - js_window_bind(ctx); -#endif -} +/* Global Javascript context. */ +static struct mlk_js js; static void init(void) @@ -104,74 +54,46 @@ /* TODO: this is temporary. */ if (mlk_core_init("fr.malikania", "mlk-run") < 0) mlk_panic(); - - /* Fireup Javascript. */ - ctx = duk_create_heap_default(); - core_bind(ctx); - - /* Setup module loader. */ - duk_module_duktape_init(ctx); - duk_get_global_string(ctx, "Duktape"); - duk_push_c_function(ctx, modsearch, 4); - duk_put_prop_string(ctx, -2, "modSearch"); - duk_pop(ctx); } static void -startup(void) +load_zip(const char *path) { - struct mlk_vfs_file *file; - char *code; - - if (!(file = mlk_vfs_open(vfs, "main.js", "r"))) +#if defined(MLK_WITH_ZIP) + if (mlk_vfs_zip_init(&iface.zip, path, "r") < 0) mlk_panic(); - if (!(code = mlk_vfs_file_read_all(file, NULL))) { - mlk_vfs_file_finish(file); - mlk_panic(); - } - - mlk_vfs_file_finish(file); - - if (duk_peval_string(ctx, code)) - mlk_panicf("%s", duk_safe_to_string(ctx, -1)); - free(code); -} - -static void -finish(void) -{ - mlk_vfs_finish(vfs); - duk_destroy_heap(ctx); -} - -static void -loadzip(const char *path) -{ -#if 0 - if (vfs_zip(&vfs, path, "r") < 0) - panic(); + vfs = &iface.zip.vfs; +#else + mlk_panicf("ZIP file support disabled")a; #endif } static void -loaddirectory(const char *path) +load_directory(const char *path) { -#if 0 - vfs_directory(&vfs, path); -#endif + mlk_vfs_dir_init(&iface.dir, path); + vfs = &iface.dir.vfs; } static void load(const char *path) { /* TODO: improve this. */ - if (strstr(path, ".mlk")) - loadzip(path); + if (strstr(path, ".mlk") || strstr(path, ".zip")) + load_zip(path); else - loaddirectory(path); + load_directory(path); + + if (mlk_js_init(&js, vfs) < 0 || mlk_js_run(&js, MLK_CORE_JS_MAIN)) + mlk_panic(); +} - startup(); +static void +finish(void) +{ + mlk_js_finish(&js); + mlk_vfs_finish(vfs); } static void