[gnome-builder] device-provider: implement new IdeDeviceProvider API
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] device-provider: implement new IdeDeviceProvider API
- Date: Fri, 23 Feb 2018 02:48:35 +0000 (UTC)
commit 981436abfd23817843ae22ebe3ab775c7d68d4a5
Author: Christian Hergert <chergert redhat com>
Date: Thu Feb 22 14:41:43 2018 -0800
device-provider: implement new IdeDeviceProvider API
This moves to using a base object like we now do elsewhere instead of an
interface (which we did because of libpeas requirements early on which are
no longer an issue).
It also drops the "settled" design in favor of an easier to manage load
async/finish pair.
src/libide/devices/ide-device-provider.c | 278 +++++++++++++++++++++++++------
src/libide/devices/ide-device-provider.h | 42 +++--
2 files changed, 258 insertions(+), 62 deletions(-)
---
diff --git a/src/libide/devices/ide-device-provider.c b/src/libide/devices/ide-device-provider.c
index 33d076cce..0abe19c0e 100644
--- a/src/libide/devices/ide-device-provider.c
+++ b/src/libide/devices/ide-device-provider.c
@@ -16,88 +16,169 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <glib/gi18n.h>
+#define G_LOG_DOMAIN "ide-device-provider"
-#include "ide-context.h"
#include "devices/ide-device-provider.h"
-G_DEFINE_INTERFACE (IdeDeviceProvider, ide_device_provider, IDE_TYPE_OBJECT)
+typedef struct
+{
+ GPtrArray *devices;
+} IdeDeviceProviderPrivate;
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (IdeDeviceProvider, ide_device_provider, IDE_TYPE_OBJECT)
enum {
DEVICE_ADDED,
DEVICE_REMOVED,
- LAST_SIGNAL
+ N_SIGNALS
};
-static guint signals [LAST_SIGNAL];
+static guint signals [N_SIGNALS];
+
+static void
+ide_device_provider_real_load_async (IdeDeviceProvider *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_task_report_new_error (self, callback, user_data,
+ ide_device_provider_real_load_async,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ "%s does not implement load_async",
+ G_OBJECT_TYPE_NAME (self));
+}
-static GPtrArray *
-default_get_devices (IdeDeviceProvider *self)
+static gboolean
+ide_device_provider_real_load_finish (IdeDeviceProvider *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+static void
+ide_device_provider_real_device_added (IdeDeviceProvider *self,
+ IdeDevice *device)
{
- return g_ptr_array_new_with_free_func (g_object_unref);
+ IdeDeviceProviderPrivate *priv = ide_device_provider_get_instance_private (self);
+
+ g_assert (IDE_IS_DEVICE_PROVIDER (self));
+ g_assert (IDE_IS_DEVICE (device));
+
+ if (priv->devices == NULL)
+ priv->devices = g_ptr_array_new_with_free_func (g_object_unref);
+ g_ptr_array_add (priv->devices, g_object_ref (device));
+}
+
+static void
+ide_device_provider_real_device_removed (IdeDeviceProvider *self,
+ IdeDevice *device)
+{
+ IdeDeviceProviderPrivate *priv = ide_device_provider_get_instance_private (self);
+
+ g_assert (IDE_IS_DEVICE_PROVIDER (self));
+ g_assert (IDE_IS_DEVICE (device));
+
+ /* Maybe we just disposed */
+ if (priv->devices == NULL)
+ return;
+
+ if (!g_ptr_array_remove (priv->devices, device))
+ g_warning ("No such device \"%s\" found in \"%s\"",
+ G_OBJECT_TYPE_NAME (device),
+ G_OBJECT_TYPE_NAME (self));
}
static void
-ide_device_provider_default_init (IdeDeviceProviderInterface *iface)
+ide_device_provider_dispose (GObject *object)
{
- iface->get_devices = default_get_devices;
+ IdeDeviceProvider *self = (IdeDeviceProvider *)object;
+ IdeDeviceProviderPrivate *priv = ide_device_provider_get_instance_private (self);
- g_object_interface_install_property (iface,
- g_param_spec_boolean ("settled",
- "Settled",
- "If the device provider has settled",
- FALSE,
- (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
+ g_clear_pointer (&priv->devices, g_ptr_array_unref);
+ G_OBJECT_CLASS (ide_device_provider_parent_class)->dispose (object);
+}
+
+static void
+ide_device_provider_class_init (IdeDeviceProviderClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = ide_device_provider_dispose;
+
+ klass->device_added = ide_device_provider_real_device_added;
+ klass->device_removed = ide_device_provider_real_device_removed;
+ klass->load_async = ide_device_provider_real_load_async;
+ klass->load_finish = ide_device_provider_real_load_finish;
+
+ /**
+ * IdeDeviceProvider::device-added:
+ * @self: an #IdeDeviceProvider
+ * @device: an #IdeDevice
+ *
+ * The "device-added" signal is emitted when a provider has discovered
+ * a device has become available.
+ *
+ * Subclasses of #IdeDeviceManager must chain-up if they override the
+ * #IdeDeviceProviderClass.device_added vfunc.
+ *
+ * Since: 3.28
+ */
signals [DEVICE_ADDED] =
g_signal_new ("device-added",
- IDE_TYPE_DEVICE_PROVIDER,
+ G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE,
- 1,
- IDE_TYPE_DEVICE);
+ G_STRUCT_OFFSET (IdeDeviceProviderClass, device_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, IDE_TYPE_DEVICE);
+ g_signal_set_va_marshaller (signals [DEVICE_ADDED],
+ G_TYPE_FROM_CLASS (klass),
+ g_cclosure_marshal_VOID__OBJECTv);
+ /**
+ * IdeDeviceProvider::device-removed:
+ * @self: an #IdeDeviceProvider
+ * @device: an #IdeDevice
+ *
+ * The "device-removed" signal is emitted when a provider has discovered
+ * a device is no longer available.
+ *
+ * Subclasses of #IdeDeviceManager must chain-up if they override the
+ * #IdeDeviceProviderClass.device_removed vfunc.
+ *
+ * Since: 3.28
+ */
signals [DEVICE_REMOVED] =
g_signal_new ("device-removed",
- IDE_TYPE_DEVICE_PROVIDER,
+ G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE,
- 1,
- IDE_TYPE_DEVICE);
+ G_STRUCT_OFFSET (IdeDeviceProviderClass, device_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, IDE_TYPE_DEVICE);
+ g_signal_set_va_marshaller (signals [DEVICE_REMOVED],
+ G_TYPE_FROM_CLASS (klass),
+ g_cclosure_marshal_VOID__OBJECTv);
}
-gboolean
-ide_device_provider_get_settled (IdeDeviceProvider *provider)
+static void
+ide_device_provider_init (IdeDeviceProvider *self)
{
- gboolean settled = FALSE;
-
- g_return_val_if_fail (IDE_IS_DEVICE_PROVIDER (provider), FALSE);
-
- g_object_get (provider, "settled", &settled, NULL);
-
- return settled;
}
/**
- * ide_device_provider_get_devices:
+ * ide_device_provider_emit_device_added:
*
- * Retrieves a list of devices currently managed by @provider.
+ * Emits the #IdeDeviceProvider::device-added signal.
*
- * Returns: (transfer container) (element-type Ide.Device): a #GPtrArray of
- * #IdeDevice instances.
+ * This should only be called by subclasses of #IdeDeviceProvider when
+ * a new device has been discovered.
+ *
+ * Since: 3.28
*/
-GPtrArray *
-ide_device_provider_get_devices (IdeDeviceProvider *provider)
-{
- g_return_val_if_fail (IDE_IS_DEVICE_PROVIDER (provider), NULL);
-
- return IDE_DEVICE_PROVIDER_GET_IFACE (provider)->get_devices (provider);
-}
-
void
ide_device_provider_emit_device_added (IdeDeviceProvider *provider,
IdeDevice *device)
@@ -108,6 +189,16 @@ ide_device_provider_emit_device_added (IdeDeviceProvider *provider,
g_signal_emit (provider, signals [DEVICE_ADDED], 0, device);
}
+/**
+ * ide_device_provider_emit_device_removed:
+ *
+ * Emits the #IdeDeviceProvider::device-removed signal.
+ *
+ * This should only be called by subclasses of #IdeDeviceProvider when
+ * a previously added device has been removed.
+ *
+ * Since: 3.28
+ */
void
ide_device_provider_emit_device_removed (IdeDeviceProvider *provider,
IdeDevice *device)
@@ -117,3 +208,92 @@ ide_device_provider_emit_device_removed (IdeDeviceProvider *provider,
g_signal_emit (provider, signals [DEVICE_REMOVED], 0, device);
}
+
+/**
+ * ide_device_provider_load_async:
+ * @self: an #IdeDeviceProvider
+ * @cancellable: (nullable): a #GCancellable or %NULL
+ * @callback: (nullable): a #GAsyncReadyCallback to execute upon completion
+ * @user_data: closure data for @callback
+ *
+ * Requests that the #IdeDeviceProvider asynchronously load any known devices.
+ *
+ * This should only be called once on an #IdeDeviceProvider. It is an error
+ * to call this function more than once for a single #IdeDeviceProvider.
+ *
+ * #IdeDeviceProvider implementations are expected to emit the
+ * #IdeDeviceProvider::device-added signal for each device they've discovered.
+ * That should be done for known devices before returning from the asynchronous
+ * operation so that the device manager does not need to wait for additional
+ * devices to enter the "settled" state.
+ *
+ * Returns: %TRUE if successful; otherwise %FALSE and @error is set.
+ *
+ * Since: 3.28
+ */
+void
+ide_device_provider_load_async (IdeDeviceProvider *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (IDE_IS_DEVICE_PROVIDER (self));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ IDE_DEVICE_PROVIDER_GET_CLASS (self)->load_async (self, cancellable, callback, user_data);
+}
+
+/**
+ * ide_device_provider_load_finish:
+ * @self: an #IdeDeviceProvider
+ * @result: a #GAsyncResult provided to callback
+ * @error: a location for a #GError, or %NULL
+ *
+ * Completes an asynchronous request to load known devices via
+ * ide_device_provider_load_async().
+ *
+ * Returns: %TRUE if successful; otherwise %FALSE and @error is set.
+ *
+ * Since: 3.28
+ */
+gboolean
+ide_device_provider_load_finish (IdeDeviceProvider *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (IDE_IS_DEVICE_PROVIDER (self), FALSE);
+ g_return_val_if_fail (G_IS_TASK (result), FALSE);
+
+ return IDE_DEVICE_PROVIDER_GET_CLASS (self)->load_finish (self, result, error);
+}
+
+/**
+ * ide_device_provider_get_devices:
+ * @self: an #IdeDeviceProvider
+ *
+ * Gets a new #GPtrArray containing a list of #IdeDevice instances that were
+ * registered by the #IdeDeviceProvider
+ *
+ * Returns: (transfer container) (element-type Ide.Device) (not nullable):
+ * a #GPtrArray of #IdeDevice.
+ *
+ * Since: 3.28
+ */
+GPtrArray *
+ide_device_provider_get_devices (IdeDeviceProvider *self)
+{
+ IdeDeviceProviderPrivate *priv = ide_device_provider_get_instance_private (self);
+ g_autoptr(GPtrArray) devices = NULL;
+
+ g_return_val_if_fail (IDE_IS_DEVICE_PROVIDER (self), NULL);
+
+ devices = g_ptr_array_new_with_free_func (g_object_unref);
+
+ if (priv->devices != NULL)
+ {
+ for (guint i = 0; i < priv->devices->len; i++)
+ g_ptr_array_add (devices, g_object_ref (g_ptr_array_index (priv->devices, i)));
+ }
+
+ return g_steal_pointer (&devices);
+}
diff --git a/src/libide/devices/ide-device-provider.h b/src/libide/devices/ide-device-provider.h
index 8c08fb4f8..3b7c4a83d 100644
--- a/src/libide/devices/ide-device-provider.h
+++ b/src/libide/devices/ide-device-provider.h
@@ -18,34 +18,50 @@
#pragma once
-#include "ide-version-macros.h"
+#include "ide-object.h"
#include "devices/ide-device.h"
-#include "ide-object.h"
+#include "ide-version-macros.h"
G_BEGIN_DECLS
#define IDE_TYPE_DEVICE_PROVIDER (ide_device_provider_get_type())
-G_DECLARE_INTERFACE (IdeDeviceProvider, ide_device_provider, IDE, DEVICE_PROVIDER, IdeObject)
+G_DECLARE_DERIVABLE_TYPE (IdeDeviceProvider, ide_device_provider, IDE, DEVICE_PROVIDER, IdeObject)
-struct _IdeDeviceProviderInterface
+struct _IdeDeviceProviderClass
{
- GTypeInterface parent_interface;
+ IdeObjectClass parent_class;
- gboolean (*get_settled) (IdeDeviceProvider *provider);
- GPtrArray *(*get_devices) (IdeDeviceProvider *provider);
+ void (*device_added) (IdeDeviceProvider *self,
+ IdeDevice *device);
+ void (*device_removed) (IdeDeviceProvider *self,
+ IdeDevice *device);
+ void (*load_async) (IdeDeviceProvider *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*load_finish) (IdeDeviceProvider *self,
+ GAsyncResult *result,
+ GError **error);
};
IDE_AVAILABLE_IN_ALL
-void ide_device_provider_emit_device_added (IdeDeviceProvider *provider,
- IdeDevice *device);
+void ide_device_provider_emit_device_added (IdeDeviceProvider *self,
+ IdeDevice *device);
+IDE_AVAILABLE_IN_ALL
+void ide_device_provider_emit_device_removed (IdeDeviceProvider *self,
+ IdeDevice *device);
IDE_AVAILABLE_IN_ALL
-void ide_device_provider_emit_device_removed (IdeDeviceProvider *provider,
- IdeDevice *device);
+void ide_device_provider_load_async (IdeDeviceProvider *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
IDE_AVAILABLE_IN_ALL
-GPtrArray *ide_device_provider_get_devices (IdeDeviceProvider *provider);
+gboolean ide_device_provider_load_finish (IdeDeviceProvider *self,
+ GAsyncResult *result,
+ GError **error);
IDE_AVAILABLE_IN_ALL
-gboolean ide_device_provider_get_settled (IdeDeviceProvider *provider);
+GPtrArray *ide_device_provider_get_devices (IdeDeviceProvider *self);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]