sd: use owner structure instead of legacy event manager
authorRémi Denis-Courmont <remi@remlab.net>
Mon, 14 Nov 2016 19:48:38 +0000 (21:48 +0200)
committerRémi Denis-Courmont <remi@remlab.net>
Mon, 14 Nov 2016 19:50:40 +0000 (21:50 +0200)
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.

include/vlc_events.h
include/vlc_services_discovery.h
lib/media_discoverer.c
src/libvlccore.sym
src/playlist/services_discovery.c

index bf1ba8c..4d9e3b4 100644 (file)
@@ -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 */
index 22df2fc..7f00d22 100644 (file)
@@ -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 */
 
index ce56a01..730b5c3 100644 (file)
@@ -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 );
 
index b3a5ddb..e60299f 100644 (file)
@@ -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
index aadee57..b31ae88 100644 (file)
@@ -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 */