📄 variables.c
字号:
static inline const void *luaL_checklightuserdata( lua_State *L, int narg ){ luaL_checktype( L, narg, LUA_TLIGHTUSERDATA ); /* can raise an error */ 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 ); /* callbacks[index] callback var oldval */ vlclua_pushvalue( L, p_callback->i_type, newval ); /* 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 runing 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 ); 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 = var_Type( *pp_obj, psz_var ); 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 == false ) /* 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 const luaL_Reg vlclua_var_reg[] = { { "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 }, { "command", vlclua_command }, { "libvlc_command", vlclua_libvlc_command }, { NULL, NULL }};void luaopen_variables( lua_State *L ){ lua_newtable( L ); luaL_register( L, NULL, vlclua_var_reg ); lua_setfield( L, -2, "var" );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -