From e63bf869950349a205400f9f0744387099706f0c Mon Sep 17 00:00:00 2001
From: George Kiagiadakis <george.kiagiadakis@collabora.com>
Date: Tue, 12 May 2020 17:36:06 +0300
Subject: [PATCH] lib: add a WpPlugin class

This serves as a base class for daemon plugins, which are implemented
inside modules
---
 lib/wp/meson.build |   2 +
 lib/wp/module.c    |   2 +
 lib/wp/plugin.c    | 200 +++++++++++++++++++++++++++++++++++++++++++++
 lib/wp/plugin.h    |  55 +++++++++++++
 lib/wp/wp.h        |   1 +
 5 files changed, 260 insertions(+)
 create mode 100644 lib/wp/plugin.c
 create mode 100644 lib/wp/plugin.h

diff --git a/lib/wp/meson.build b/lib/wp/meson.build
index 9c88bd3f..40d64b4d 100644
--- a/lib/wp/meson.build
+++ b/lib/wp/meson.build
@@ -15,6 +15,7 @@ wp_lib_sources = files(
   'node.c',
   'object-interest.c',
   'object-manager.c',
+  'plugin.c',
   'port.c',
   'properties.c',
   'proxy.c',
@@ -48,6 +49,7 @@ wp_lib_headers = files(
   'node.h',
   'object-interest.h',
   'object-manager.h',
+  'plugin.h',
   'port.h',
   'properties.h',
   'proxy.h',
diff --git a/lib/wp/module.c b/lib/wp/module.c
index f6036ef3..05f4746a 100644
--- a/lib/wp/module.c
+++ b/lib/wp/module.c
@@ -191,6 +191,7 @@ wp_module_load (WpCore * core, const gchar * abi, const gchar * module_name,
 GVariant *
 wp_module_get_properties (WpModule * self)
 {
+  g_return_val_if_fail (WP_IS_MODULE (self), NULL);
   return self->properties;
 }
 
@@ -203,6 +204,7 @@ wp_module_get_properties (WpModule * self)
 WpCore *
 wp_module_get_core (WpModule * self)
 {
+  g_return_val_if_fail (WP_IS_MODULE (self), NULL);
   return g_weak_ref_get (&self->core);
 }
 
diff --git a/lib/wp/plugin.c b/lib/wp/plugin.c
new file mode 100644
index 00000000..ddd6c77d
--- /dev/null
+++ b/lib/wp/plugin.c
@@ -0,0 +1,200 @@
+/* WirePlumber
+ *
+ * Copyright © 2020 Collabora Ltd.
+ *    @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+/**
+ * SECTION: plugin
+ * @title: WirePlumber Daemon Plugins
+ */
+
+#define G_LOG_DOMAIN "wp-plugin"
+
+#include "plugin.h"
+#include "private.h"
+
+enum {
+  PROP_0,
+  PROP_MODULE,
+};
+
+typedef struct _WpPluginPrivate WpPluginPrivate;
+struct _WpPluginPrivate
+{
+  GWeakRef module;
+};
+
+/**
+ * WpPlugin:
+ *
+ * #WpPlugin is a base class for objects that provide functionality to the
+ * WirePlumber daemon.
+ *
+ * Typically, a plugin is created within a module and then registered to
+ * make it available for use by the daemon. The daemon is responsible for
+ * calling #WpPluginClass.activate() after all modules have been loaded,
+ * the core is connected and the initial discovery of global objects is
+ * done.
+ */
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (WpPlugin, wp_plugin, G_TYPE_OBJECT)
+
+static void
+wp_plugin_init (WpPlugin * self)
+{
+  WpPluginPrivate *priv = wp_plugin_get_instance_private (self);
+  g_weak_ref_init (&priv->module, NULL);
+}
+
+static void
+wp_plugin_dispose (GObject * object)
+{
+  WpPlugin *self = WP_PLUGIN (object);
+
+  wp_plugin_deactivate (self);
+
+  G_OBJECT_CLASS (wp_plugin_parent_class)->dispose (object);
+}
+
+static void
+wp_plugin_finalize (GObject * object)
+{
+  WpPlugin *self = WP_PLUGIN (object);
+  WpPluginPrivate *priv = wp_plugin_get_instance_private (self);
+
+  g_weak_ref_clear (&priv->module);
+
+  G_OBJECT_CLASS (wp_plugin_parent_class)->finalize (object);
+}
+
+static void
+wp_plugin_set_property (GObject * object, guint property_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  WpPlugin *self = WP_PLUGIN (object);
+  WpPluginPrivate *priv = wp_plugin_get_instance_private (self);
+
+  switch (property_id) {
+  case PROP_MODULE:
+    g_weak_ref_set (&priv->module, g_value_get_object (value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    break;
+  }
+}
+
+static void
+wp_plugin_get_property (GObject * object, guint property_id,
+    GValue * value, GParamSpec * pspec)
+{
+  WpPlugin *self = WP_PLUGIN (object);
+  WpPluginPrivate *priv = wp_plugin_get_instance_private (self);
+
+  switch (property_id) {
+  case PROP_MODULE:
+    g_value_take_object (value, g_weak_ref_get (&priv->module));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    break;
+  }
+}
+
+static void
+wp_plugin_class_init (WpPluginClass * klass)
+{
+  GObjectClass * object_class = (GObjectClass *) klass;
+
+  object_class->dispose = wp_plugin_dispose;
+  object_class->finalize = wp_plugin_finalize;
+  object_class->set_property = wp_plugin_set_property;
+  object_class->get_property = wp_plugin_get_property;
+
+  /**
+   * WpPlugin:module:
+   * The module that created this plugin.
+   * Implementations should initialize this in the constructor.
+   */
+  g_object_class_install_property (object_class, PROP_MODULE,
+      g_param_spec_object ("module", "module",
+          "The module that owns this plugin", WP_TYPE_MODULE,
+          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+}
+
+/**
+ * wp_plugin_register:
+ * @plugin: (transfer full): the plugin
+ *
+ * Registers the plugin to its associated core, making it available for use
+ */
+void
+wp_plugin_register (WpPlugin * plugin)
+{
+  g_autoptr (WpCore) core = wp_plugin_get_core (plugin);
+  g_return_if_fail (WP_IS_CORE (core));
+
+  wp_registry_register_object (wp_core_get_registry (core), plugin);
+}
+
+/**
+ * wp_plugin_get_module:
+ * @self: the plugin
+ *
+ * Returns: (transfer full): the module associated with this plugin
+ */
+WpModule *
+wp_plugin_get_module (WpPlugin * self)
+{
+  g_return_val_if_fail (WP_IS_PLUGIN (self), NULL);
+
+  WpPluginPrivate *priv = wp_plugin_get_instance_private (self);
+  return g_weak_ref_get (&priv->module);
+}
+
+/**
+ * wp_plugin_get_core:
+ * @self: the plugin
+ *
+ * Returns: (transfer full): the core associated with this plugin
+ */
+WpCore *
+wp_plugin_get_core (WpPlugin * self)
+{
+  g_autoptr (WpModule) module = wp_plugin_get_module (self);
+  return module ? wp_module_get_core (module) : NULL;
+}
+
+/**
+ * wp_plugin_activate: (virtual activate)
+ * @self: the plugin
+ *
+ * Activates the plugin. The plugin is required to start any operations only
+ * when this method is called and not before.
+ */
+void
+wp_plugin_activate (WpPlugin * self)
+{
+  g_return_if_fail (WP_IS_PLUGIN (self));
+  g_return_if_fail (WP_PLUGIN_GET_CLASS (self)->activate);
+
+  WP_PLUGIN_GET_CLASS (self)->activate (self);
+}
+
+/**
+ * wp_plugin_deactivate: (virtual deactivate)
+ * @self: the plugin
+ *
+ * Deactivates the plugin. The plugin is required to stop all operations and
+ * release all resources associated with it.
+ */
+void
+wp_plugin_deactivate (WpPlugin * self)
+{
+  g_return_if_fail (WP_IS_PLUGIN (self));
+  g_return_if_fail (WP_PLUGIN_GET_CLASS (self)->deactivate);
+
+  WP_PLUGIN_GET_CLASS (self)->deactivate (self);
+}
diff --git a/lib/wp/plugin.h b/lib/wp/plugin.h
new file mode 100644
index 00000000..97180f10
--- /dev/null
+++ b/lib/wp/plugin.h
@@ -0,0 +1,55 @@
+/* WirePlumber
+ *
+ * Copyright © 2020 Collabora Ltd.
+ *    @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __WIREPLUMBER_PLUGIN_H__
+#define __WIREPLUMBER_PLUGIN_H__
+
+#include "module.h"
+
+G_BEGIN_DECLS
+
+/**
+ * WP_TYPE_PLUGIN:
+ *
+ * The #WpPlugin #GType
+ */
+#define WP_TYPE_PLUGIN (wp_plugin_get_type ())
+WP_API
+G_DECLARE_DERIVABLE_TYPE (WpPlugin, wp_plugin, WP, PLUGIN, GObject)
+
+/**
+ * WpPluginClass:
+ * @activate: See wp_plugin_activate()
+ * @deactivate: See wp_plugin_deactivate()
+ */
+struct _WpPluginClass
+{
+  GObjectClass parent_class;
+
+  void (*activate) (WpPlugin * self);
+  void (*deactivate) (WpPlugin * self);
+};
+
+WP_API
+void wp_plugin_register (WpPlugin * plugin);
+
+WP_API
+WpModule * wp_plugin_get_module (WpPlugin * self);
+
+WP_API
+WpCore * wp_plugin_get_core (WpPlugin * self);
+
+WP_API
+void wp_plugin_activate (WpPlugin * self);
+
+WP_API
+void wp_plugin_deactivate (WpPlugin * self);
+
+G_END_DECLS
+
+#endif
diff --git a/lib/wp/wp.h b/lib/wp/wp.h
index 50d9762d..df6af38b 100644
--- a/lib/wp/wp.h
+++ b/lib/wp/wp.h
@@ -25,6 +25,7 @@
 #include "node.h"
 #include "object-interest.h"
 #include "object-manager.h"
+#include "plugin.h"
 #include "port.h"
 #include "properties.h"
 #include "proxy.h"
-- 
GitLab