mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-05-14 11:08:10 +02:00
lib: implement WpSiFactory, a factory for session items
This commit is contained in:
parent
51f7897aa1
commit
fc4fa4ca8a
5 changed files with 371 additions and 0 deletions
|
|
@ -17,6 +17,7 @@ wp_lib_sources = files(
|
|||
'proxy.c',
|
||||
'session.c',
|
||||
'session-item.c',
|
||||
'si-factory.c',
|
||||
'si-interfaces.c',
|
||||
'spa-props.c',
|
||||
'transition.c',
|
||||
|
|
@ -43,6 +44,7 @@ wp_lib_headers = files(
|
|||
'session.h',
|
||||
'session-item.h',
|
||||
'si-interfaces.h',
|
||||
'si-factory.h',
|
||||
'transition.h',
|
||||
'wp.h',
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
/**
|
||||
* SECTION: WpSessionItem
|
||||
* @title: Session Items
|
||||
*/
|
||||
|
||||
#include "session-item.h"
|
||||
|
|
@ -27,6 +28,9 @@ enum {
|
|||
|
||||
guint32 signals[N_SIGNALS] = {0};
|
||||
|
||||
/**
|
||||
* WpSessionItem:
|
||||
*/
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (WpSessionItem, wp_session_item, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
|
|
|
|||
306
lib/wp/si-factory.c
Normal file
306
lib/wp/si-factory.c
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
/* WirePlumber
|
||||
*
|
||||
* Copyright © 2020 Collabora Ltd.
|
||||
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION: WpSiFactory
|
||||
* @title: Session Items Factory
|
||||
*/
|
||||
|
||||
#include "si-factory.h"
|
||||
#include "private.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
};
|
||||
|
||||
typedef struct _WpSiFactoryPrivate WpSiFactoryPrivate;
|
||||
struct _WpSiFactoryPrivate
|
||||
{
|
||||
GQuark name_quark;
|
||||
};
|
||||
|
||||
/**
|
||||
* WpSiFactory:
|
||||
*
|
||||
* A factory for session items.
|
||||
*
|
||||
* The most simple way to register a new item implementation would be:
|
||||
* |[
|
||||
* GVariantBuilder b = G_VARIANT_BUILDER_INIT ("a(ssymv)");
|
||||
* g_variant_builder_add (&b, ...);
|
||||
* wp_si_factory_register (core, wp_si_factory_new_simple (
|
||||
* "foobar", FOO_TYPE_BAR, g_variant_builder_end (&b)));
|
||||
* ]|
|
||||
*
|
||||
* And the most simple way to construct an item from a registered factory:
|
||||
* |[
|
||||
* item = wp_session_item_make (core, "foobar");
|
||||
* ]|
|
||||
*/
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (WpSiFactory, wp_si_factory, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
wp_si_factory_init (WpSiFactory * self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
wp_si_factory_set_property (GObject * object, guint property_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
WpSiFactory *self = WP_SI_FACTORY (object);
|
||||
WpSiFactoryPrivate *priv = wp_si_factory_get_instance_private (self);
|
||||
|
||||
switch (property_id) {
|
||||
case PROP_NAME:
|
||||
priv->name_quark = g_quark_from_string (g_value_get_string (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wp_si_factory_get_property (GObject * object, guint property_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
WpSiFactory *self = WP_SI_FACTORY (object);
|
||||
WpSiFactoryPrivate *priv = wp_si_factory_get_instance_private (self);
|
||||
|
||||
switch (property_id) {
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, g_quark_to_string (priv->name_quark));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wp_si_factory_class_init (WpSiFactoryClass * klass)
|
||||
{
|
||||
GObjectClass * object_class = (GObjectClass *) klass;
|
||||
|
||||
object_class->get_property = wp_si_factory_get_property;
|
||||
object_class->set_property = wp_si_factory_set_property;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_NAME,
|
||||
g_param_spec_string ("name", "name", "The factory's name", "",
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_si_factory_get_name:
|
||||
* @self: the factory
|
||||
*
|
||||
* Returns: the factory name
|
||||
*/
|
||||
const gchar *
|
||||
wp_si_factory_get_name (WpSiFactory * self)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_SI_FACTORY (self), NULL);
|
||||
|
||||
WpSiFactoryPrivate *priv = wp_si_factory_get_instance_private (self);
|
||||
return g_quark_to_string (priv->name_quark);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_si_factory_construct:
|
||||
* @self: the factory
|
||||
*
|
||||
* Creates a new instance of the session item that is constructed
|
||||
* by this factory
|
||||
*
|
||||
* Returns: (transfer full): a new session item instance
|
||||
*/
|
||||
WpSessionItem *
|
||||
wp_si_factory_construct (WpSiFactory * self)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_SI_FACTORY (self), NULL);
|
||||
g_return_val_if_fail (WP_SI_FACTORY_GET_CLASS (self)->construct, NULL);
|
||||
|
||||
return WP_SI_FACTORY_GET_CLASS (self)->construct (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_si_factory_get_config_spec:
|
||||
* @self: the factory
|
||||
*
|
||||
* Returns a description of all the configuration options that the constructed
|
||||
* items of this factory have. Configuration options are a way for items to
|
||||
* accept input from external sources that affects their behavior, or to
|
||||
* provide output for other items to consume as their configuration.
|
||||
*
|
||||
* The returned GVariant has the a(ssymv) type. This is an array of tuples,
|
||||
* where each tuple has the following values, in order:
|
||||
* * s (string): the name of the option
|
||||
* * s (string): a GVariant type string, describing the type of the data
|
||||
* * y (byte): a combination of #WpSiConfigOptionFlags
|
||||
* * mv (optional variant): optionally, an additional variant
|
||||
* This is provided to allow extensions.
|
||||
*
|
||||
* Returns: (transfer full): the configuration description
|
||||
*/
|
||||
GVariant *
|
||||
wp_si_factory_get_config_spec (WpSiFactory * self)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_SI_FACTORY (self), NULL);
|
||||
g_return_val_if_fail (WP_SI_FACTORY_GET_CLASS (self)->get_config_spec, NULL);
|
||||
|
||||
return WP_SI_FACTORY_GET_CLASS (self)->get_config_spec (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_si_factory_register:
|
||||
* @core: the core
|
||||
* @factory: (transfer full): the factory to register
|
||||
*
|
||||
* Registers the @factory on the @core.
|
||||
*/
|
||||
void
|
||||
wp_si_factory_register (WpCore * core, WpSiFactory * factory)
|
||||
{
|
||||
g_return_if_fail (WP_IS_CORE (core));
|
||||
g_return_if_fail (WP_IS_SI_FACTORY (factory));
|
||||
|
||||
wp_registry_register_object (wp_core_get_registry (core), factory);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
find_factory_func (gpointer factory, gpointer name_quark)
|
||||
{
|
||||
if (!WP_IS_SI_FACTORY (factory))
|
||||
return FALSE;
|
||||
|
||||
WpSiFactoryPrivate *priv =
|
||||
wp_si_factory_get_instance_private ((WpSiFactory *) factory);
|
||||
return priv->name_quark == GPOINTER_TO_UINT (name_quark);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_si_factory_find:
|
||||
* @core: the core
|
||||
* @factory_name: the lookup name
|
||||
*
|
||||
* Returns: (transfer full) (nullable): the factory matching the lookup name
|
||||
*/
|
||||
WpSiFactory *
|
||||
wp_si_factory_find (WpCore * core, const gchar * factory_name)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_CORE (core), NULL);
|
||||
|
||||
GQuark q = g_quark_try_string (factory_name);
|
||||
if (q == 0)
|
||||
return NULL;
|
||||
GObject *f = wp_registry_find_object (wp_core_get_registry (core),
|
||||
(GEqualFunc) find_factory_func, GUINT_TO_POINTER (q));
|
||||
return f ? WP_SI_FACTORY (f) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_session_item_make:
|
||||
* @core: the #WpCore
|
||||
* @factory_name: the name of the factory to be used for constructing the object
|
||||
*
|
||||
* Finds the factory associated with the given @name from the @core and
|
||||
* uses it to construct a new #WpSessionItem.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): the new session item
|
||||
*/
|
||||
WpSessionItem *
|
||||
wp_session_item_make (WpCore * core, const gchar * factory_name)
|
||||
{
|
||||
g_autoptr (WpSiFactory) f = wp_si_factory_find (core, factory_name);
|
||||
return f ? wp_si_factory_construct (f) : NULL;
|
||||
}
|
||||
|
||||
struct _WpSimpleSiFactory
|
||||
{
|
||||
WpSiFactory parent;
|
||||
GType si_type;
|
||||
GVariant *config_spec;
|
||||
};
|
||||
|
||||
G_DECLARE_FINAL_TYPE (WpSimpleSiFactory, wp_simple_si_factory,
|
||||
WP, SIMPLE_SI_FACTORY, WpSiFactory)
|
||||
G_DEFINE_TYPE (WpSimpleSiFactory, wp_simple_si_factory, WP_TYPE_SI_FACTORY)
|
||||
|
||||
static void
|
||||
wp_simple_si_factory_init (WpSimpleSiFactory * self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
wp_simple_si_factory_finalize (GObject * object)
|
||||
{
|
||||
WpSimpleSiFactory * self = WP_SIMPLE_SI_FACTORY (object);
|
||||
|
||||
g_clear_pointer (&self->config_spec, g_variant_unref);
|
||||
|
||||
G_OBJECT_CLASS (wp_simple_si_factory_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static WpSessionItem *
|
||||
wp_simple_si_factory_construct (WpSiFactory * self)
|
||||
{
|
||||
return g_object_new (WP_SIMPLE_SI_FACTORY (self)->si_type, NULL);
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
wp_simple_si_factory_get_config_spec (WpSiFactory * self)
|
||||
{
|
||||
return g_variant_ref (WP_SIMPLE_SI_FACTORY (self)->config_spec);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_simple_si_factory_class_init (WpSimpleSiFactoryClass * klass)
|
||||
{
|
||||
GObjectClass * object_class = (GObjectClass *) klass;
|
||||
WpSiFactoryClass * factory_class = (WpSiFactoryClass *) klass;
|
||||
|
||||
object_class->finalize = wp_simple_si_factory_finalize;
|
||||
|
||||
factory_class->construct = wp_simple_si_factory_construct;
|
||||
factory_class->get_config_spec = wp_simple_si_factory_get_config_spec;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_si_factory_new_simple:
|
||||
* @factory_name: the factory name; must be a static string!
|
||||
* @si_type: the #WpSessionItem subclass type to instantiate for
|
||||
* constructing items
|
||||
* @config_spec: (transfer floating): the config spec that will be returned
|
||||
* by wp_si_factory_get_config_spec()
|
||||
*
|
||||
* Returns: (transfer full): the new factory
|
||||
*/
|
||||
WpSiFactory *
|
||||
wp_si_factory_new_simple (const gchar * factory_name,
|
||||
GType si_type, GVariant * config_spec)
|
||||
{
|
||||
g_return_val_if_fail (factory_name != NULL, NULL);
|
||||
g_return_val_if_fail (g_type_is_a (si_type, WP_TYPE_SESSION_ITEM), NULL);
|
||||
g_return_val_if_fail (
|
||||
g_variant_is_of_type (config_spec, G_VARIANT_TYPE ("a{sv}")), NULL);
|
||||
|
||||
WpSimpleSiFactory *self = g_object_new (
|
||||
wp_simple_si_factory_get_type (), NULL);
|
||||
|
||||
/* assign the quark directly to use g_quark_from_static_string */
|
||||
WpSiFactoryPrivate *priv =
|
||||
wp_si_factory_get_instance_private (WP_SI_FACTORY (self));
|
||||
priv->name_quark = g_quark_from_static_string (factory_name);
|
||||
|
||||
self->si_type = si_type;
|
||||
self->config_spec = g_variant_ref_sink (config_spec);
|
||||
|
||||
return WP_SI_FACTORY (self);
|
||||
}
|
||||
58
lib/wp/si-factory.h
Normal file
58
lib/wp/si-factory.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/* WirePlumber
|
||||
*
|
||||
* Copyright © 2020 Collabora Ltd.
|
||||
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef __WIREPLUMBER_SI_FACTORY_H__
|
||||
#define __WIREPLUMBER_SI_FACTORY_H__
|
||||
|
||||
#include "core.h"
|
||||
#include "session-item.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* WP_TYPE_SI_FACTORY:
|
||||
*
|
||||
* The #WpSiFactory #GType
|
||||
*/
|
||||
#define WP_TYPE_SI_FACTORY (wp_si_factory_get_type ())
|
||||
WP_API
|
||||
G_DECLARE_DERIVABLE_TYPE (WpSiFactory, wp_si_factory, WP, SI_FACTORY, GObject)
|
||||
|
||||
struct _WpSiFactoryClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
WpSessionItem * (*construct) (WpSiFactory * self);
|
||||
GVariant * (*get_config_spec) (WpSiFactory * self);
|
||||
};
|
||||
|
||||
WP_API
|
||||
WpSiFactory * wp_si_factory_new_simple (const gchar * factory_name,
|
||||
GType si_type, GVariant * config_spec);
|
||||
|
||||
WP_API
|
||||
const gchar * wp_si_factory_get_name (WpSiFactory * self);
|
||||
|
||||
WP_API
|
||||
WpSessionItem * wp_si_factory_construct (WpSiFactory * self);
|
||||
|
||||
WP_API
|
||||
GVariant * wp_si_factory_get_config_spec (WpSiFactory * self);
|
||||
|
||||
WP_API
|
||||
void wp_si_factory_register (WpCore * core, WpSiFactory * factory);
|
||||
|
||||
WP_API
|
||||
WpSiFactory * wp_si_factory_find (WpCore * core, const gchar * factory_name);
|
||||
|
||||
WP_API
|
||||
WpSessionItem * wp_session_item_make (WpCore * core, const gchar * factory_name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
@ -25,5 +25,6 @@
|
|||
#include "session.h"
|
||||
#include "session-item.h"
|
||||
#include "si-interfaces.h"
|
||||
#include "si-factory.h"
|
||||
#include "transition.h"
|
||||
#include "wpenums.h"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue