diff libmlk-core/mlk/core/js/js.c @ 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
line wrap: on
line diff
--- 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);