an ongoing lua cleanup. existing lua is there and works for the most part.

but it could be much much much cleaner/better so i started a minimalist redo.
it's temporarily enabled right now. will disable soon to do in the background.



SVN revision: 47782
This commit is contained in:
Carsten Haitzler 2010-04-06 11:26:32 +00:00
parent 62b6d186cd
commit 8babebf48e
8 changed files with 556 additions and 7 deletions

View File

@ -24,6 +24,7 @@ edje_callbacks.c \
edje_data.c \
edje_embryo.c \
edje_lua.c \
edje_lua2.c \
edje_load.c \
edje_main.c \
edje_misc.c \

View File

@ -96,6 +96,9 @@ _edje_file_coll_open(Edje_File *edf, const char *coll)
if (data)
{
#ifdef LUA2
_edje_lua2_script_load(edc, data, size);
#else
int err_code;
//printf("lua chunk size: %d\n", size);
@ -110,6 +113,7 @@ _edje_file_coll_open(Edje_File *edf, const char *coll)
}
if (lua_pcall(_edje_lua_state_get(), 0, 0, 0))
ERR("lua call error: %s", lua_tostring(_edje_lua_state_get(), -1));
#endif
free(data);
}

View File

@ -886,6 +886,9 @@ _edje_file_del(Edje *ed)
if (rp->custom)
{
#ifdef LUA2
// xxx: lua2
#else
if (ed->L)
{
_edje_lua_get_reg(ed->L, rp->custom->description);
@ -893,6 +896,7 @@ _edje_file_del(Edje *ed)
lua_pop(ed->L, 1);
_edje_lua_free_reg(ed->L, rp->custom->description); // created in edje_lua.c::_edje_lua_part_fn_custom_state
}
#endif
_edje_collection_free_part_description_free(rp->custom->description, ed->file->free_strings);
}
@ -949,10 +953,14 @@ _edje_file_del(Edje *ed)
}
if (ed->L)
{
#ifdef LUA2
_edje_lua2_script_shutdown(ed);
#else
_edje_lua_free_reg(ed->L, ed); // created in edje_lua.c::_edje_lua_script_fn_new/_edje_lua_group_fn_new
_edje_lua_free_reg(ed->L, ed->L); // created in edje_program.c::_edje_program_run/edje_lua_script_only.c::_edje_lua_script_only_init
_edje_lua_free_thread(ed, ed->L); // created in edje_program.c::_edje_program_run/edje_lua_script_only.c::_edje_lua_script_only_init
ed->L = NULL;
#endif
}
if (ed->table_parts) free(ed->table_parts);
ed->table_parts = NULL;
@ -1154,6 +1162,7 @@ _edje_collection_free(Edje_File *edf, Edje_Part_Collection *ec)
}
#endif
if (ec->script) embryo_program_free(ec->script);
_edje_lua2_script_unload(ec);
free(ec);
}

View File

@ -4953,11 +4953,41 @@ static int
_edje_lua_group_fn_timer(lua_State *L)
{
Edje_Lua_Timer *tar = lua_newuserdata(L, sizeof(Edje_Lua_Timer));
_edje_lua_set_class(L, -1, cTimer);
/* ^^^^^^^^^^^^^^^^(L, index, class)
lua_newtable(L);
if (index < 0)
lua_setfenv(L, index - 1);
else
lua_setfenv(L, index);
_edje_lua_get_metatable(L, class);
if (index < 0)
lua_setmetatable(L, index - 1);
else
lua_setmetatable(L, index);
*/
tar->et = ecore_timer_add(luaL_checknumber(L, 2), _edje_lua_timer_cb, tar);
tar->L = L;
_edje_lua_new_reg(L, -1, tar); // freed in _edje_lua_timer_cb/del
/* ^^^^^^^^^^^^^^(L, index, ptr)
lua_pushvalue(L, index);
lua_pushlightuserdata(L, ptr);
lua_insert(L, -2);
lua_rawset(L, LUA_REGISTRYINDEX); // freed in _edje_lua_free_reg
*/
tar->cb = _edje_lua_new_ref(L, 3); // freed in _edje_lua_timer_cb/del
/* ^^^^^^^^^^^^^^^^^^^^^^^^(L, index)
lua_pushvalue(L, index);
Edje_Lua_Ref *ref = malloc(sizeof(Edje_Lua_Ref));
ref->id = luaL_ref(L, LUA_REGISTRYINDEX);
ref->L = L;
return ref;
*/
return 1;
}
@ -5578,7 +5608,7 @@ _edje_lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
}
if (nsize == 0)
{
free(ptr); /* ANSI requires that free(NULL) has no effect */
free(ptr); /* ANSI requires that free(NULL) has no effect */
return NULL;
}

View File

@ -0,0 +1,434 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <string.h>
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#elif defined __GNUC__
# define alloca __builtin_alloca
#elif defined _AIX
# define alloca __alloca
#elif defined _MSC_VER
# include <malloc.h>
# define alloca _alloca
#else
# include <stddef.h>
# ifdef __cplusplus
extern "C"
# endif
void *alloca(size_t);
#endif
#include "edje_private.h"
//--------------------------------------------------------------------------//
#ifdef LUA2
#define MAX_LUA_MEM (4 * (1024 * 1024))
//--------------------------------------------------------------------------//
typedef struct _Edje_Lua_Alloc Edje_Lua_Alloc;
typedef struct _Edje_Lua_Obj Edje_Lua_Obj;
typedef struct _Edje_Lua_Timer Edje_Lua_Timer;
typedef struct _Edje_Lua_Anim Edje_Lua_Anim;
//--------------------------------------------------------------------------//
struct _Edje_Lua_Alloc
{
size_t max, cur;
};
struct _Edje_Lua_Obj
{
EINA_INLIST;
Edje *ed;
void (*free_func) (void *obj);
};
struct _Edje_Lua_Timer
{
Edje_Lua_Obj obj;
Ecore_Timer *timer;
int fn_ref;
};
struct _Edje_Lua_Anim
{
Edje_Lua_Obj obj;
Ecore_Animator *anim;
int fn_ref;
};
//--------------------------------------------------------------------------//
static int _elua_obj_gc(lua_State *L);
static int _elua_obj_del(lua_State *L);
static int _elua_echo(lua_State *L);
static int _elua_timer(lua_State *L);
static int _elua_anim(lua_State *L);
//--------------------------------------------------------------------------//
static lua_State *lstate = NULL;
static const struct luaL_reg _elua_edje_api [] =
{
{"echo", _elua_echo}, // test func - echo (i know we have print. test)
{"del", _elua_obj_del}, // generic del any object created for edje
{"timer", _elua_timer}, // add timer
{"anim", _elua_anim}, // add animator (not done yet)
{NULL, NULL} // end
};
static const struct luaL_reg _elua_edje_meta [] =
{
{"__gc", _elua_obj_gc}, // garbage collector func for edje objects
{NULL, NULL} // end
};
static const luaL_Reg _elua_libs[] =
{
{"", luaopen_base},
// {LUA_LOADLIBNAME, luaopen_package}, // disable this lib - don't want
{LUA_TABLIBNAME, luaopen_table},
// {LUA_IOLIBNAME, luaopen_io}, // disable this lib - don't want
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
// {LUA_DBLIBNAME, luaopen_debug}, // disable this lib - don't want
{NULL, NULL} // end
};
static const char *_elua_key = "key";
//--------------------------------------------------------------------------//
static void *
_elua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
Edje_Lua_Alloc *ela = ud;
void *ptr2;
ela->cur += nsize - osize;
if (ela->cur > ela->max)
{
ERR("Edje Lua memory limit of %zu bytes reached (%zu allocated)",
ela->max, ela->cur);
return NULL;
}
if (nsize == 0)
{
free(ptr);
return NULL;
}
ptr2 = realloc(ptr, nsize);
if (ptr2) return ptr2;
ERR("Edje Lua cannot re-allocate %i bytes\n", nsize);
return ptr2;
}
static int
_elua_custom_panic(lua_State *L)
{
ERR("Lua Panic!!!!");
return 1;
}
//-------------
void
_edje_lua2_error_full(const char *file, const char *fnc, int line,
lua_State *L, int err_code)
{
char *err_type;
switch (err_code)
{
case LUA_ERRRUN:
err_type = "runtime";
break;
case LUA_ERRSYNTAX:
err_type = "syntax";
break;
case LUA_ERRMEM:
err_type = "memory allocation";
break;
case LUA_ERRERR:
err_type = "error handler";
break;
default:
err_type = "unknown";
break;
}
eina_log_print
(_edje_default_log_dom, EINA_LOG_LEVEL_ERR, file, fnc, line,
"Lua %s error: %s", err_type, lua_tostring(L, -1));
}
static void
_elua_init(void)
{
static Edje_Lua_Alloc ela = { MAX_LUA_MEM, 0 };
const luaL_Reg *l;
if (lstate) return;
lstate = lua_newstate(_elua_alloc, &ela); //0
lua_atpanic(lstate, _elua_custom_panic); //0
// FIXME: figure out optimal gc settings later
// lua_gc(lstate, LUA_GCSETPAUSE, 200); //0
// lua_gc(lstate, LUA_GCSETSTEPMUL, 200); //0
for (l = _elua_libs; l->func; l++)
{
lua_pushcfunction(lstate, l->func);
lua_pushstring(lstate, l->name);
lua_call(lstate, 1, 0);
}
luaL_register(lstate, "edje", _elua_edje_api); //+1
luaL_newmetatable(lstate, "edje"); //+1
luaL_register(lstate, 0, _elua_edje_meta); //0
lua_pushliteral(lstate, "__index"); //+1
lua_pushvalue(lstate, -3); //+1
lua_rawset(lstate, -3); //-2
lua_pop(lstate, 2);
}
//-------------
static void
_elua_table_ptr_set(lua_State *L, const void *key, const void *val)
{
lua_pushlightuserdata(L, (void *)key); //+1
lua_pushlightuserdata(L, (void *)val); //+1
lua_settable(L, LUA_REGISTRYINDEX); //-2
}
static const void *
_elua_table_ptr_get(lua_State *L, const void *key)
{
const void *ptr;
lua_pushlightuserdata(L, (void *)key); //+1
lua_gettable(L, LUA_REGISTRYINDEX); //0
ptr = lua_topointer(L, -1); //0
lua_pop(L, 1);
return ptr;
}
static void
_elua_table_ptr_del(lua_State *L, const void *key)
{
lua_pushlightuserdata(L, (void *)key); //+1
lua_pushnil(L); //+1
lua_settable(L, LUA_REGISTRYINDEX); //-2
}
static void
_elua_gc(lua_State *L)
{
lua_gc(L, LUA_GCCOLLECT, 0); //0
}
//-------------
static Edje_Lua_Obj *
_elua_obj_new(lua_State *L, Edje *ed, int size)
{
Edje_Lua_Obj *obj;
obj = (Edje_Lua_Obj *)lua_newuserdata(L, size); //+1
memset(obj, 0, size);
ed->lua_objs = eina_inlist_append(ed->lua_objs, EINA_INLIST_GET(obj));
luaL_getmetatable(L, "edje"); //+1
lua_setmetatable(L, -2); //-1
obj->ed = ed;
return obj;
}
static void
_elua_obj_free(lua_State *L, Edje_Lua_Obj *obj)
{
if (!obj->free_func) return;
obj->free_func(obj);
obj->ed->lua_objs = eina_inlist_remove(obj->ed->lua_objs, EINA_INLIST_GET(obj));
obj->free_func = NULL;
obj->ed = NULL;
}
//-------------
static int
_elua_obj_gc(lua_State *L)
{
Edje_Lua_Obj *obj = (Edje_Lua_Obj *)lua_touserdata(L, 1);
if (!obj) return 0;
_elua_obj_free(L, obj);
return 0;
}
static int
_elua_obj_del(lua_State *L)
{
return _elua_obj_gc(L);
}
//-------------
static int
_elua_echo(lua_State *L)
{
const char *string = luaL_checkstring(L, 1); //0
printf("%s\n", string);
return 1;
}
//-------------
static int
_elua_timer_cb(void *data)
{
Edje_Lua_Timer *elt = data;
int ret = 0;
int err;
if (!elt->obj.ed) return 0;
lua_rawgeti(lstate, LUA_REGISTRYINDEX, elt->fn_ref); //+1
if ((err = lua_pcall(lstate, 0, 1, 0))) //+1
{
_edje_lua2_error(lstate, err); //0
_elua_obj_free(lstate, (Edje_Lua_Obj *)elt);
_elua_gc(lstate);
return 0;
}
ret = luaL_checkint(lstate, -1); //0
lua_pop(lstate, 1);
if (ret == 0)
_elua_obj_free(lstate, (Edje_Lua_Obj *)elt);
_elua_gc(lstate);
return ret;
}
static void
_elua_timer_free(void *obj)
{
Edje_Lua_Timer *elt = (Edje_Lua_Timer *)obj;
luaL_unref(lstate, LUA_REGISTRYINDEX, elt->fn_ref); //0
elt->fn_ref = 0;
ecore_timer_del(elt->timer);
elt->timer = NULL;
}
static int
_elua_timer(lua_State *L)
{
Edje *ed = (Edje *)_elua_table_ptr_get(L, _elua_key);
Edje_Lua_Timer *elt;
double val;
val = luaL_checknumber(L, 1);
luaL_checkany(L, 2);
elt = (Edje_Lua_Timer *)_elua_obj_new(L, ed, sizeof(Edje_Lua_Timer)); //+1
elt->obj.free_func = _elua_timer_free;
elt->timer = ecore_timer_add(val, _elua_timer_cb, elt);
lua_pushvalue(L, 2); //+1
elt->fn_ref = luaL_ref(L, LUA_REGISTRYINDEX);
// lua_pop(ed->L, 2); // don't pop - return back to lua
_elua_gc(lstate);
return 1;
}
//-------------
static int
_elua_anim(lua_State *L)
{
// xxxxx
// not done yet - but do like timer (but 1 arg only - no timeout val)
// xxxxx
Edje *ed = (Edje *)_elua_table_ptr_get(L, _elua_key);
return 1;
}
//-------------
void
_edje_lua2_script_init(Edje *ed)
{
if (ed->L) return;
_elua_init();
ed->L = lstate;
lua_newtable(ed->L); //+1
ed->lua_ref = luaL_ref(ed->L, LUA_REGISTRYINDEX); //+1
// lua_pushvalue(ed->L, LUA_GLOBALSINDEX);
// lua_setfield(ed->L, -2, "__index");
// lua_setmetatable(ed->L, -2);
// lua_setfenv(ed->L, -2);
_elua_table_ptr_set(ed->L, _elua_key, ed); //0
// lua_pop(ed->L, 1); // our current script stack anyway
}
void
_edje_lua2_script_shutdown(Edje *ed)
{
if (!ed->L) return;
lua_getfenv(ed->L, -1);
lua_pushnil(ed->L);
luaL_unref(ed->L, LUA_REGISTRYINDEX, ed->lua_ref); //0
lua_gc(ed->L, LUA_GCCOLLECT, 0); //0
while (ed->lua_objs)
{
Edje_Lua_Obj *obj = (Edje_Lua_Obj *)ed->lua_objs;
if (obj->free_func)
{
ERR("uncollected Lua object %p", obj);
_elua_obj_free(ed->L, obj);
}
else
{
ERR("dangling Lua object %p", obj);
ed->lua_objs = eina_inlist_remove(ed->lua_objs, ed->lua_objs);
}
}
ed->L = NULL;
}
void
_edje_lua2_script_load(Edje_Part_Collection *edc, void *data, int size)
{
int err;
_elua_init();
err = luaL_loadbuffer(lstate, data, size, "edje_lua_script"); //+1
if (err)
{
if (err == LUA_ERRSYNTAX)
ERR("lua load syntax error: %s", lua_tostring(lstate, -1)); //0
else if (err == LUA_ERRMEM)
ERR("lua load memory allocation error: %s", lua_tostring(lstate, -1)); //0
}
if ((err = lua_pcall(lstate, 0, 0, 0))) //0
_edje_lua2_error(lstate, err); //0
}
void
_edje_lua2_script_unload(Edje_Part_Collection *edc)
{
lua_gc(lstate, LUA_GCCOLLECT, 0); //0
}
#endif

