X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Flua%2Flibs%2Fvariables.c;h=e1d06070764e7120343a2d799a3f23d8d76891d2;hb=d00d1822a13a2d1c38b06627223907e76bc28748;hp=1e6e409032563c166ce1bdac6bb2d037cb511406;hpb=e292947855ae11068c34a1e27dbf919e3abc85c6;p=vlc diff --git a/modules/lua/libs/variables.c b/modules/lua/libs/variables.c index 1e6e409032..e1d0607076 100644 --- a/modules/lua/libs/variables.c +++ b/modules/lua/libs/variables.c @@ -34,10 +34,6 @@ #include -#include /* Low level lua C API */ -#include /* Higher level C API */ -#include /* Lua libs */ - #include "../vlc.h" #include "../libs.h" #include "variables.h" @@ -75,9 +71,6 @@ static int vlclua_pushvalue( lua_State *L, int i_type, vlc_value_t val, bool b_e case VLC_VAR_ADDRESS: vlclua_error( L ); break; - case VLC_VAR_MUTEX: - vlclua_error( L ); - break; default: vlclua_error( L ); } @@ -127,15 +120,33 @@ static int vlclua_tovalue( lua_State *L, int i_type, vlc_value_t *val ) case VLC_VAR_ADDRESS: vlclua_error( L ); break; - case VLC_VAR_MUTEX: - vlclua_error( L ); - break; default: vlclua_error( L ); } return 1; } +static int vlclua_var_inherit( lua_State *L ) +{ + vlc_value_t val; + vlc_object_t *p_obj; + if( lua_type( L, 1 ) == LUA_TNIL ) + p_obj = vlclua_get_this( L ); + else + { + vlc_object_t **pp_obj = luaL_checkudata( L, 1, "vlc_object" ); + p_obj = *pp_obj; + } + const char *psz_var = luaL_checkstring( L, 2 ); + + int i_type = config_GetType( p_obj, psz_var ); + if( var_Inherit( p_obj, psz_var, i_type, &val ) != VLC_SUCCESS ) + return 0; + + lua_pop( L, 2 ); + return vlclua_pushvalue( L, i_type, val, true ); +} + static int vlclua_var_get( lua_State *L ) { vlc_value_t val; @@ -219,29 +230,6 @@ static int vlclua_var_get_list( lua_State *L ) return 2; } -static int vlclua_command( lua_State *L ) -{ - vlc_object_t * p_this = vlclua_get_this( L ); - char *psz_msg; - - const char *psz_name = luaL_checkstring( L, 1 ); - const char *psz_cmd = luaL_checkstring( L, 2 ); - const char *psz_arg = luaL_checkstring( L, 3 ); - int ret = var_Command( p_this, psz_name, psz_cmd, psz_arg, &psz_msg ); - lua_pop( L, 3 ); - - if( psz_msg ) - { - lua_pushstring( L, psz_msg ); - free( psz_msg ); - } - else - { - lua_pushliteral( L, "" ); - } - return vlclua_push_ret( L, ret ) + 1; -} - static int vlclua_libvlc_command( lua_State *L ) { vlc_object_t * p_this = vlclua_get_this( L ); @@ -304,268 +292,6 @@ static inline const void *luaL_checklightuserdata( lua_State *L, int narg ) return lua_topointer( L, narg ); } -typedef struct -{ - int i_index; - int i_type; - lua_State *L; -} vlclua_callback_t; - -static int vlclua_callback( vlc_object_t *p_this, char const *psz_var, - vlc_value_t oldval, vlc_value_t newval, - void *p_data ) -{ - vlclua_callback_t *p_callback = (vlclua_callback_t*)p_data; - lua_State *L = p_callback->L; - - /* */ - lua_getglobal( L, "vlc" ); - /* vlc */ - lua_getfield( L, -1, "callbacks" ); - /* vlc callbacks */ - lua_remove( L, -2 ); - /* callbacks */ - lua_pushinteger( L, p_callback->i_index ); - /* callbacks index */ - lua_gettable( L, -2 ); - /* callbacks callbacks[index] */ - lua_remove( L, -2 ); - /* callbacks[index] */ - lua_getfield( L, -1, "callback" ); - /* callbacks[index] callback */ - lua_pushstring( L, psz_var ); - /* callbacks[index] callback var */ - vlclua_pushvalue( L, p_callback->i_type, oldval, false ); - /* callbacks[index] callback var oldval */ - vlclua_pushvalue( L, p_callback->i_type, newval, false ); - /* callbacks[index] callback var oldval newval */ - lua_getfield( L, -5, "data" ); - /* callbacks[index] callback var oldval newval data */ - lua_remove( L, -6 ); - /* callback var oldval newval data */ - - if( lua_pcall( L, 4, 0, 0 ) ) - { - /* errormessage */ - const char *psz_err = lua_tostring( L, -1 ); - msg_Err( p_this, "Error while running lua interface callback: %s", - psz_err ); - /* empty the stack (should only contain the error message) */ - lua_settop( L, 0 ); - return VLC_EGENERIC; - } - - /* empty the stack (should already be empty) */ - lua_settop( L, 0 ); - - return VLC_SUCCESS; -} - -static int vlclua_add_callback( lua_State *L ) -{ - vlclua_callback_t *p_callback; - static int i_index = 0; - vlc_object_t **pp_obj = luaL_checkudata( L, 1, "vlc_object" ); - const char *psz_var = luaL_checkstring( L, 2 ); - lua_settop( L, 4 ); /* makes sure that optional data arg is set */ - if( !lua_isfunction( L, 3 ) ) - return vlclua_error( L ); - - if( !pp_obj || !*pp_obj ) - return vlclua_error( L ); - - int i_type = var_Type( *pp_obj, psz_var ); - - /* Check variable type, in order to avoid PANIC */ - switch( i_type & VLC_VAR_CLASS ) - { - case VLC_VAR_VOID: - case VLC_VAR_BOOL: - case VLC_VAR_INTEGER: - case VLC_VAR_STRING: - case VLC_VAR_FLOAT: - case VLC_VAR_TIME: - break; - case VLC_VAR_ADDRESS: - case VLC_VAR_MUTEX: - default: - return vlclua_error( L ); - } - - i_index++; - - p_callback = (vlclua_callback_t*)malloc( sizeof( vlclua_callback_t ) ); - if( !p_callback ) - return vlclua_error( L ); - - /* obj var func data */ - lua_getglobal( L, "vlc" ); - /* obj var func data vlc */ - lua_getfield( L, -1, "callbacks" ); - if( lua_isnil( L, -1 ) ) - { - lua_pop( L, 1 ); - lua_newtable( L ); - lua_setfield( L, -2, "callbacks" ); - lua_getfield( L, -1, "callbacks" ); - } - /* obj var func data vlc callbacks */ - lua_remove( L, -2 ); - /* obj var func data callbacks */ - lua_pushinteger( L, i_index ); - /* obj var func data callbacks index */ - lua_insert( L, -4 ); - /* obj var index func data callbacks */ - lua_insert( L, -4 ); - /* obj var callbacks index func data */ - lua_createtable( L, 0, 0 ); - /* obj var callbacks index func data cbtable */ - lua_insert( L, -2 ); - /* obj var callbacks index func cbtable data */ - lua_setfield( L, -2, "data" ); - /* obj var callbacks index func cbtable */ - lua_insert( L, -2 ); - /* obj var callbacks index cbtable func */ - lua_setfield( L, -2, "callback" ); - /* obj var callbacks index cbtable */ - lua_pushlightuserdata( L, *pp_obj ); /* will be needed in vlclua_del_callback */ - /* obj var callbacks index cbtable p_obj */ - lua_setfield( L, -2, "private1" ); - /* obj var callbacks index cbtable */ - lua_pushvalue( L, 2 ); /* will be needed in vlclua_del_callback */ - /* obj var callbacks index cbtable var */ - lua_setfield( L, -2, "private2" ); - /* obj var callbacks index cbtable */ - lua_pushlightuserdata( L, p_callback ); /* will be needed in vlclua_del_callback */ - /* obj var callbacks index cbtable p_callback */ - lua_setfield( L, -2, "private3" ); - /* obj var callbacks index cbtable */ - lua_settable( L, -3 ); - /* obj var callbacks */ - lua_pop( L, 3 ); - /* */ - - /* Do not move this before the lua specific code (it somehow changes - * the function in the stack to nil) */ - p_callback->i_index = i_index; - p_callback->i_type = i_type; - p_callback->L = lua_newthread( L ); /* Do we have to keep a reference to this thread somewhere to prevent garbage collection? */ - - var_AddCallback( *pp_obj, psz_var, vlclua_callback, p_callback ); - return 0; -} - -static int vlclua_del_callback( lua_State *L ) -{ - vlclua_callback_t *p_callback; - bool b_found = false; - vlc_object_t **pp_obj = luaL_checkudata( L, 1, "vlc_object" ); - const char *psz_var = luaL_checkstring( L, 2 ); - lua_settop( L, 4 ); /* makes sure that optional data arg is set */ - if( !lua_isfunction( L, 3 ) ) - return vlclua_error( L ); - - /* obj var func data */ - lua_getglobal( L, "vlc" ); - /* obj var func data vlc */ - lua_getfield( L, -1, "callbacks" ); - if( lua_isnil( L, -1 ) ) - return luaL_error( L, "Couldn't find matching callback." ); - /* obj var func data vlc callbacks */ - lua_remove( L, -2 ); - /* obj var func data callbacks */ - lua_pushnil( L ); - /* obj var func data callbacks index */ - while( lua_next( L, -2 ) ) - { - /* obj var func data callbacks index value */ - if( lua_isnumber( L, -2 ) ) - { - lua_getfield( L, -1, "private2" ); - /* obj var func data callbacks index value private2 */ - if( lua_equal( L, 2, -1 ) ) /* var name is equal */ - { - lua_pop( L, 1 ); - /* obj var func data callbacks index value */ - lua_getfield( L, -1, "callback" ); - /* obj var func data callbacks index value callback */ - if( lua_equal( L, 3, -1 ) ) /* callback function is equal */ - { - lua_pop( L, 1 ); - /* obj var func data callbacks index value */ - lua_getfield( L, -1, "data" ); /* callback data is equal */ - /* obj var func data callbacks index value data */ - if( lua_equal( L, 4, -1 ) ) - { - vlc_object_t *p_obj2; - lua_pop( L, 1 ); - /* obj var func data callbacks index value */ - lua_getfield( L, -1, "private1" ); - /* obj var func data callbacks index value private1 */ - p_obj2 = (vlc_object_t*)luaL_checklightuserdata( L, -1 ); - if( p_obj2 == *pp_obj ) /* object is equal */ - { - lua_pop( L, 1 ); - /* obj var func data callbacks index value */ - lua_getfield( L, -1, "private3" ); - /* obj var func data callbacks index value private3 */ - p_callback = (vlclua_callback_t*)luaL_checklightuserdata( L, -1 ); - lua_pop( L, 2 ); - /* obj var func data callbacks index */ - b_found = true; - break; - } - else - { - /* obj var func data callbacks index value private1 */ - lua_pop( L, 1 ); - /* obj var func data callbacks index value */ - } - } - else - { - /* obj var func data callbacks index value data */ - lua_pop( L, 1 ); - /* obj var func data callbacks index value */ - } - } - else - { - /* obj var func data callbacks index value callback */ - lua_pop( L, 1 ); - /* obj var func data callbacks index value */ - } - } - else - { - /* obj var func data callbacks index value private2 */ - lua_pop( L, 1 ); - /* obj var func data callbacks index value */ - } - } - /* obj var func data callbacks index value */ - lua_pop( L, 1 ); - /* obj var func data callbacks index */ - } - if( !b_found ) - /* obj var func data callbacks */ - return luaL_error( L, "Couldn't find matching callback." ); - /* else */ - /* obj var func data callbacks index*/ - - var_DelCallback( *pp_obj, psz_var, vlclua_callback, p_callback ); - free( p_callback ); - - /* obj var func data callbacks index */ - lua_pushnil( L ); - /* obj var func data callbacks index nil */ - lua_settable( L, -3 ); /* delete the callback table entry */ - /* obj var func data callbacks */ - lua_pop( L, 5 ); - /* */ - return 0; -} - static int vlclua_trigger_callback( lua_State *L ) { vlc_object_t **pp_obj = luaL_checkudata( L, 1, "vlc_object" ); @@ -618,14 +344,12 @@ static int vlclua_togglebool( lua_State *L ) * *****************************************************************************/ static const luaL_Reg vlclua_var_reg[] = { + { "inherit", vlclua_var_inherit }, { "get", vlclua_var_get }, { "get_list", vlclua_var_get_list }, { "set", vlclua_var_set }, { "create", vlclua_var_create }, - { "add_callback", vlclua_add_callback }, - { "del_callback", vlclua_del_callback }, { "trigger_callback", vlclua_trigger_callback }, - { "command", vlclua_command }, { "libvlc_command", vlclua_libvlc_command }, { "inc_integer", vlclua_inc_integer }, { "dec_integer", vlclua_dec_integer },