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

sd: use owner structure instead of legacy event manager

Since there are always exactly one callback per event (the owner´s),
this is much simpler. This also removes unhandled error cases, and
provides more straightforward callback prototypes.
parent 1a8808df
......@@ -121,12 +121,8 @@ typedef enum vlc_event_type_t {
vlc_InputItemErrorWhenReadingChanged,
vlc_InputItemPreparseEnded,
/* Service Discovery event */
vlc_ServicesDiscoveryItemAdded,
vlc_ServicesDiscoveryItemRemoved,
/* Renderer Discovery events */
vlc_RendererDiscoveryItemAdded=vlc_ServicesDiscoveryItemRemoved+4,
vlc_RendererDiscoveryItemAdded=vlc_InputItemPreparseEnded+6,
vlc_RendererDiscoveryItemRemoved,
/* Addons Manager events */
......
......@@ -25,7 +25,6 @@
#define VLC_SERVICES_DISCOVERY_H_
#include <vlc_input.h>
#include <vlc_events.h>
#include <vlc_probe.h>
/**
......@@ -41,6 +40,14 @@ extern "C" {
* @{
*/
struct services_discovery_owner_t
{
void *sys; /**< Private data for the owner callbacks */
void (*item_added)(struct services_discovery_t *sd, input_item_t *item,
const char *category);
void (*item_removed)(struct services_discovery_t *sd, input_item_t *item);
};
/**
* Main service discovery structure to build a SD module
*/
......@@ -49,10 +56,6 @@ struct services_discovery_t
VLC_COMMON_MEMBERS
module_t * p_module; /**< Loaded module */
/**< Event manager
* You should access it through setters, outside of the core */
vlc_event_manager_t event_manager;
char *psz_name; /**< Main name of the SD */
config_chain_t *p_cfg; /**< Configuration for the SD */
......@@ -62,6 +65,8 @@ struct services_discovery_t
int ( *pf_control ) ( services_discovery_t *, int, va_list );
services_discovery_sys_t *p_sys; /**< Custom private data */
struct services_discovery_owner_t owner; /**< Owner callbacks */
};
/**
......@@ -131,8 +136,13 @@ VLC_API char ** vlc_sd_GetNames( vlc_object_t *, char ***, int ** ) VLC_USED;
#define vlc_sd_GetNames(obj, pln, pcat ) \
vlc_sd_GetNames(VLC_OBJECT(obj), pln, pcat)
/* Creation of a services_discovery object */
VLC_API services_discovery_t * vlc_sd_Create( vlc_object_t *, const char * ) VLC_USED;
/**
* Creates a services discoverer.
*/
VLC_API services_discovery_t *vlc_sd_Create(vlc_object_t *parent,
const char *chain, const struct services_discovery_owner_t *owner)
VLC_USED;
VLC_API bool vlc_sd_Start( services_discovery_t * );
VLC_API void vlc_sd_Stop( services_discovery_t * );
VLC_API void vlc_sd_Destroy( services_discovery_t * );
......@@ -152,12 +162,39 @@ VLC_API char * services_discovery_GetLocalizedName( services_discovery_t * p_thi
/* Receive event notification (preferred way to get new items) */
VLC_API vlc_event_manager_t * services_discovery_EventManager( services_discovery_t * p_this ) VLC_USED;
/* Used by services_discovery to post update about their items */
/* About the psz_category, it is a legacy way to add info to the item,
* for more options, directly set the (meta) data on the input item */
VLC_API void services_discovery_AddItem( services_discovery_t * p_this, input_item_t * p_item, const char * psz_category );
VLC_API void services_discovery_RemoveItem( services_discovery_t * p_this, input_item_t * p_item );
/**
* Added service callback.
*
* A services discovery module invokes this function when it "discovers" a new
* service, i.e. a new input item.
*
* @note The function does not take ownership of the input item; it might
* however add one of more references. The caller is responsible for releasing
* its reference to the input item.
*
* @param sd services discoverer / services discovery module instance
* @param item input item to add
* @param category Optional name of a group that the item belongs in
* (for backward compatibility with legacy modules)
*/
static inline void services_discovery_AddItem(services_discovery_t *sd,
input_item_t *item,
const char *category)
{
return sd->owner.item_added(sd, item, category);
}
/**
* Removed service callback.
*
* A services discovery module invokes this function when it senses that a
* service is no longer available.
*/
static inline void services_discovery_RemoveItem(services_discovery_t *sd,
input_item_t *item)
{
return sd->owner.item_removed(sd, item);
}
/* SD probing */
......
......@@ -57,13 +57,12 @@ struct libvlc_media_discoverer_t
* services_discovery_item_added (Private) (VLC event callback)
**************************************************************************/
static void services_discovery_item_added( const vlc_event_t * p_event,
void * user_data )
static void services_discovery_item_added( services_discovery_t *sd,
input_item_t *p_item,
const char *psz_cat )
{
input_item_t * p_item = p_event->u.services_discovery_item_added.p_new_item;
const char * psz_cat = p_event->u.services_discovery_item_added.psz_category;
libvlc_media_t * p_md;
libvlc_media_discoverer_t * p_mdis = user_data;
libvlc_media_discoverer_t *p_mdis = sd->owner.sys;
libvlc_media_list_t * p_mlist = p_mdis->p_mlist;
p_md = libvlc_media_new_from_input_item( p_mdis->p_libvlc_instance,
......@@ -107,12 +106,11 @@ static void services_discovery_item_added( const vlc_event_t * p_event,
* services_discovery_item_removed (Private) (VLC event callback)
**************************************************************************/
static void services_discovery_item_removed( const vlc_event_t * p_event,
void * user_data )
static void services_discovery_item_removed( services_discovery_t *sd,
input_item_t *p_item )
{
input_item_t * p_item = p_event->u.services_discovery_item_added.p_new_item;
libvlc_media_t * p_md;
libvlc_media_discoverer_t * p_mdis = user_data;
libvlc_media_discoverer_t *p_mdis = sd->owner.sys;
int i, count = libvlc_media_list_count( p_mdis->p_mlist );
libvlc_media_list_lock( p_mdis->p_mlist );
......@@ -166,8 +164,14 @@ libvlc_media_discoverer_new( libvlc_instance_t * p_inst, const char * psz_name )
return NULL;
}
struct services_discovery_owner_t owner = {
p_mdis,
services_discovery_item_added,
services_discovery_item_removed,
};
p_mdis->p_sd = vlc_sd_Create( (vlc_object_t*)p_inst->p_libvlc_int,
psz_name );
psz_name, &owner );
if( unlikely(p_mdis->p_sd == NULL) )
{
libvlc_printerr( "%s: no such discovery module found", psz_name );
......@@ -177,15 +181,6 @@ libvlc_media_discoverer_new( libvlc_instance_t * p_inst, const char * psz_name )
return NULL;
}
vlc_event_attach( services_discovery_EventManager( p_mdis->p_sd ),
vlc_ServicesDiscoveryItemAdded,
services_discovery_item_added,
p_mdis );
vlc_event_attach( services_discovery_EventManager( p_mdis->p_sd ),
vlc_ServicesDiscoveryItemRemoved,
services_discovery_item_removed,
p_mdis );
libvlc_retain( p_inst );
return p_mdis;
}
......@@ -256,15 +251,6 @@ libvlc_media_discoverer_new_from_name( libvlc_instance_t * p_inst,
void
libvlc_media_discoverer_release( libvlc_media_discoverer_t * p_mdis )
{
vlc_event_detach( services_discovery_EventManager( p_mdis->p_sd ),
vlc_ServicesDiscoveryItemAdded,
services_discovery_item_added,
p_mdis );
vlc_event_detach( services_discovery_EventManager( p_mdis->p_sd ),
vlc_ServicesDiscoveryItemRemoved,
services_discovery_item_removed,
p_mdis );
if( p_mdis->running )
libvlc_media_discoverer_stop( p_mdis );
......
......@@ -375,10 +375,7 @@ playlist_MuteGet
sdp_AddAttribute
sdp_AddMedia
secstotimestr
services_discovery_AddItem
services_discovery_EventManager
services_discovery_GetLocalizedName
services_discovery_RemoveItem
sout_AccessOutControl
sout_AccessOutDelete
sout_AccessOutNew
......
......@@ -27,7 +27,6 @@
#include <vlc_common.h>
#include "vlc_playlist.h"
#include "vlc_events.h"
#include <vlc_services_discovery.h>
#include <vlc_probe.h>
#include <vlc_modules.h>
......@@ -99,9 +98,6 @@ char **vlc_sd_GetNames (vlc_object_t *obj, char ***pppsz_longnames, int **pp_cat
return names;
}
static void services_discovery_Destructor ( vlc_object_t *p_obj );
/*
* Services discovery
* Basically you just listen to Service discovery event through the
......@@ -109,26 +105,18 @@ static void services_discovery_Destructor ( vlc_object_t *p_obj );
* That's how the playlist get's Service Discovery information
*/
/*******************************************************************//**
* Create a Service discovery
***********************************************************************/
services_discovery_t *vlc_sd_Create( vlc_object_t *p_super,
const char *cfg )
services_discovery_t *vlc_sd_Create(vlc_object_t *parent, const char *cfg,
const struct services_discovery_owner_t *restrict owner)
{
services_discovery_t *p_sd;
p_sd = vlc_custom_create( p_super, sizeof( *p_sd ), "services discovery" );
if( !p_sd )
services_discovery_t *sd = vlc_custom_create(parent, sizeof (*sd),
"services discovery");
if (unlikely(sd == NULL))
return NULL;
free(config_ChainCreate( &p_sd->psz_name, &p_sd->p_cfg, cfg ));
vlc_event_manager_t *em = &p_sd->event_manager;
vlc_event_manager_init( em, p_sd );
vlc_event_manager_register_event_type(em, vlc_ServicesDiscoveryItemAdded);
vlc_event_manager_register_event_type(em, vlc_ServicesDiscoveryItemRemoved);
free(config_ChainCreate(&sd->psz_name, &sd->p_cfg, cfg));
sd->owner = *owner;
vlc_object_set_destructor( p_sd, services_discovery_Destructor );
return p_sd;
return sd;
}
/*******************************************************************//**
......@@ -168,16 +156,6 @@ void vlc_sd_Destroy( services_discovery_t *p_sd )
vlc_object_release( p_sd );
}
/*******************************************************************//**
* Destructor of the Service Discovery
***********************************************************************/
static void services_discovery_Destructor ( vlc_object_t *p_obj )
{
services_discovery_t * p_sd = (services_discovery_t *)p_obj;
assert(!p_sd->p_module); /* Forgot to call Stop */
vlc_event_manager_fini( &p_sd->event_manager );
}
/*******************************************************************//**
* Get the Localized Name
*
......@@ -191,46 +169,6 @@ services_discovery_GetLocalizedName ( services_discovery_t * p_sd )
return strdup( module_get_name( p_sd->p_module, true ) );
}
/*******************************************************************//**
* Getter for the EventManager
*
* You can receive event notification
* This is the preferred way to get new items
***********************************************************************/
vlc_event_manager_t *
services_discovery_EventManager ( services_discovery_t * p_sd )
{
return &p_sd->event_manager;
}
/*******************************************************************//**
* Add an item to the Service Discovery listing
***********************************************************************/
void
services_discovery_AddItem ( services_discovery_t * p_sd, input_item_t * p_item,
const char * psz_category )
{
vlc_event_t event;
event.type = vlc_ServicesDiscoveryItemAdded;
event.u.services_discovery_item_added.p_new_item = p_item;
event.u.services_discovery_item_added.psz_category = psz_category;
vlc_event_send( &p_sd->event_manager, &event );
}
/*******************************************************************//**
* Remove an item from the Service Discovery listing
***********************************************************************/
void
services_discovery_RemoveItem ( services_discovery_t * p_sd, input_item_t * p_item )
{
vlc_event_t event;
event.type = vlc_ServicesDiscoveryItemRemoved;
event.u.services_discovery_item_removed.p_item = p_item;
vlc_event_send( &p_sd->event_manager, &event );
}
/*
* Playlist - Services discovery bridge
*/
......@@ -244,11 +182,11 @@ struct vlc_sd_internal_t
};
/* A new item has been added to a certain sd */
static void playlist_sd_item_added( const vlc_event_t * p_event, void * user_data )
static void playlist_sd_item_added(services_discovery_t *sd,
input_item_t *p_input, const char *psz_cat)
{
input_item_t * p_input = p_event->u.services_discovery_item_added.p_new_item;
const char * psz_cat = p_event->u.services_discovery_item_added.psz_category;
playlist_item_t * p_parent = user_data;
vlc_sd_internal_t *sds = sd->owner.sys;
playlist_item_t *p_parent = sds->node;
playlist_t * p_playlist = p_parent->p_playlist;
msg_Dbg( p_playlist, "Adding %s in %s",
......@@ -278,10 +216,11 @@ static void playlist_sd_item_added( const vlc_event_t * p_event, void * user_dat
}
/* A new item has been removed from a certain sd */
static void playlist_sd_item_removed( const vlc_event_t * p_event, void * user_data )
static void playlist_sd_item_removed(services_discovery_t *sd,
input_item_t *p_input)
{
input_item_t * p_input = p_event->u.services_discovery_item_removed.p_item;
playlist_item_t * p_sd_node = user_data;
vlc_sd_internal_t *sds = sd->owner.sys;
playlist_item_t *p_sd_node = sds->node;
playlist_t *p_playlist = p_sd_node->p_playlist;
PL_LOCK;
......@@ -339,8 +278,14 @@ int playlist_ServicesDiscoveryAdd(playlist_t *playlist, const char *chain)
return VLC_ENOMEM;
}
struct services_discovery_owner_t owner = {
sds,
playlist_sd_item_added,
playlist_sd_item_removed,
};
/* Perform the addition */
sds->sd = vlc_sd_Create(VLC_OBJECT(playlist), chain);
sds->sd = vlc_sd_Create(VLC_OBJECT(playlist), chain, &owner);
if (unlikely(sds->sd == NULL))
{
playlist_Lock(playlist);
......@@ -350,12 +295,6 @@ int playlist_ServicesDiscoveryAdd(playlist_t *playlist, const char *chain)
return VLC_ENOMEM;
}
vlc_event_manager_t *em = services_discovery_EventManager(sds->sd);
vlc_event_attach(em, vlc_ServicesDiscoveryItemAdded,
playlist_sd_item_added, sds->node);
vlc_event_attach(em, vlc_ServicesDiscoveryItemRemoved,
playlist_sd_item_removed, sds->node);
if (!vlc_sd_Start(sds->sd))
{
vlc_sd_Destroy(sds->sd);
......@@ -379,13 +318,6 @@ static void playlist_ServicesDiscoveryInternalRemove(playlist_t *playlist,
{
assert(sds->sd != NULL);
vlc_sd_Stop(sds->sd);
vlc_event_detach(services_discovery_EventManager(sds->sd),
vlc_ServicesDiscoveryItemAdded,
playlist_sd_item_added, sds->node);
vlc_event_detach(services_discovery_EventManager(sds->sd),
vlc_ServicesDiscoveryItemRemoved,
playlist_sd_item_removed, sds->node);
vlc_sd_Destroy(sds->sd);
/* Remove the sd playlist node if it exists */
......
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