View File

@ -26,7 +26,7 @@ void *alloca(size_t);
#include "edje_private.h"
Eina_Bool
_edje_lua_script_only(Edje * ed)
_edje_lua_script_only(Edje *ed)
{
if ((ed->collection) && (ed->collection->lua_script_only))
return EINA_TRUE;
@ -34,10 +34,26 @@ _edje_lua_script_only(Edje * ed)
}
void
_edje_lua_script_only_init(Edje * ed)
_edje_lua_script_only_init(Edje *ed)
{
if (ed->collection)
{
#ifdef LUA2
int err;
_edje_lua2_script_init(ed);
if (ed->L)
{
lua_getglobal(ed->L, "init");
if (!lua_isnil(ed->L, -1))
{
if ((err = lua_pcall(ed->L, 0, 0, 0)))
_edje_lua2_error(ed->L, err);
}
else
lua_pop(ed->L, 1);
}
#else
ed->L = _edje_lua_new_thread(ed, _edje_lua_state_get()); // freed in _edje_lua_script_only_shutdown
_edje_lua_new_reg(ed->L, -1, ed->L); // freed in _edje_lua_script_only_shutdown
lua_pop(ed->L, 1); /* thread */
@ -60,14 +76,31 @@ _edje_lua_script_only_init(Edje * ed)
}
else
lua_pop(L, 1);
#endif
}
}
void
_edje_lua_script_only_shutdown(Edje * ed)
_edje_lua_script_only_shutdown(Edje *ed)
{
if (ed->collection && ed->L)
{
#ifdef LUA2
int err;
if (ed->L)
{
lua_getglobal(ed->L, "shutdown");
if (!lua_isnil(ed->L, -1))
{
if ((err = lua_pcall(ed->L, 0, 0, 0)))
_edje_lua2_error(ed->L, err);
}
else
lua_pop(ed->L, 1);
}
_edje_lua2_script_shutdown(ed);
#else
lua_State *L = ed->L;
lua_getglobal(L, "shutdown");
if (!lua_isnil (L, -1))
@ -83,12 +116,15 @@ _edje_lua_script_only_shutdown(Edje * ed)
}
else
lua_pop (L, 1);
#endif
}
}
void
_edje_lua_script_only_show(Edje * ed)
{
#ifdef LUA2
#else
if (ed->collection && ed->L)
{
lua_State *L = ed->L;
@ -107,11 +143,14 @@ _edje_lua_script_only_show(Edje * ed)
else
lua_pop (L, 1);
}
#endif
}
void
_edje_lua_script_only_hide(Edje * ed)
{
#ifdef LUA2
#else
if (ed->collection && ed->L)
{
lua_State *L = ed->L;
@ -130,11 +169,14 @@ _edje_lua_script_only_hide(Edje * ed)
else
lua_pop (L, 1);
}
#endif
}
void
_edje_lua_script_only_move(Edje * ed)
{
#ifdef LUA2
#else
if (ed->collection && ed->L)
{
lua_State *L = ed->L;
@ -155,11 +197,14 @@ _edje_lua_script_only_move(Edje * ed)
else
lua_pop (L, 1);
}
#endif
}
void
_edje_lua_script_only_resize(Edje * ed)
{
#ifdef LUA2
#else
if (ed->collection && ed->L)
{
lua_State *L = ed->L;
@ -180,11 +225,14 @@ _edje_lua_script_only_resize(Edje * ed)
else
lua_pop (L, 1);
}
#endif
}
void
_edje_lua_script_only_message(Edje * ed, Edje_Message * em)
{
#ifdef LUA2
#else
if (ed->collection && ed->L)
{
lua_State *L = ed->L;
@ -291,5 +339,6 @@ _edje_lua_script_only_message(Edje * ed, Edje_Message * em)
else
lua_pop (L, 1);
}
#endif
}

View File

@ -23,6 +23,7 @@
#include "Edje_Edit.h"
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <setjmp.h>
@ -532,7 +533,7 @@ struct _Edje_Part_Collection
unsigned char script_only;
unsigned char lua_script_only;
unsigned char lua_script_only;
};
struct _Edje_Part
@ -845,6 +846,7 @@ struct _Edje
unsigned int have_mapped_part : 1;
lua_State *L;
Eina_Inlist *lua_objs;
int lua_ref;
};
@ -1555,4 +1557,21 @@ void _edje_external_parsed_params_free(Evas_Object *obj, void *params);
void _edje_module_init();
void _edje_module_shutdown();
#define LUA2 1
void _edje_lua2_error_full(const char *file, const char *fnc, int line, lua_State *L, int err_code);
#define _edje_lua2_error(L, err_code) _edje_lua2_error_full(__FILE__, __FUNCTION__, __LINE__, L, err_code)
void _edje_lua2_script_init(Edje *ed);
void _edje_lua2_script_shutdown(Edje *ed);
void _edje_lua2_script_load(Edje_Part_Collection *edc, void *data, int size);
void _edje_lua2_script_unload(Edje_Part_Collection *edc);
#endif

View File

@ -844,7 +844,10 @@ _edje_program_run(Edje *ed, Edje_Program *pr, Eina_Bool force, const char *ssig,
// _edje_emit(ed, "program,start", pr->name);
if (_edje_block_break(ed)) goto break_prog;
#ifdef LUA2
_edje_lua2_script_init(ed);
#else
if (ed->L == NULL) /* private state does not yet exist, create it */
{
ed->L = _edje_lua_new_thread(ed, _edje_lua_state_get());
@ -870,7 +873,7 @@ _edje_program_run(Edje *ed, Edje_Program *pr, Eina_Bool force, const char *ssig,
if ((err_code = lua_pcall(L, 3, 0, 0)))
_edje_lua_error(L, err_code);
}
#endif
// _edje_emit(ed, "program,stop", pr->name);
if (_edje_block_break(ed)) goto break_prog;
_edje_recalc_do(ed);