changeset 1177:a7c98f237b03 trunk

[svn] - add general_evaluate which can run arbitrary VM code
author nenolod
date Fri, 08 Jun 2007 11:19:25 -0700
parents 44d28af95a23
children e9b2d21cf078
files ChangeLog src/paranormal/builtins.c src/paranormal/general.c
diffstat 3 files changed, 93 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Jun 08 10:58:23 2007 -0700
+++ b/ChangeLog	Fri Jun 08 11:19:25 2007 -0700
@@ -1,3 +1,11 @@
+2007-06-08 17:58:23 +0000  William Pitcock <nenolod@sacredspiral.co.uk>
+  revision [2546]
+  - i forgot to commit something here
+  
+  trunk/src/paranormal/libcalc/function.c |    4 ++--
+  1 file changed, 2 insertions(+), 2 deletions(-)
+
+
 2007-06-08 17:56:12 +0000  William Pitcock <nenolod@sacredspiral.co.uk>
   revision [2544]
   - libcalc (paranormal virtual evaluation machine): add rand() instruction, global registers (global_reg0-reg99).
--- a/src/paranormal/builtins.c	Fri Jun 08 10:58:23 2007 -0700
+++ b/src/paranormal/builtins.c	Fri Jun 08 11:19:25 2007 -0700
@@ -34,6 +34,7 @@
 DECLARE_ACTUATOR (general_swap);
 DECLARE_ACTUATOR (general_copy);
 DECLARE_ACTUATOR (general_flip);
+DECLARE_ACTUATOR (general_evaluate);
 
 /* **************** misc **************** */
 DECLARE_ACTUATOR (misc_floater);
@@ -81,6 +82,7 @@
   &builtin_general_swap,
   &builtin_general_copy,
   &builtin_general_flip,
+  &builtin_general_evaluate,
   /* **************** misc **************** */
   &builtin_misc_floater,
   /* **************** wave **************** */
--- a/src/paranormal/general.c	Fri Jun 08 10:58:23 2007 -0700
+++ b/src/paranormal/general.c	Fri Jun 08 11:19:25 2007 -0700
@@ -7,6 +7,7 @@
 #include "paranormal.h"
 #include "actuators.h"
 #include "pn_utils.h"
+#include "libcalc/calc.h"
 
 /* **************** general_fade **************** */
 static struct pn_actuator_option_desc general_fade_opts[] =
@@ -309,3 +310,85 @@
   0, general_flip_opts,
   NULL, NULL, general_flip_exec
 };
+
+/* ***************** general_evaluate ***************** */
+
+static struct pn_actuator_option_desc general_evaluate_opts[] =
+{
+  { "init_script", "Script to run on start.", OPT_TYPE_STRING, {sval: "global_reg0 = 27;"} },
+  { "frame_script", "Script to run.", OPT_TYPE_STRING, {sval: "global_reg0 = global_reg0 + 1;"} },
+  { NULL }
+};
+
+struct pn_evaluate_ctx
+{
+  expression_t *expr_on_init, *expr_on_frame;
+  symbol_dict_t *dict;
+  gboolean reset;
+};
+
+static void
+general_evaluate_init(gpointer *data)
+{
+  *data = g_new0(struct pn_evaluate_ctx, 1);
+
+  ((struct pn_evaluate_ctx *)*data)->reset = TRUE;
+}
+
+static void
+general_evaluate_cleanup(gpointer op_data)
+{
+  struct pn_evaluate_ctx *data = (struct pn_evaluate_ctx *) op_data;
+
+  g_return_if_fail(data != NULL);
+
+  if (data->expr_on_init)
+    expr_free(data->expr_on_init);
+
+  if (data->expr_on_frame)
+    expr_free(data->expr_on_frame);
+
+  if (data->dict)
+    dict_free(data->dict);
+
+  if (data)
+    g_free(data);
+}
+
+static void
+general_evaluate_exec(const struct pn_actuator_option *opts,
+                      gpointer op_data)
+{
+  struct pn_evaluate_ctx *data = (struct pn_evaluate_ctx *) op_data;
+
+  if (data->reset)
+    {
+       if (data->dict)
+         dict_free(data->dict);
+
+       data->dict = dict_new();
+
+       if (opts[0].val.sval != NULL);
+         data->expr_on_init = expr_compile_string(opts[0].val.sval, data->dict);
+
+       if (opts[1].val.sval != NULL);
+         data->expr_on_frame = expr_compile_string(opts[1].val.sval, data->dict);
+
+       if (data->expr_on_init != NULL)
+         expr_execute(data->expr_on_init, data->dict);
+
+       data->reset = FALSE;
+    }
+
+  if (data->expr_on_frame != NULL)
+    expr_execute(data->expr_on_frame, data->dict);
+}
+
+struct pn_actuator_desc builtin_general_evaluate =
+{
+  "general_evaluate", "Evalulate VM Code",
+  "Evaluates arbitrary VM code. Does not draw anything.",
+  0, general_evaluate_opts,
+  general_evaluate_init, general_evaluate_cleanup, general_evaluate_exec
+};
+