Commit 3aa7d6ce authored by George Kiagiadakis's avatar George Kiagiadakis

lib: remove the session-manager object and register endpoints as globals

parent 1b6d9720
......@@ -88,12 +88,6 @@
#include "error.h"
#include "factory.h"
/* private api in session-manager */
void wp_session_manager_add_endpoint (WpSessionManager * self,
WpEndpoint * ep);
void wp_session_manager_remove_endpoint (WpSessionManager * self,
WpEndpoint * ep);
typedef struct _WpEndpointPrivate WpEndpointPrivate;
struct _WpEndpointPrivate
{
......@@ -102,7 +96,7 @@ struct _WpEndpointPrivate
GPtrArray *streams;
GPtrArray *controls;
GPtrArray *links;
GWeakRef sm;
WpCore *core;
};
enum {
......@@ -125,7 +119,6 @@ wp_endpoint_init (WpEndpoint * self)
{
WpEndpointPrivate *priv = wp_endpoint_get_instance_private (self);
g_weak_ref_init (&priv->sm, NULL);
priv->streams =
g_ptr_array_new_with_free_func ((GDestroyNotify) g_variant_unref);
priv->controls =
......@@ -155,7 +148,6 @@ wp_endpoint_finalize (GObject * object)
WpEndpointPrivate *priv =
wp_endpoint_get_instance_private (WP_ENDPOINT (object));
g_weak_ref_clear (&priv->sm);
g_ptr_array_unref (priv->streams);
g_ptr_array_unref (priv->controls);
g_ptr_array_unref (priv->links);
......@@ -246,25 +238,26 @@ wp_endpoint_class_init (WpEndpointClass * klass)
/**
* wp_endpoint_register:
* @self: the endpoint
* @sm: the session manager
* @core: the core
*
* Registers the endpoint on the @sm.
* Registers the endpoint on the @core.
*/
void
wp_endpoint_register (WpEndpoint * self, WpSessionManager * sm)
wp_endpoint_register (WpEndpoint * self, WpCore * core)
{
WpEndpointPrivate *priv;
g_return_if_fail (WP_IS_ENDPOINT (self));
g_return_if_fail (WP_IS_SESSION_MANAGER (sm));
g_return_if_fail (WP_IS_CORE (core));
priv = wp_endpoint_get_instance_private (self);
g_info ("WpEndpoint:%p registering '%s' (%s)", self, priv->name,
priv->media_class);
g_weak_ref_set (&priv->sm, sm);
wp_session_manager_add_endpoint (sm, self);
priv->core = core;
wp_core_register_global (core, WP_GLOBAL_ENDPOINT, g_object_ref (self),
g_object_unref);
}
/**
......@@ -278,19 +271,81 @@ void
wp_endpoint_unregister (WpEndpoint * self)
{
WpEndpointPrivate *priv;
g_autoptr (WpSessionManager) sm = NULL;
g_return_if_fail (WP_IS_ENDPOINT (self));
priv = wp_endpoint_get_instance_private (self);
sm = g_weak_ref_get (&priv->sm);
if (sm) {
if (priv->core) {
g_info ("WpEndpoint:%p unregistering '%s' (%s)", self, priv->name,
priv->media_class);
g_weak_ref_set (&priv->sm, NULL);
wp_session_manager_remove_endpoint (sm, self);
priv->core = NULL;
wp_core_remove_global (priv->core, WP_GLOBAL_ENDPOINT, self);
}
}
struct endpoints_foreach_data
{
GPtrArray *result;
const gchar *lookup;
};
static inline gboolean
media_class_matches (const gchar * media_class, const gchar * lookup)
{
const gchar *c1 = media_class, *c2 = lookup;
/* empty lookup matches all classes */
if (!lookup)
return TRUE;
/* compare until we reach the end of the lookup string */
for (; *c2 != '\0'; c1++, c2++) {
if (*c1 != *c2)
return FALSE;
}
/* the lookup may not end in a slash, however it must match up
* to the end of a submedia_class. i.e.:
* match: media_class: Audio/Source/Virtual
* lookup: Audio/Source
*
* NO match: media_class: Audio/Source/Virtual
* lookup: Audio/Sou
*
* if *c1 is not /, also check the previous char, because the lookup
* may actually end in a slash:
*
* match: media_class: Audio/Source/Virtual
* lookup: Audio/Source/
*/
if (!(*c1 == '/' || *c1 == '\0' || *(c1 - 1) == '/'))
return FALSE;
return TRUE;
}
static gboolean
find_endpoints (GQuark key, gpointer global, gpointer user_data)
{
struct endpoints_foreach_data * data = user_data;
if (key == WP_GLOBAL_ENDPOINT &&
media_class_matches (wp_endpoint_get_media_class (WP_ENDPOINT (global)),
data->lookup))
g_ptr_array_add (data->result, g_object_ref (global));
return WP_CORE_FOREACH_GLOBAL_CONTINUE;
}
GPtrArray *
wp_endpoint_find (WpCore * core, const gchar * media_class_lookup)
{
struct endpoints_foreach_data data;
data.result = g_ptr_array_new_with_free_func (g_object_unref);
data.lookup = media_class_lookup;
wp_core_foreach_global (core, find_endpoints, &data);
return data.result;
}
const gchar *
......
......@@ -10,7 +10,6 @@
#define __WIREPLUMBER_ENDPOINT_H__
#include "core.h"
#include "session-manager.h"
G_BEGIN_DECLS
......@@ -35,8 +34,9 @@ struct _WpEndpointClass
const gchar * (*get_endpoint_link_factory) (WpEndpoint * self);
};
void wp_endpoint_register (WpEndpoint * self, WpSessionManager * sm);
void wp_endpoint_register (WpEndpoint * self, WpCore * core);
void wp_endpoint_unregister (WpEndpoint * self);
GPtrArray * wp_endpoint_find (WpCore * core, const gchar * media_class_lookup);
const gchar * wp_endpoint_get_name (WpEndpoint * self);
const gchar * wp_endpoint_get_media_class (WpEndpoint * self);
......
......@@ -4,7 +4,6 @@ wp_lib_sources = [
'error.c',
'factory.c',
'module.c',
'session-manager.c',
]
wp_lib_headers = [
......@@ -13,7 +12,6 @@ wp_lib_headers = [
'error.h',
'factory.h',
'module.h',
'session-manager.h',
]
enums = gnome.mkenums_simple('wpenums', sources: wp_lib_headers)
......
/* WirePlumber
*
* Copyright © 2019 Collabora Ltd.
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "session-manager.h"
#include "endpoint.h"
struct _WpSessionManager
{
GObject parent;
GPtrArray *endpoints;
};
enum {
SIGNAL_ENDPOINT_ADDED,
SIGNAL_ENDPOINT_REMOVED,
NUM_SIGNALS
};
static guint32 signals[NUM_SIGNALS];
G_DEFINE_TYPE (WpSessionManager, wp_session_manager, G_TYPE_OBJECT)
G_DEFINE_QUARK (WP_GLOBAL_SESSION_MANAGER, wp_global_session_manager)
static void
wp_session_manager_init (WpSessionManager * self)
{
self->endpoints = g_ptr_array_new_with_free_func (g_object_unref);
}
static void
wp_session_manager_finalize (GObject * obj)
{
WpSessionManager * self = WP_SESSION_MANAGER (obj);
g_ptr_array_unref (self->endpoints);
G_OBJECT_CLASS (wp_session_manager_parent_class)->finalize (obj);
}
static void
wp_session_manager_class_init (WpSessionManagerClass * klass)
{
GObjectClass *object_class = (GObjectClass *) klass;
object_class->finalize = wp_session_manager_finalize;
signals[SIGNAL_ENDPOINT_ADDED] = g_signal_new ("endpoint-added",
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
G_TYPE_NONE, 1, WP_TYPE_ENDPOINT);
signals[SIGNAL_ENDPOINT_REMOVED] = g_signal_new ("endpoint-removed",
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
G_TYPE_NONE, 1, WP_TYPE_ENDPOINT);
}
WpSessionManager *
wp_session_manager_new (void)
{
return g_object_new (WP_TYPE_SESSION_MANAGER, NULL);
}
void
wp_session_manager_add_endpoint (WpSessionManager * self, WpEndpoint * ep)
{
g_ptr_array_add (self->endpoints, g_object_ref (ep));
g_signal_emit (self, signals[SIGNAL_ENDPOINT_ADDED], 0, ep);
}
void
wp_session_manager_remove_endpoint (WpSessionManager * self, WpEndpoint * ep)
{
g_signal_emit (self, signals[SIGNAL_ENDPOINT_REMOVED], 0, ep);
g_ptr_array_remove_fast (self->endpoints, ep);
}
struct endpoints_foreach_data
{
GPtrArray *result;
const gchar *lookup;
};
static inline gboolean
media_class_matches (const gchar * media_class, const gchar * lookup)
{
const gchar *c1 = media_class, *c2 = lookup;
/* empty lookup matches all classes */
if (!lookup)
return TRUE;
/* compare until we reach the end of the lookup string */
for (; *c2 != '\0'; c1++, c2++) {
if (*c1 != *c2)
return FALSE;
}
/* the lookup may not end in a slash, however it must match up
* to the end of a submedia_class. i.e.:
* match: media_class: Audio/Source/Virtual
* lookup: Audio/Source
*
* NO match: media_class: Audio/Source/Virtual
* lookup: Audio/Sou
*
* if *c1 is not /, also check the previous char, because the lookup
* may actually end in a slash:
*
* match: media_class: Audio/Source/Virtual
* lookup: Audio/Source/
*/
if (!(*c1 == '/' || *c1 == '\0' || *(c1 - 1) == '/'))
return FALSE;
return TRUE;
}
static void
find_endpoints (WpEndpoint * endpoint, struct endpoints_foreach_data * data)
{
if (media_class_matches (wp_endpoint_get_media_class (endpoint), data->lookup))
g_ptr_array_add (data->result, g_object_ref (endpoint));
}
GPtrArray *
wp_session_manager_find_endpoints (WpSessionManager * self,
const gchar * media_class_lookup)
{
struct endpoints_foreach_data data;
data.result = g_ptr_array_new_with_free_func (g_object_unref);
data.lookup = media_class_lookup;
g_ptr_array_foreach (self->endpoints, (GFunc) find_endpoints, &data);
return data.result;
}
/* WirePlumber
*
* Copyright © 2019 Collabora Ltd.
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#ifndef __WIREPLUMBER_SESSION_MANAGER_H__
#define __WIREPLUMBER_SESSION_MANAGER_H__
#include <glib-object.h>
G_BEGIN_DECLS
#define WP_TYPE_SESSION_MANAGER (wp_session_manager_get_type ())
G_DECLARE_FINAL_TYPE (WpSessionManager, wp_session_manager, WP, SESSION_MANAGER, GObject)
#define WP_GLOBAL_SESSION_MANAGER (wp_global_session_manager_quark ())
GQuark wp_global_session_manager_quark (void);
WpSessionManager * wp_session_manager_new (void);
GPtrArray * wp_session_manager_find_endpoints (WpSessionManager * self,
const gchar * media_class_lookup);
G_END_DECLS
#endif
......@@ -11,4 +11,3 @@
#include "error.h"
#include "factory.h"
#include "module.h"
#include "session-manager.h"
......@@ -50,7 +50,6 @@ registry_global (void * d, uint32_t id, uint32_t parent_id,
g_autoptr (GVariant) endpoint_props = NULL;
g_autoptr (WpCore) core = NULL;
g_autoptr (WpEndpoint) endpoint = NULL;
WpSessionManager *sm = NULL;
/* listen for client "Stream" nodes and create endpoints for them */
if (type == PW_TYPE_INTERFACE_Node &&
......@@ -79,12 +78,10 @@ registry_global (void * d, uint32_t id, uint32_t parent_id,
core = wp_module_get_core (data->module);
g_return_if_fail (core != NULL);
sm = wp_core_get_global (core, WP_GLOBAL_SESSION_MANAGER);
g_return_if_fail (sm != NULL);
endpoint = wp_factory_make (core, "pipewire-simple-endpoint",
WP_TYPE_ENDPOINT, endpoint_props);
wp_endpoint_register (endpoint, sm);
wp_endpoint_register (endpoint, core);
}
}
......
......@@ -385,7 +385,8 @@ static const struct pw_proxy_events proxy_events = {
};
static void
endpoint_added (WpSessionManager *sm, WpEndpoint *ep, struct pw_remote * remote)
endpoint_added (WpCore *core, GQuark key, WpEndpoint *ep,
struct pw_remote * remote)
{
struct pw_core_proxy *core_proxy;
struct pw_client_endpoint_proxy *client_ep_proxy;
......@@ -396,6 +397,8 @@ endpoint_added (WpSessionManager *sm, WpEndpoint *ep, struct pw_remote * remote)
struct spa_dict props_dict = SPA_DICT_INIT(props, SPA_N_ELEMENTS (props));
struct proxy_priv *priv;
g_return_if_fail (key == WP_GLOBAL_ENDPOINT);
core_proxy = pw_remote_get_core_proxy (remote);
client_ep_proxy = pw_core_proxy_create_object (core_proxy,
"client-endpoint",
......@@ -419,9 +422,12 @@ endpoint_added (WpSessionManager *sm, WpEndpoint *ep, struct pw_remote * remote)
}
static void
endpoint_removed (WpSessionManager *sm, WpEndpoint *ep, gpointer _unused)
endpoint_removed (WpCore *sm, GQuark key, WpEndpoint *ep, gpointer _unused)
{
struct pw_proxy *p;
g_return_if_fail (key == WP_GLOBAL_ENDPOINT);
p = g_object_get_qdata (G_OBJECT (ep), remote_endpoint_data_quark ());
if (p)
pw_proxy_destroy (p);
......@@ -431,13 +437,11 @@ void
remote_endpoint_init (WpCore * core, struct pw_core *pw_core,
struct pw_remote * remote)
{
WpSessionManager *sm;
pw_module_load (pw_core, "libpipewire-module-endpoint", NULL, NULL, NULL,
NULL);
sm = wp_core_get_global (core, WP_GLOBAL_SESSION_MANAGER);
g_return_if_fail (sm != NULL);
g_signal_connect (sm, "endpoint-added", (GCallback) endpoint_added, remote);
g_signal_connect (sm, "endpoint-removed", (GCallback) endpoint_removed, NULL);
g_signal_connect (core, "global-added::endpoint",
(GCallback) endpoint_added, remote);
g_signal_connect (core, "global-removed::endpoint",
(GCallback) endpoint_removed, NULL);
}
......@@ -33,7 +33,6 @@ handle_node(struct impl *impl, uint32_t id, uint32_t parent_id,
GVariantBuilder b;
g_autoptr(GVariant) endpoint_props = NULL;
g_autoptr (WpEndpoint) endpoint = NULL;
WpSessionManager *sm;
/* Make sure the node has properties */
if (!props) {
......@@ -64,13 +63,10 @@ handle_node(struct impl *impl, uint32_t id, uint32_t parent_id,
"node-proxy", g_variant_new_uint64 ((guint64) proxy));
endpoint_props = g_variant_builder_end (&b);
sm = wp_core_get_global (impl->wp_core, WP_GLOBAL_SESSION_MANAGER);
g_return_if_fail (sm != NULL);
/* Create the endpoint */
endpoint = wp_factory_make (impl->wp_core, "pw-audio-softdsp-endpoint",
WP_TYPE_ENDPOINT, endpoint_props);
wp_endpoint_register (endpoint, sm);
wp_endpoint_register (endpoint, impl->wp_core);
}
static void
......
......@@ -195,14 +195,9 @@ main (gint argc, gchar **argv)
}
/* init wireplumber */
data.core = core = wp_core_new ();
wp_core_register_global (core, WP_GLOBAL_SESSION_MANAGER,
wp_session_manager_new (), g_object_unref);
/* init main loop */
data.loop = loop = g_main_loop_new (NULL, FALSE);
/* watch for exit signals */
......
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