[gnome-games/wip/aplazas/781572-remove-vala-macro: 11/11] gamepad: Port GamepadMonitor to C



commit 6456b6556407bfb76dc78611324afd88dd03aea3
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Wed Apr 26 08:42:49 2017 +0200

    gamepad: Port GamepadMonitor to C
    
    This finishes porting part of the gamepad handling to C to avoid using
    Vala macros.

 src/Makefile.am                   |    4 +-
 src/gamepad/gamepad-monitor.c     |  255 +++++++++++++++++++++++++++++++++++++
 src/gamepad/gamepad-monitor.h     |   22 +++
 src/gamepad/gamepad-monitor.vapi  |    8 +
 src/gamepad/raw-gamepad-monitor.h |    4 +-
 5 files changed, 291 insertions(+), 2 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 604ff67..2124de7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,6 +23,7 @@ BUILT_SOURCES = \
 
 EXTRA_DIST = \
        $(gresource_file) \
+       gamepad/gamepad-monitor.vapi \
        gamepad/linux/linux-raw-gamepad-monitor.vapi \
        gamepad/raw-gamepad.vapi \
        gamepad/raw-gamepad-monitor.vapi \
@@ -78,7 +79,7 @@ gnome_games_SOURCES = \
        gamepad/gamepad-mapping.vala \
        gamepad/gamepad-mapping-error.vala \
        gamepad/gamepad-mappings-manager.vala \
-       gamepad/gamepad-monitor.vala \
+       gamepad/gamepad-monitor.c \
        gamepad/raw-gamepad.c \
        gamepad/raw-gamepad-monitor.c \
        gamepad/standard-gamepad-axis.c \
@@ -182,6 +183,7 @@ gnome_games_VALAFLAGS = \
        --pkg retro-gtk-0.10 \
        --pkg linux \
        --pkg posix \
+       --pkg gamepad-monitor \
        --pkg raw-gamepad \
        --pkg raw-gamepad-monitor \
        --pkg standard-gamepad-axis \
