mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2025-12-20 14:40:03 +01:00
The intention is to make checks for enabled log topics faster. Every topic has its own structure that is statically defined in the file where the logs are printed from. The structure is initialized transparently when it is first used and it contains all the log level flags for the levels that this topic should print messages. It is then checked on the wp_log() macro before printing the message. Topics from SPA/PipeWire are also handled natively, so messages are printed directly without checking if the topic is enabled, since the PipeWire and SPA macros do the checking themselves. Messages coming from GLib are checked inside the handler. An internal WpLogFields object is used to manage the state of each log message, populating all the fields appropriately from the place they are coming from (wp_log, spa_log, glib log), formatting the message and then printing it. For printing to the journald, we still use the glib message handler, converting all the needed fields to GLogField on demand. That message handler does not do any checks for the topic or the level, so we can just call it to send the message.
258 lines
6.7 KiB
C
258 lines
6.7 KiB
C
/* WirePlumber
|
|
*
|
|
* Copyright © 2020 Collabora Ltd.
|
|
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include "si-factory.h"
|
|
#include "private/registry.h"
|
|
#include "log.h"
|
|
|
|
WP_DEFINE_LOCAL_LOG_TOPIC ("wp-si-factory")
|
|
|
|
/*! \defgroup wpsifactory WpSiFactory */
|
|
/*!
|
|
* \struct WpSiFactory
|
|
*
|
|
* A factory for session items.
|
|
*
|
|
* The most simple way to register a new item implementation would be:
|
|
* \code
|
|
* wp_si_factory_register (core,
|
|
* wp_si_factory_new_simple ("foobar", FOO_TYPE_BAR));
|
|
* \endcode
|
|
*
|
|
* And the most simple way to construct an item from a registered factory:
|
|
* \code
|
|
* item = wp_session_item_make (core, "foobar");
|
|
* \endcode
|
|
*
|
|
* \gproperties
|
|
*
|
|
* \gproperty{name, gchar *, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY,
|
|
* The factory's name}
|
|
*/
|
|
enum {
|
|
PROP_0,
|
|
PROP_NAME,
|
|
};
|
|
|
|
typedef struct _WpSiFactoryPrivate WpSiFactoryPrivate;
|
|
struct _WpSiFactoryPrivate
|
|
{
|
|
GQuark name_quark;
|
|
};
|
|
|
|
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));
|
|
}
|
|
|
|
/*!
|
|
* \brief Gets the name of the factory
|
|
*
|
|
* \ingroup wpsifactory
|
|
* \param 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);
|
|
}
|
|
|
|
/*!
|
|
* \brief Creates a new instance of the session item that is constructed
|
|
* by this factory
|
|
*
|
|
* \ingroup wpsifactory
|
|
* \param self the factory
|
|
* \param core the core
|
|
* \returns (transfer full): a new session item instance
|
|
*/
|
|
WpSessionItem *
|
|
wp_si_factory_construct (WpSiFactory * self, WpCore * core)
|
|
{
|
|
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, core);
|
|
}
|
|
|
|
/*!
|
|
* \brief Registers the \a factory on the \a core.
|
|
*
|
|
* \ingroup wpsifactory
|
|
* \param core the core
|
|
* \param factory (transfer full): the factory to register
|
|
*/
|
|
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);
|
|
}
|
|
|
|
/*!
|
|
* \brief Looks up a factory matching a name
|
|
*
|
|
* \ingroup wpsifactory
|
|
* \param core the core
|
|
* \param 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;
|
|
}
|
|
|
|
/*!
|
|
* \brief Finds the factory associated with the given \a name from the \a core
|
|
* and uses it to construct a new WpSessionItem.
|
|
*
|
|
* \ingroup wpsifactory
|
|
* \param core the WpCore
|
|
* \param factory_name the name of the factory to be used for constructing
|
|
* the object
|
|
* \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, core) : NULL;
|
|
}
|
|
|
|
struct _WpSimpleSiFactory
|
|
{
|
|
WpSiFactory parent;
|
|
GType si_type;
|
|
};
|
|
|
|
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 WpSessionItem *
|
|
wp_simple_si_factory_construct (WpSiFactory * self, WpCore *core)
|
|
{
|
|
return g_object_new (WP_SIMPLE_SI_FACTORY (self)->si_type,
|
|
"core", core,
|
|
NULL);
|
|
}
|
|
|
|
static void
|
|
wp_simple_si_factory_class_init (WpSimpleSiFactoryClass * klass)
|
|
{
|
|
WpSiFactoryClass * factory_class = (WpSiFactoryClass *) klass;
|
|
|
|
factory_class->construct = wp_simple_si_factory_construct;
|
|
}
|
|
|
|
/*!
|
|
* \brief Creates a simple factory that constructs objects of a given GType.
|
|
*
|
|
* \ingroup wpsifactory
|
|
* \param factory_name the factory name; must be a static string!
|
|
* \param si_type the WpSessionItem subclass type to instantiate for
|
|
* constructing items
|
|
* \returns (transfer full): the new factory
|
|
*/
|
|
WpSiFactory *
|
|
wp_si_factory_new_simple (const gchar * factory_name, GType si_type)
|
|
{
|
|
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);
|
|
|
|
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;
|
|
|
|
return WP_SI_FACTORY (self);
|
|
}
|