[script] Rationalize function calls and callbacks

Allows script functions to be executed without extracting the body of the
function and executing that. This makes implementing callbacks simpler and
enables passing of parameters.
This commit is contained in:
Charlie Brej 2009-06-25 11:25:12 +01:00 committed by Ray Strode
parent 0892d0c66a
commit 9af3a9d3db
8 changed files with 115 additions and 53 deletions

View file

@ -157,13 +157,8 @@ on_timeout (ply_boot_splash_plugin_t *plugin)
now = ply_get_timestamp ();
if (plugin->script_plymouth_lib->script_refresh_func){
script_state* sub_state = script_state_init_sub(plugin->script_state);
script_return ret = script_execute(sub_state, plugin->script_plymouth_lib->script_refresh_func->data.function->data.script); // FIXME too many redirections
if (ret.object) script_obj_unref(ret.object); // Throw anything sent back away
script_state_destroy(sub_state);
}
script_lib_sprite_refresh(plugin->script_sprite_lib);
script_lib_plymouth_on_refresh(plugin->script_state, plugin->script_plymouth_lib);
script_lib_sprite_refresh(plugin->script_sprite_lib);
sleep_time = 1.0 / FRAMES_PER_SECOND;
ply_event_loop_watch_for_timeout (plugin->loop,

View file

@ -4,6 +4,7 @@
#include "ply-list.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>
#include <assert.h>
#include <stdbool.h>
@ -16,6 +17,7 @@
#include "script-object.h"
static script_obj* script_evaluate (script_state* state, script_exp* exp);
static script_return script_execute_function_with_parlist (script_state* state, script_function* function, ply_list_t* parameter_data);
static script_obj* script_evaluate_plus (script_state* state, script_exp* exp)
{
@ -626,7 +628,6 @@ static script_obj* script_evaluate_unary (script_state* state, script_exp* exp)
static script_obj* script_evaluate_func (script_state* state, script_exp* exp)
{
script_state localstate;
script_obj* func = script_evaluate (state, exp->data.function.name);
script_obj* obj = NULL;
script_obj_deref (&func);
@ -634,54 +635,33 @@ static script_obj* script_evaluate_func (script_state* state, script_exp* exp)
if (func->type != SCRIPT_OBJ_TYPE_FUNCTION)
return script_obj_new_null ();
localstate = *state;
localstate.local = script_obj_new_hash();
ply_list_t* parameter_expressions = exp->data.function.parameters;
ply_list_t* parameter_data = ply_list_new();
ply_list_t* parameter_names = func->data.function->parameters;
ply_list_t* parameter_data = exp->data.function.parameters;
ply_list_node_t *node_name = ply_list_get_first_node (parameter_names);
ply_list_node_t *node_data = ply_list_get_first_node (parameter_data);
while (node_name && node_data){
script_exp* data_exp = ply_list_node_get_data (node_data);
char* name = ply_list_node_get_data (node_name);
ply_list_node_t *node_expression = ply_list_get_first_node (parameter_expressions);
while (node_expression){
script_exp* data_exp = ply_list_node_get_data (node_expression);
script_obj* data_obj = script_evaluate (state, data_exp);
script_vareable* vareable = malloc(sizeof(script_vareable));
vareable->name = strdup(name);
vareable->object = data_obj;
ply_hashtable_insert (localstate.local->data.hash, vareable->name, vareable);
node_name = ply_list_get_next_node (parameter_names, node_name);
node_data = ply_list_get_next_node (parameter_data, node_data);
ply_list_append_data (parameter_data, data_obj);
node_expression = ply_list_get_next_node (parameter_expressions, node_expression);
}
script_return reply;
switch (func->data.function->type){
case SCRIPT_FUNCTION_TYPE_SCRIPT:
{
script_op* op = func->data.function->data.script;
reply = script_execute (&localstate, op);
break;
}
case SCRIPT_FUNCTION_TYPE_NATIVE:
{
reply = func->data.function->data.native (&localstate, func->data.function->user_data);
break;
}
}
script_obj_unref (localstate.local);
script_obj_unref (func);
script_return reply = script_execute_function_with_parlist (state, func->data.function, parameter_data);
if (reply.type == SCRIPT_RETURN_TYPE_RETURN)
obj = reply.object;
if (!obj){
obj = script_obj_new_null ();
else
obj = script_obj_new_null();
ply_list_node_t *node_data = ply_list_get_first_node (parameter_data);
while (node_data){
script_obj* data_obj = ply_list_node_get_data (node_data);
script_obj_unref (data_obj);
node_data = ply_list_get_next_node (parameter_data, node_data);
}
ply_list_free(parameter_data);
script_obj_unref (func);
return obj;
}
@ -801,6 +781,66 @@ static script_return script_execute_list (script_state* state, ply_list_t* op_li
return reply;
}
// parameter_data list should be freed by caller
static script_return script_execute_function_with_parlist (script_state* state, script_function* function, ply_list_t* parameter_data)
{
script_state* sub_state = script_state_init_sub(state);
ply_list_t* parameter_names = function->parameters;
ply_list_node_t *node_name = ply_list_get_first_node (parameter_names);
ply_list_node_t *node_data = ply_list_get_first_node (parameter_data);
while (node_name && node_data){
script_obj* data_obj = ply_list_node_get_data (node_data);
char* name = ply_list_node_get_data (node_name);
script_obj_hash_add_element (sub_state->local, data_obj, name);
node_name = ply_list_get_next_node (parameter_names, node_name);
node_data = ply_list_get_next_node (parameter_data, node_data);
}
script_return reply;
switch (function->type){
case SCRIPT_FUNCTION_TYPE_SCRIPT:
{
script_op* op = function->data.script;
reply = script_execute (sub_state, op);
break;
}
case SCRIPT_FUNCTION_TYPE_NATIVE:
{
reply = function->data.native (sub_state, function->user_data);
break;
}
}
script_state_destroy(sub_state);
return reply;
}
script_return script_execute_function (script_state* state, script_function* function, script_obj* first_arg, ...)
{
script_return reply;
va_list args;
script_obj* arg;
ply_list_t *parameter_data = ply_list_new();
arg = first_arg;
va_start (args, first_arg);
while (arg){
ply_list_append_data (parameter_data, arg);
arg = va_arg (args, script_obj*);
}
va_end (args);
reply = script_execute_function_with_parlist (state, function, parameter_data);
ply_list_free(parameter_data);
return reply;
}
script_return script_execute (script_state* state, script_op* op)
{

View file

@ -4,6 +4,6 @@
#include "script.h"
script_return script_execute (script_state* state, script_op* op);
script_return script_execute_function (script_state* state, script_function* function, script_obj* first_arg, ...);
#endif /* SCRIPT_EXECUTE_H */

View file

@ -2,6 +2,7 @@
#include "ply-image.h"
#include "ply-utils.h"
#include "script.h"
#include "script-parse.h"
#include "script-object.h"
#include "script-parse.h"
#include "script-execute.h"

View file

@ -1,6 +1,7 @@
#define _GNU_SOURCE
#include "ply-utils.h"
#include "script.h"
#include "script-parse.h"
#include "script-execute.h"
#include "script-object.h"
#include "script-lib-math.h"

View file

@ -1,6 +1,7 @@
#define _GNU_SOURCE
#include "ply-utils.h"
#include "script.h"
#include "script-parse.h"
#include "script-execute.h"
#include "script-object.h"
#include "script-lib-plymouth.h"
@ -18,12 +19,20 @@
static script_return plymouth_set_refresh (script_state* state, void* user_data)
{
script_lib_plymouth_data_t* data = user_data;
script_obj** script_func = user_data;
script_obj* obj = script_obj_hash_get_element (state->local, "function");
script_obj_deref(&obj);
if (*script_func)
script_obj_unref(*script_func);
if (obj->type == SCRIPT_OBJ_TYPE_FUNCTION){
data->script_refresh_func = obj;
*script_func = obj;
}
else {
*script_func = NULL;
script_obj_unref(obj);
}
return (script_return){SCRIPT_RETURN_TYPE_RETURN, script_obj_new_null ()};
}
@ -34,7 +43,7 @@ script_lib_plymouth_data_t* script_lib_plymouth_setup(script_state *state)
data->script_refresh_func = NULL;
script_add_native_function (state->global, "PlymouthSetRefreshFunction", plymouth_set_refresh, data, "function", NULL);
script_add_native_function (state->global, "PlymouthSetRefreshFunction", plymouth_set_refresh, &data->script_refresh_func, "function", NULL);
data->script_main_op = script_parse_string (script_lib_plymouth_string);
script_return ret = script_execute(state, data->script_main_op);
if (ret.object) script_obj_unref(ret.object); // Throw anything sent back away
@ -49,3 +58,16 @@ void script_lib_plymouth_destroy(script_lib_plymouth_data_t* data)
script_obj_unref(data->script_refresh_func);
free(data);
}
void script_lib_plymouth_on_refresh(script_state* state, script_lib_plymouth_data_t* data)
{
script_obj* refresh_func_obj = data->script_refresh_func;
if (refresh_func_obj && refresh_func_obj->type == SCRIPT_OBJ_TYPE_FUNCTION){
script_return ret = script_execute_function (state, data->script_refresh_func->data.function, NULL);
if (ret.object) script_obj_unref(ret.object); // Throw anything sent back away
}
}

View file

@ -13,4 +13,6 @@ typedef struct
script_lib_plymouth_data_t* script_lib_plymouth_setup(script_state *state);
void script_lib_plymouth_destroy(script_lib_plymouth_data_t* data);
void script_lib_plymouth_on_refresh(script_state* state, script_lib_plymouth_data_t* data);
#endif /* SCRIPT_LIB_PLYMOUTH */

View file

@ -4,6 +4,7 @@
#include "ply-logger.h"
#include "ply-key-file.h"
#include "script.h"
#include "script-parse.h"
#include "script-execute.h"
#include "script-object.h"
#include "script-lib-image.h"