diff --git a/src/gamepad/gamepad-monitor.c b/src/gamepad/gamepad-monitor.c
new file mode 100644
index 0000000..273d1fd
--- /dev/null
+++ b/src/gamepad/gamepad-monitor.c
@@ -0,0 +1,255 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+#include "gamepad-monitor.h"
+
+#include "raw-gamepad-monitor.h"
+//#include "raw-gamepad.h"
+
+#define GAMES_TYPE_GAMEPAD_MONITOR (games_gamepad_monitor_get_type ())
+#define GAMES_GAMEPAD_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAMES_TYPE_GAMEPAD_MONITOR, 
GamesGamepadMonitor))
+#define GAMES_GAMEPAD_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAMES_TYPE_GAMEPAD_MONITOR, 
GamesGamepadMonitorClass))
+#define GAMES_IS_GAMEPAD_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAMES_TYPE_GAMEPAD_MONITOR))
+#define GAMES_IS_GAMEPAD_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAMES_TYPE_GAMEPAD_MONITOR))
+#define GAMES_GAMEPAD_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAMES_TYPE_GAMEPAD_MONITOR, 
GamesGamepadMonitorClass))
+
+typedef struct _GamesGamepadMonitor GamesGamepadMonitor;
+typedef struct _GamesGamepadMonitorClass GamesGamepadMonitorClass;
+
+#define GAMES_TYPE_GAMEPAD (games_gamepad_get_type ())
+#define GAMES_GAMEPAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAMES_TYPE_GAMEPAD, GamesGamepad))
+#define GAMES_GAMEPAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAMES_TYPE_GAMEPAD, GamesGamepadClass))
+#define GAMES_IS_GAMEPAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAMES_TYPE_GAMEPAD))
+#define GAMES_IS_GAMEPAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAMES_TYPE_GAMEPAD))
+#define GAMES_GAMEPAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAMES_TYPE_GAMEPAD, 
GamesGamepadClass))
+
+typedef struct _GamesGamepad GamesGamepad;
+typedef struct _GamesGamepadClass GamesGamepadClass;
+#define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL)))
+
+#define GAMES_TYPE_LINUX_RAW_GAMEPAD_MONITOR (games_linux_raw_gamepad_monitor_get_type ())
+#define GAMES_LINUX_RAW_GAMEPAD_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GAMES_TYPE_LINUX_RAW_GAMEPAD_MONITOR, GamesLinuxRawGamepadMonitor))
+#define GAMES_LINUX_RAW_GAMEPAD_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), 
GAMES_TYPE_LINUX_RAW_GAMEPAD_MONITOR, GamesLinuxRawGamepadMonitorClass))
+#define GAMES_IS_LINUX_RAW_GAMEPAD_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
GAMES_TYPE_LINUX_RAW_GAMEPAD_MONITOR))
+#define GAMES_IS_LINUX_RAW_GAMEPAD_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), 
GAMES_TYPE_LINUX_RAW_GAMEPAD_MONITOR))
+#define GAMES_LINUX_RAW_GAMEPAD_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), 
GAMES_TYPE_LINUX_RAW_GAMEPAD_MONITOR, GamesLinuxRawGamepadMonitorClass))
+
+typedef struct _GamesLinuxRawGamepadMonitor GamesLinuxRawGamepadMonitor;
+typedef struct _GamesLinuxRawGamepadMonitorClass GamesLinuxRawGamepadMonitorClass;
+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
+#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
+enum
+{
+  SIGNAL_PLUGGED,
+  LAST_SIGNAL,
+};
+static guint signals[LAST_SIGNAL] = { 0 };
+
+struct _GamesGamepadMonitor {
+  GObject parent_instance;
+  GHashTable *gamepads;
+};
+
+struct _GamesGamepadMonitorClass {
+  GObjectClass parent_class;
+};
+
+typedef enum {
+  GAMES_GAMEPAD_MAPPING_ERROR_NOT_A_MAPPING,
+} GamesGamepadMappingError;
+#define GAMES_GAMEPAD_MAPPING_ERROR games_gamepad_mapping_error_quark ()
+
+static gpointer games_gamepad_monitor_parent_class = NULL;
+static GamesGamepadMonitor *instance;
+static GamesGamepadMonitor *instance = NULL;
+
+GType games_gamepad_monitor_get_type (void) G_GNUC_CONST;
+GType games_gamepad_get_type (void) G_GNUC_CONST;
+
+static GamesGamepadMonitor *games_gamepad_monitor_new (void);
+static GamesGamepadMonitor *games_gamepad_monitor_construct (GType object_type);
+GType games_linux_raw_gamepad_monitor_get_type (void) G_GNUC_CONST;
+GamesLinuxRawGamepadMonitor *games_linux_raw_gamepad_monitor_get_instance (void);
+static void on_raw_gamepad_plugged (GamesGamepadMonitor *self, GamesRawGamepad *raw_gamepad);
+static void _on_raw_gamepad_plugged_games_raw_gamepad_monitor_gamepad_plugged (GamesRawGamepadMonitor 
*_sender, GamesRawGamepad *raw_gamepad, gpointer self);
+static GamesGamepad *add_gamepad (GamesGamepadMonitor *self, GamesRawGamepad *raw_gamepad);
+static void foreach_raw_gamepad_do (GamesRawGamepad *raw_gamepad, gpointer self);
+GamesGamepadMonitor *games_gamepad_monitor_get_instance (void);
+void games_gamepad_monitor_foreach_gamepad (GamesGamepadMonitor *self, GamesGamepadCallback callback, void 
*callback_target);
+GQuark games_gamepad_mapping_error_quark (void);
+GamesGamepad *games_gamepad_new (GamesRawGamepad *raw_gamepad, GError **error);
+GamesGamepad *games_gamepad_construct (GType object_type, GamesRawGamepad *raw_gamepad, GError **error);
+static void games_gamepad_monitor_finalize (GObject *obj);
+
+static void _on_raw_gamepad_plugged_games_raw_gamepad_monitor_gamepad_plugged (GamesRawGamepadMonitor 
*_sender, GamesRawGamepad *raw_gamepad, gpointer self) {
+  on_raw_gamepad_plugged ((GamesGamepadMonitor*) self, raw_gamepad);
+}
+
+static void
+foreach_raw_gamepad_do (GamesRawGamepad *raw_gamepad, gpointer data)
+{
+  GamesGamepadMonitor *self;
+  GamesGamepad *gamepad;
+
+  self = GAMES_GAMEPAD_MONITOR (self);
+
+  g_return_if_fail (self != NULL);
+  g_return_if_fail (raw_gamepad != NULL);
+
+  gamepad = add_gamepad (self, raw_gamepad);
+  if (gamepad != NULL)
+    g_object_unref (gamepad);
+}
+
+static GamesGamepadMonitor *
+games_gamepad_monitor_new (void)
+{
+  GamesGamepadMonitor *self = NULL;
+  GamesLinuxRawGamepadMonitor *raw_gamepad_monitor;
+
+  self = (GamesGamepadMonitor*) g_object_new (GAMES_TYPE_GAMEPAD_MONITOR, NULL);
+  self->gamepads = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
+
+#if ENABLE_LINUX_GAMEPADS
+  raw_gamepad_monitor = games_linux_raw_gamepad_monitor_get_instance ();
+  g_signal_connect_object ((GamesRawGamepadMonitor*) raw_gamepad_monitor, "gamepad-plugged", (GCallback) 
_on_raw_gamepad_plugged_games_raw_gamepad_monitor_gamepad_plugged, self, 0);
+  games_raw_gamepad_monitor_foreach_gamepad ((GamesRawGamepadMonitor*) raw_gamepad_monitor, 
foreach_raw_gamepad_do, self);
+  g_object_unref (raw_gamepad_monitor);
+#endif / *ENABLE_LINUX_GAMEPADS */
+
+  return self;
+}
+
+static void
+remove_gamepad (GamesGamepadMonitor *self,
+                GamesGamepad        *gamepad)
+{
+  g_return_if_fail (self != NULL);
+  g_return_if_fail (gamepad != NULL);
+
+  g_hash_table_remove (self->gamepads, gamepad);
+}
+
+static void
+on_gamepad_unplugged (GamesGamepad *sender,
+                      gpointer      self)
+{
+  remove_gamepad (GAMES_GAMEPAD_MONITOR (self), sender);
+}
+
+static GamesGamepad *
+add_gamepad (GamesGamepadMonitor *self,
+             GamesRawGamepad     *raw_gamepad)
+{
+  GamesGamepad *gamepad = NULL;
+  GError *_inner_error_ = NULL;
+
+  g_return_val_if_fail (self != NULL, NULL);
+  g_return_val_if_fail (raw_gamepad != NULL, NULL);
+
+  gamepad = games_gamepad_new (raw_gamepad, &_inner_error_);
+  if (G_UNLIKELY (_inner_error_ != NULL))
+  {
+    g_error_free (_inner_error_);
+    g_assert (gamepad == NULL);
+
+    return NULL;
+  }
+
+  g_assert (gamepad != NULL);
+
+  g_hash_table_add (self->gamepads, g_object_ref (gamepad));
+  g_signal_connect_object (gamepad, "unplugged",
+                           (GCallback) on_gamepad_unplugged,
+                           self, 0);
+
+  return gamepad;
+}
+
+static void
+on_raw_gamepad_plugged (GamesGamepadMonitor *self,
+                        GamesRawGamepad     *raw_gamepad)
+{
+  GamesGamepad *gamepad;
+
+  g_return_if_fail (self != NULL);
+  g_return_if_fail (raw_gamepad != NULL);
+
+  gamepad = add_gamepad (self, raw_gamepad);
+  if (gamepad != NULL)
+  {
+    g_signal_emit (self, signals[SIGNAL_PLUGGED], 0, gamepad);
+    g_object_unref (gamepad);
+  }
+}
+
+/* Public */
+
+GamesGamepadMonitor *
+games_gamepad_monitor_get_instance (void)
+{
+  if (instance == NULL)
+    instance = games_gamepad_monitor_new ();
+
+  return g_object_ref (instance);
+}
+
+void
+games_gamepad_monitor_foreach_gamepad (GamesGamepadMonitor  *self,
+                                       GamesGamepadCallback  callback,
+                                       gpointer              callback_target)
+{
+  GHashTableIter iter = { 0 };
+  GamesGamepad *gamepad = NULL;
+
+  g_return_if_fail (self != NULL);
+
+  g_hash_table_iter_init (&iter, self->gamepads);
+  while (g_hash_table_iter_next (&iter, (gpointer *) &gamepad, NULL))
+    callback (gamepad, callback_target);
+}
+
+/* Type */
+
+static void games_gamepad_monitor_class_init (GamesGamepadMonitorClass *klass) {
+  games_gamepad_monitor_parent_class = g_type_class_peek_parent (klass);
+  G_OBJECT_CLASS (klass)->finalize = games_gamepad_monitor_finalize;
+  /**
+   * Emitted when a gamepad is plugged in.
+   * This would be emitted once even if RawGamepadMonitor emits it multiple
+   * times
+   * @param gamepad The gamepad
+   */
+  signals[SIGNAL_PLUGGED] =
+    g_signal_new ("gamepad_plugged",
+                  GAMES_TYPE_GAMEPAD_MONITOR,
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  g_cclosure_marshal_VOID__OBJECT,
+                  G_TYPE_NONE, 1, GAMES_TYPE_GAMEPAD);
+}
+
+static void instance_init (GamesGamepadMonitor *self) {
+}
+
+static void games_gamepad_monitor_finalize (GObject *obj) {
+  GamesGamepadMonitor *self;
+  self = G_TYPE_CHECK_INSTANCE_CAST (obj, GAMES_TYPE_GAMEPAD_MONITOR, GamesGamepadMonitor);
+  _g_hash_table_unref0 (self->gamepads);
+  G_OBJECT_CLASS (games_gamepad_monitor_parent_class)->finalize (obj);
+}
+
+/**
+ * This class provides a way to the client to monitor gamepads
+ *
+ * The client interfaces with this class primarily
+ */
+GType games_gamepad_monitor_get_type (void) {
+  static volatile gsize games_gamepad_monitor_type_id__volatile = 0;
+  if (g_once_init_enter (&games_gamepad_monitor_type_id__volatile)) {
+    static const GTypeInfo g_define_type_info = { sizeof (GamesGamepadMonitorClass), (GBaseInitFunc) NULL, 
(GBaseFinalizeFunc) NULL, (GClassInitFunc) games_gamepad_monitor_class_init, (GClassFinalizeFunc) NULL, NULL, 
sizeof (GamesGamepadMonitor), 0, (GInstanceInitFunc) instance_init, NULL };
+    GType games_gamepad_monitor_type_id;
+    games_gamepad_monitor_type_id = g_type_register_static (G_TYPE_OBJECT, "GamesGamepadMonitor", 
&g_define_type_info, 0);
+    g_once_init_leave (&games_gamepad_monitor_type_id__volatile, games_gamepad_monitor_type_id);
+  }
+  return games_gamepad_monitor_type_id__volatile;
+}
diff --git a/src/gamepad/gamepad-monitor.h b/src/gamepad/gamepad-monitor.h
new file mode 100644
index 0000000..62efeb5
--- /dev/null
+++ b/src/gamepad/gamepad-monitor.h
@@ -0,0 +1,22 @@
+#ifndef GAMES_GAMEPAD_MONITOR_H
+#define GAMES_GAMEPAD_MONITOR_H
+
+#include <glib-object.h>
+#include "gamepad.h"
+
+G_BEGIN_DECLS
+
+typedef void (*GamesGamepadCallback) (GamesGamepad *gamepad, gpointer user_data);
+
+#define GAMES_TYPE_GAMEPAD_MONITOR (games_gamepad_monitor_get_type())
+
+G_DECLARE_FINAL_TYPE (GamesGamepadMonitor, games_gamepad_monitor, GAMES, GAMEPAD_MONITOR, GObject)
+
+GamesGamepadMonitor *games_gamepad_monitor_get_instance (void);
+void games_gamepad_monitor_foreach_gamepad (GamesGamepadMonitor  *self,
+                                            GamesGamepadCallback  callback,
+                                            gpointer              callback_target);
+
+G_END_DECLS
+
+#endif /* GAMES_GAMEPAD_MONITOR_H */
diff --git a/src/gamepad/gamepad-monitor.vapi b/src/gamepad/gamepad-monitor.vapi
new file mode 100644
index 0000000..027caae
--- /dev/null
+++ b/src/gamepad/gamepad-monitor.vapi
@@ -0,0 +1,8 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+[CCode (cheader_filename = "gamepad-monitor.h")]
+private class Games.GamepadMonitor : GLib.Object {
+       public signal void gamepad_plugged (Gamepad gamepad);
+       public static GamepadMonitor get_instance ();
+       public void foreach_gamepad (GamepadCallback callback);
+}
diff --git a/src/gamepad/raw-gamepad-monitor.h b/src/gamepad/raw-gamepad-monitor.h
index 7ac4f19..c771e3a 100644
--- a/src/gamepad/raw-gamepad-monitor.h
+++ b/src/gamepad/raw-gamepad-monitor.h
@@ -27,7 +27,9 @@ struct _GamesRawGamepadMonitorInterface
 // FIXME Remove this once every piece using it has been moved to C.
 typedef struct _GamesRawGamepadMonitorInterface GamesRawGamepadMonitorIface;
 
-const gchar *games_raw_gamepad_monitor_get_guid (GamesRawGamepadMonitor *self);
+void games_raw_gamepad_monitor_foreach_gamepad (GamesRawGamepadMonitor  *self,
+                                                GamesRawGamepadCallback  callback,
+                                                gpointer                 data);
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]