Commit fe5df3d5 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

lua: remove add_callback and del_callback

add_callback could not work correctly with the (lack of) Lua threading
support. Fortunately, it was not in use.

del_callback depends on add_callback.
parent 1b01c5be
...@@ -315,267 +315,6 @@ static inline const void *luaL_checklightuserdata( lua_State *L, int narg ) ...@@ -315,267 +315,6 @@ static inline const void *luaL_checklightuserdata( lua_State *L, int narg )
return lua_topointer( L, 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;
/* <empty stack> */
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:
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 );
/* <empty stack> */
/* 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 );
/* <empty stack> */
return 0;
}
static int vlclua_trigger_callback( lua_State *L ) static int vlclua_trigger_callback( lua_State *L )
{ {
vlc_object_t **pp_obj = luaL_checkudata( L, 1, "vlc_object" ); vlc_object_t **pp_obj = luaL_checkudata( L, 1, "vlc_object" );
...@@ -633,8 +372,6 @@ static const luaL_Reg vlclua_var_reg[] = { ...@@ -633,8 +372,6 @@ static const luaL_Reg vlclua_var_reg[] = {
{ "get_list", vlclua_var_get_list }, { "get_list", vlclua_var_get_list },
{ "set", vlclua_var_set }, { "set", vlclua_var_set },
{ "create", vlclua_var_create }, { "create", vlclua_var_create },
{ "add_callback", vlclua_add_callback },
{ "del_callback", vlclua_del_callback },
{ "trigger_callback", vlclua_trigger_callback }, { "trigger_callback", vlclua_trigger_callback },
{ "command", vlclua_command }, { "command", vlclua_command },
{ "libvlc_command", vlclua_libvlc_command }, { "libvlc_command", vlclua_libvlc_command },
......
...@@ -399,12 +399,6 @@ var.create( object, name, value ): Create and set the object's variable "name" ...@@ -399,12 +399,6 @@ var.create( object, name, value ): Create and set the object's variable "name"
to "value". Created vars can be of type float, string, bool or void. to "value". Created vars can be of type float, string, bool or void.
For a void variable the value has to be 'nil'. For a void variable the value has to be 'nil'.
var.add_callback( object, name, function, data ): Add a callback to the
object's "name" variable. Callback functions take 4 arguments: the
variable name, the old value, the new value and data.
var.del_callback( object, name, function, data ): Delete a callback to
the object's "name" variable. "function" and "data" must be the same as
when add_callback() was called.
var.trigger_callback( object, name ): Trigger the callbacks associated with the var.trigger_callback( object, name ): Trigger the callbacks associated with the
object's "name" variable. object's "name" variable.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment