Files
wireplumber/lib/wp/session-manager.c
George Kiagiadakis 447c968846 Refactor everything!
After discussing things at the AGL May 2019 F2F meeting
and reflecting on the initial design of WirePlumber,
it became clear that it needed a fresh start.
2019-05-17 13:34:07 +03:00

121 lines
2.9 KiB
C

/* WirePlumber
*
* Copyright © 2019 Collabora Ltd.
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "session-manager.h"
struct _WpSessionManager
{
GObject parent;
GPtrArray *endpoints;
};
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;
}
WpSessionManager *
wp_session_manager_new (void)
{
return g_object_new (WP_TYPE_SESSION_MANAGER, NULL);
}
void
wp_session_manager_register_endpoint (WpSessionManager * self,
WpEndpoint * ep)
{
g_ptr_array_add (self->endpoints, g_object_ref (ep));
}
void
wp_session_manager_remove_endpoint (WpSessionManager * self,
WpEndpoint * 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;
}