[mw-devel] [Git][arthur/mw][master] Implement mw.command for defining new commands (bind replacement)

Andrew Price welshbyte at sucs.org
Sat Nov 3 22:18:52 GMT 2018


Andrew Price pushed to branch master at Justin Mitchell / mw


Commits:
eefe9cc5 by Andrew Price at 2018-11-03T22:16:13+00:00
Implement mw.command for defining new commands (bind replacement)

Define a new command ,boop handled by boopCmd:

    function boopCmd(arg1, arg2, arg3)
    {
            mw.print("Arg 1: " + arg1);
            mw.print("Arg 2: " + arg2);
            mw.print("Arg 3: " + arg3);
    }
    mw.command.boop = boopCmd;

- - - - -


3 changed files:

- src/client/js-duk.c
- src/client/js.h
- src/client/script.c


Changes:

=====================================
src/client/js-duk.c
=====================================
--- a/src/client/js-duk.c
+++ b/src/client/js-duk.c
@@ -1081,6 +1081,102 @@ static void define_store_object(const char *name)
 	duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE);
 }
 
+static duk_ret_t js_command_get(duk_context *cx)
+{
+	const char *key = duk_get_string(cx, 1);
+
+	duk_push_this(cx);
+	(void)duk_get_prop_string(cx, -1, key);
+	return 1;
+}
+
+static duk_ret_t js_command_set(duk_context *cx)
+{
+	(void)duk_require_string(cx, 1);
+	duk_require_callable(cx, 2);
+
+	duk_push_this(cx); /* Target object */
+	duk_dup(cx, 1); /* Command name */
+	duk_dup(cx, 2); /* Handler */
+	duk_def_prop(cx, -3, DUK_DEFPROP_HAVE_VALUE);
+	return 0;
+}
+
+static duk_ret_t js_command_has(duk_context *cx)
+{
+	const char *key = duk_get_string(cx, 1);
+
+	duk_push_this(cx);
+	return duk_has_prop_string(cx, -1, key);
+}
+
+static duk_ret_t js_command_delete(duk_context *cx)
+{
+	const char *key = duk_get_string(cx, 1);
+
+	duk_push_this(cx);
+	return duk_del_prop_string(cx, -1, key);
+}
+
+static const duk_function_list_entry command_handlers[] = {
+	{ "get", js_command_get, 3 },
+	{ "set", js_command_set, 4 },
+	{ "has", js_command_has, 2 },
+	{ "deleteProperty", js_command_delete, 2 },
+	{ NULL, NULL, 0 }
+};
+
+/* The owning object must be at the top of the stack when calling this */
+static void define_command_object(void)
+{
+	duk_del_prop_string(ctx, -1, "command");
+	duk_push_string(ctx, "command"); /* To be used by duk_def_prop() below */
+	duk_push_object(ctx); /* command object */
+	duk_push_object(ctx); /* Handler object */
+	duk_put_function_list(ctx, -1, command_handlers);
+	duk_push_proxy(ctx, 0); /* Stack is now [ "command", proxy ] */
+
+	/* Define the command object in the parent object */
+	duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE);
+}
+
+int js_handle_command(const char *name, int argc, const char **argv)
+{
+	duk_require_stack(ctx, argc + 5);
+	if (!duk_get_global_string(ctx, "mw")) {
+		fprintf(stderr, "mwjs error: failed to lookup mw namespace\n");
+		duk_pop(ctx);
+		return -1;
+	}
+	if (!duk_get_prop_string(ctx, -1, "command")) {
+		fprintf(stderr, "mwjs error: failed to lookup 'mw.command'\n");
+		duk_pop_2(ctx);
+		return -1;
+	}
+	if (!duk_is_object(ctx, -1)) {
+		fprintf(stderr, "mwjs error: 'mw.command' is not an object\n");
+		return -1;
+	}
+	if (!duk_get_prop_string(ctx, -1, name)) {
+		duk_pop_3(ctx);
+		return 1;
+	}
+	if (duk_is_undefined(ctx, -1)) {
+		duk_pop_3(ctx);
+		return 1;
+	}
+	if (!duk_is_function(ctx, -1)) {
+		fprintf(stderr, "mwjs warning: mw.command.%s is not a function.\n", name);
+		duk_pop_3(ctx);
+		return -1;
+	}
+	for (int i = 0; i < argc; i++)
+		duk_push_string(ctx, argv[i]);
+
+	(void)mwjs_call_fn(argc);
+	return 0;
+}
+
 /* The owning object must be at the top of the stack when calling this */
 static void define_func(const char *name, duk_c_function func, int nargs)
 {
@@ -1138,6 +1234,7 @@ static void define_api(void)
 	define_func("termsize", js_termsize, 0);
 	define_func("whoami", js_whoami, 0);
 	define_store_object("store");
+	define_command_object();
 
 	/* mw object */
 	duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE);


=====================================
src/client/js.h
=====================================
--- a/src/client/js.h
+++ b/src/client/js.h
@@ -12,6 +12,7 @@ void js_stop_execution(void);
 int stop_js(void);
 int setup_js(void);
 int js_handle_event(struct mwevent *ev);
+int js_handle_command(const char *name, int argc, const char **argv);
 
 enum bindtype {
 	K_BIND = 0,


=====================================
src/client/script.c
=====================================
--- a/src/client/script.c
+++ b/src/client/script.c
@@ -661,6 +661,8 @@ void DoScript(char *line)
 
 	if ((num=ParseLine(line, bits))<1) return;
 
+	if (js_handle_command(bits[0], num - 1, &bits[1]) == 0)
+		return;
 	if ((function_name = FindLinks(bind_list, bits[0])) == NULL) {
 		printf("Script bind '%s' not found.\n", bits[0]);
 		return;



View it on GitLab: https://projects.sucs.org/arthur/mw/commit/eefe9cc5f525a6f2e2612b1d36d7c5251a1576a2

-- 
View it on GitLab: https://projects.sucs.org/arthur/mw/commit/eefe9cc5f525a6f2e2612b1d36d7c5251a1576a2
You're receiving this email because of your account on projects.sucs.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sucs.org/pipermail/mw-devel/attachments/20181103/9312dab4/attachment-0001.html>


More information about the mw-devel mailing list