Commit f8187680 authored by Felix Abecassis's avatar Felix Abecassis

variables: add helper function when adding/removing variable callbacks

parent cf820788
...@@ -804,36 +804,15 @@ int var_Get( vlc_object_t *p_this, const char *psz_name, vlc_value_t *p_val ) ...@@ -804,36 +804,15 @@ int var_Get( vlc_object_t *p_this, const char *psz_name, vlc_value_t *p_val )
return var_GetChecked( p_this, psz_name, 0, p_val ); return var_GetChecked( p_this, psz_name, 0, p_val );
} }
#undef var_AddCallback static int AddCallback( vlc_object_t *p_this, const char *psz_name,
/** callback_entry_t entry )
* Register a callback in a variable
*
* We store a function pointer that will be called upon variable
* modification.
*
* \param p_this The object that holds the variable
* \param psz_name The name of the variable
* \param pf_callback The function pointer
* \param p_data A generic pointer that will be passed as the last
* argument to the callback function.
*
* \warning The callback function is run in the thread that calls var_Set on
* the variable. Use proper locking. This thread may not have much
* time to spare, so keep callback functions short.
*/
int var_AddCallback( vlc_object_t *p_this, const char *psz_name,
vlc_callback_t pf_callback, void *p_data )
{ {
variable_t *p_var; variable_t *p_var;
callback_entry_t entry;
assert( p_this ); assert( p_this );
vlc_object_internals_t *p_priv = vlc_internals( p_this ); vlc_object_internals_t *p_priv = vlc_internals( p_this );
entry.pf_callback = pf_callback;
entry.p_data = p_data;
vlc_mutex_lock( &p_priv->var_lock ); vlc_mutex_lock( &p_priv->var_lock );
p_var = Lookup( p_this, psz_name ); p_var = Lookup( p_this, psz_name );
...@@ -841,7 +820,7 @@ int var_AddCallback( vlc_object_t *p_this, const char *psz_name, ...@@ -841,7 +820,7 @@ int var_AddCallback( vlc_object_t *p_this, const char *psz_name,
{ {
vlc_mutex_unlock( &p_priv->var_lock ); vlc_mutex_unlock( &p_priv->var_lock );
msg_Err( p_this, "cannot add callback %p to nonexistent " msg_Err( p_this, "cannot add callback %p to nonexistent "
"variable '%s'", pf_callback, psz_name ); "variable '%s'", entry.pf_callback, psz_name );
return VLC_ENOVAR; return VLC_ENOVAR;
} }
...@@ -856,15 +835,35 @@ int var_AddCallback( vlc_object_t *p_this, const char *psz_name, ...@@ -856,15 +835,35 @@ int var_AddCallback( vlc_object_t *p_this, const char *psz_name,
return VLC_SUCCESS; return VLC_SUCCESS;
} }
#undef var_DelCallback #undef var_AddCallback
/** /**
* Remove a callback from a variable * Register a callback in a variable
* *
* pf_callback and p_data have to be given again, because different objects * We store a function pointer that will be called upon variable
* might have registered the same callback function. * modification.
*
* \param p_this The object that holds the variable
* \param psz_name The name of the variable
* \param pf_callback The function pointer
* \param p_data A generic pointer that will be passed as the last
* argument to the callback function.
*
* \warning The callback function is run in the thread that calls var_Set on
* the variable. Use proper locking. This thread may not have much
* time to spare, so keep callback functions short.
*/ */
int var_DelCallback( vlc_object_t *p_this, const char *psz_name, int var_AddCallback( vlc_object_t *p_this, const char *psz_name,
vlc_callback_t pf_callback, void *p_data ) vlc_callback_t pf_callback, void *p_data )
{
callback_entry_t entry;
entry.pf_callback = pf_callback;
entry.p_data = p_data;
return AddCallback(p_this, psz_name, entry);
}
static int DelCallback( vlc_object_t *p_this, const char *psz_name,
callback_entry_t entry )
{ {
int i_entry; int i_entry;
variable_t *p_var; variable_t *p_var;
...@@ -889,13 +888,13 @@ int var_DelCallback( vlc_object_t *p_this, const char *psz_name, ...@@ -889,13 +888,13 @@ int var_DelCallback( vlc_object_t *p_this, const char *psz_name,
for( i_entry = p_var->i_entries ; i_entry-- ; ) for( i_entry = p_var->i_entries ; i_entry-- ; )
{ {
if( p_var->p_entries[i_entry].pf_callback == pf_callback if( p_var->p_entries[i_entry].pf_callback == entry.pf_callback
&& p_var->p_entries[i_entry].p_data == p_data ) && p_var->p_entries[i_entry].p_data == entry.p_data )
{ {
break; break;
} }
#ifndef NDEBUG #ifndef NDEBUG
else if( p_var->p_entries[i_entry].pf_callback == pf_callback ) else if( p_var->p_entries[i_entry].pf_callback == entry.pf_callback )
b_found_similar = true; b_found_similar = true;
#endif #endif
} }
...@@ -919,6 +918,23 @@ int var_DelCallback( vlc_object_t *p_this, const char *psz_name, ...@@ -919,6 +918,23 @@ int var_DelCallback( vlc_object_t *p_this, const char *psz_name,
return VLC_SUCCESS; return VLC_SUCCESS;
} }
#undef var_DelCallback
/**
* Remove a callback from a variable
*
* pf_callback and p_data have to be given again, because different objects
* might have registered the same callback function.
*/
int var_DelCallback( vlc_object_t *p_this, const char *psz_name,
vlc_callback_t pf_callback, void *p_data )
{
callback_entry_t entry;
entry.pf_callback = pf_callback;
entry.p_data = p_data;
return DelCallback(p_this, psz_name, entry);
}
#undef var_TriggerCallback #undef var_TriggerCallback
/** /**
* Trigger callback on a variable * Trigger callback on a 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