[retro-gtk] Port Module to C



commit b3c76475685d25b64b04ebfad4107ede1ab5f9ff
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Thu Aug 3 01:07:39 2017 +0200

    Port Module to C
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777489

 retro-gtk/Makefile.am    |    5 +-
 retro-gtk/module.vala    |  220 --------------------------
 retro-gtk/retro-core.h   |    1 +
 retro-gtk/retro-module.c |  390 ++++++++++++++++++++++++++++++++++++++++++++++
 retro-gtk/retro-module.h |   58 +++++++
 5 files changed, 453 insertions(+), 221 deletions(-)
---
diff --git a/retro-gtk/Makefile.am b/retro-gtk/Makefile.am
index 344b4f9..a1c8ba7 100644
--- a/retro-gtk/Makefile.am
+++ b/retro-gtk/Makefile.am
@@ -51,12 +51,12 @@ libretro_gtk_la_SOURCES = \
        disk-controller.vala \
        game-info.vala \
        memory.vala \
-       module.vala \
        retro.vala \
        retro-core-descriptor.vala \
        retro-core-descriptor-error.vala \
        retro-core-view.vala \
        retro-log.c \
+       retro-module.c \
        retro-module-query.vala \
        retro-module-iterator.vala \
        rumble.vala \
@@ -79,6 +79,8 @@ retro-environment.c: retro-gtk-internal.h libretro-environment.h
 
 retro-log.c: retro-gtk-internal.h
 
+retro-module.c: retro-gtk-internal.h
+
 libretro_gtk_la_LDFLAGS =
 
 libretro_gtk_la_VALAFLAGS = \
@@ -147,6 +149,7 @@ pkgconfig_DATA = retro-gtk-0.12.pc
 EXTRA_DIST = \
        input/retro-keyboard-key.h \
        retro-core.h \
+       retro-module.h \
        retro-rotation.h \
        retro-gtk-0.12.pc.in \
        update-from-retroarch.sh \
diff --git a/retro-gtk/retro-core.h b/retro-gtk/retro-core.h
index eaa3a3c..1dde4e5 100644
--- a/retro-gtk/retro-core.h
+++ b/retro-gtk/retro-core.h
@@ -4,6 +4,7 @@
 #define RETRO_CORE_H
 
 #include "retro-gtk-internal.h"
+#include "retro-module.h"
 #include "retro-rotation.h"
 
 G_BEGIN_DECLS
diff --git a/retro-gtk/retro-module.c b/retro-gtk/retro-module.c
new file mode 100644
index 0000000..bf2d6a5
--- /dev/null
+++ b/retro-gtk/retro-module.c
@@ -0,0 +1,390 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#include <glib.h>
+#include <glib-object.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+#include <math.h>
+#include <gio/gio.h>
+#include <gmodule.h>
+#include <stdio.h>
+#include "retro-module.h"
+
+static GHashTable *retro_module_loaded_modules;
+
+struct _RetroModule
+{
+  GObject parent_instance;
+  gchar *file_name;
+  gboolean is_a_copy;
+  GFile *tmp_file;
+  GModule *module;
+  RetroCallbackSetter set_environment;
+  RetroCallbackSetter set_video_refresh;
+  RetroCallbackSetter set_audio_sample;
+  RetroCallbackSetter set_audio_sample_batch;
+  RetroCallbackSetter set_input_poll;
+  RetroCallbackSetter set_input_state;
+  RetroInit init;
+  RetroDeinit deinit;
+  RetroApiVersion api_version;
+  RetroGetSystemInfo get_system_info;
+  RetroGetSystemAvInfo get_system_av_info;
+  RetroSetControllerPortDevice set_controller_port_device;
+  RetroReset reset;
+  RetroRun run;
+  RetroSerializeSize serialize_size;
+  RetroSerialize serialize;
+  RetroUnserialize unserialize;
+  RetroLoadGame load_game;
+  RetroUnloadGame unload_game;
+  RetroGetMemoryData get_memory_data;
+  RetroGetMemorySize get_memory_size;
+};
+
+G_DEFINE_TYPE (RetroModule, retro_module, G_TYPE_OBJECT)
+
+/* Private */
+
+static void
+try_delete_file (GFile *file)
+{
+  GError *inner_error = NULL;
+
+  g_return_if_fail (file != NULL);
+
+  g_file_delete (file, NULL, &inner_error);
+  if (G_UNLIKELY (inner_error != NULL)) {
+    g_debug ("%s", inner_error->message);
+    g_clear_error (&inner_error);
+  }
+}
+
+static void
+load_module (RetroModule *self,
+             const gchar *file_name)
+{
+  self->module = g_module_open (file_name, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
+}
+
+static void
+retro_module_finalize (GObject *object)
+{
+  RetroModule *self = RETRO_MODULE (object);
+
+  if (self->tmp_file != NULL) {
+    try_delete_file (self->tmp_file);
+    g_object_unref (self->tmp_file);
+  }
+
+  if (!self->is_a_copy)
+    g_hash_table_remove (retro_module_loaded_modules, self->file_name);\
+
+  g_free (self->file_name);
+  g_module_close (self->module);
+
+  G_OBJECT_CLASS (retro_module_parent_class)->finalize (object);
+}
+
+static void
+retro_module_class_init (RetroModuleClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = retro_module_finalize;
+
+  retro_module_loaded_modules = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
+}
+
+static void
+retro_module_init (RetroModule *self)
+{
+}
+
+const gchar *
+retro_module_get_file_name (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->file_name;
+}
+
+/* Public */
+
+RetroModule *
+retro_module_new (const gchar *file_name)
+{
+  RetroModule *self = NULL;
+  GFile *file;
+  GFileIOStream *ios = NULL;
+  GFile *absolute_path_file;
+  gchar *tmp_file_name;
+  gpointer function;
+  GError *inner_error = NULL;
+
+  g_return_val_if_fail (file_name != NULL, NULL);
+
+  self = (RetroModule*) g_object_new (RETRO_TYPE_MODULE, NULL);
+
+  file = g_file_new_for_path (file_name);
+  absolute_path_file = g_file_resolve_relative_path (file, "");
+  self->file_name = g_file_get_path (absolute_path_file);
+  self->is_a_copy = FALSE;
+
+  if (g_hash_table_contains (retro_module_loaded_modules, self->file_name)) {
+    file = g_file_new_for_path (self->file_name);
+    self->tmp_file = g_file_new_tmp (NULL, &ios, &inner_error);
+    if (G_UNLIKELY (inner_error != NULL)) {
+      g_debug ("%s", inner_error->message);
+
+      if (self->tmp_file != NULL) {
+        try_delete_file (self->tmp_file);
+        g_clear_object (&self->tmp_file);
+      }
+
+      self->is_a_copy = FALSE;
+      load_module (self, self->file_name);
+      g_clear_error (&inner_error);
+    }
+    g_file_copy (file, self->tmp_file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &inner_error);
+    if (G_UNLIKELY (inner_error != NULL)) {
+      g_debug ("%s", inner_error->message);
+
+      if (self->tmp_file != NULL) {
+        try_delete_file (self->tmp_file);
+        g_clear_object (&self->tmp_file);
+      }
+
+      self->is_a_copy = FALSE;
+      load_module (self, self->file_name);
+      g_clear_error (&inner_error);
+    }
+    self->is_a_copy = TRUE;
+    tmp_file_name = g_file_get_path (self->tmp_file);
+    load_module (self, self->file_name);
+    g_free (tmp_file_name);
+
+    if (ios != NULL)
+      g_object_unref (ios);
+    if (file != NULL)
+      g_object_unref (file);
+  }
+  else {
+    g_hash_table_add (retro_module_loaded_modules, g_strdup (self->file_name));
+    load_module (self, self->file_name);
+  }
+
+  g_module_symbol (self->module, "retro_set_environment", &function);
+  self->set_environment = (RetroCallbackSetter) function;
+  g_module_symbol (self->module, "retro_set_video_refresh", &function);
+  self->set_video_refresh = (RetroCallbackSetter) function;
+  g_module_symbol (self->module, "retro_set_audio_sample", &function);
+  self->set_audio_sample = (RetroCallbackSetter) function;
+  g_module_symbol (self->module, "retro_set_audio_sample_batch", &function);
+  self->set_audio_sample_batch = (RetroCallbackSetter) function;
+  g_module_symbol (self->module, "retro_set_input_poll", &function);
+  self->set_input_poll = (RetroCallbackSetter) function;
+  g_module_symbol (self->module, "retro_set_input_state", &function);
+  self->set_input_state = (RetroCallbackSetter) function;
+  g_module_symbol (self->module, "retro_init", &function);
+  self->init = (RetroInit) function;
+  g_module_symbol (self->module, "retro_deinit", &function);
+  self->deinit = (RetroDeinit) function;
+  g_module_symbol (self->module, "retro_api_version", &function);
+  self->api_version = (RetroApiVersion) function;
+  g_module_symbol (self->module, "retro_get_system_info", &function);
+  self->get_system_info = (RetroGetSystemInfo) function;
+  g_module_symbol (self->module, "retro_get_system_av_info", &function);
+  self->get_system_av_info = (RetroGetSystemAvInfo) function;
+  g_module_symbol (self->module, "retro_set_controller_port_device", &function);
+  self->set_controller_port_device = (RetroSetControllerPortDevice) function;
+  g_module_symbol (self->module, "retro_reset", &function);
+  self->reset = (RetroReset) function;
+  g_module_symbol (self->module, "retro_run", &function);
+  self->run = (RetroRun) function;
+  g_module_symbol (self->module, "retro_serialize_size", &function);
+  self->serialize_size = (RetroSerializeSize) function;
+  g_module_symbol (self->module, "retro_serialize", &function);
+  self->serialize = (RetroSerialize) function;
+  g_module_symbol (self->module, "retro_unserialize", &function);
+  self->unserialize = (RetroUnserialize) function;
+  g_module_symbol (self->module, "retro_load_game", &function);
+  self->load_game = (RetroLoadGame) function;
+  g_module_symbol (self->module, "retro_unload_game", &function);
+  self->unload_game = (RetroUnloadGame) function;
+  g_module_symbol (self->module, "retro_get_memory_data", &function);
+  self->get_memory_data = (RetroGetMemoryData) function;
+  g_module_symbol (self->module, "retro_get_memory_size", &function);
+  self->get_memory_size = (RetroGetMemorySize) function;
+
+  return self;
+}
+
+RetroCallbackSetter
+retro_module_get_set_environment (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->set_environment;
+}
+
+RetroCallbackSetter
+retro_module_get_set_video_refresh (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->set_video_refresh;
+}
+
+RetroCallbackSetter
+retro_module_get_set_audio_sample (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->set_audio_sample;
+}
+
+RetroCallbackSetter
+retro_module_get_set_audio_sample_batch (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->set_audio_sample_batch;
+}
+
+RetroCallbackSetter
+retro_module_get_set_input_poll (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->set_input_poll;
+}
+
+RetroCallbackSetter
+retro_module_get_set_input_state (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->set_input_state;
+}
+
+RetroInit
+retro_module_get_init (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->init;
+}
+
+RetroDeinit
+retro_module_get_deinit (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->deinit;
+}
+
+RetroApiVersion
+retro_module_get_api_version (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->api_version;
+}
+
+RetroGetSystemInfo
+retro_module_get_get_system_info (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->get_system_info;
+}
+
+RetroGetSystemAvInfo
+retro_module_get_get_system_av_info (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->get_system_av_info;
+}
+
+RetroSetControllerPortDevice
+retro_module_get_set_controller_port_device (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->set_controller_port_device;
+}
+
+RetroReset
+retro_module_get_reset (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->reset;
+}
+
+RetroRun
+retro_module_get_run (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->run;
+}
+
+RetroSerializeSize
+retro_module_get_serialize_size (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->serialize_size;
+}
+
+RetroSerialize
+retro_module_get_serialize (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->serialize;
+}
+
+RetroUnserialize
+retro_module_get_unserialize (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->unserialize;
+}
+
+RetroLoadGame
+retro_module_get_load_game (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->load_game;
+}
+
+RetroUnloadGame
+retro_module_get_unload_game (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->unload_game;
+}
+
+RetroGetMemoryData
+retro_module_get_get_memory_data (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->get_memory_data;
+}
+
+RetroGetMemorySize
+retro_module_get_get_memory_size (RetroModule *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->get_memory_size;
+}
diff --git a/retro-gtk/retro-module.h b/retro-gtk/retro-module.h
new file mode 100644
index 0000000..9667ed9
--- /dev/null
+++ b/retro-gtk/retro-module.h
@@ -0,0 +1,58 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#ifndef RETRO_MODULE_H
+#define RETRO_MODULE_H
+
+#include <glib-object.h>
+#include "retro-gtk-internal.h"
+
+G_BEGIN_DECLS
+
+typedef gboolean (*RetroLoadGame) (RetroGameInfo *game);
+typedef gboolean (*RetroSerialize) (guint8 *data, gint length);
+typedef gboolean (*RetroUnserialize) (guint8 *data, gint length);
+typedef gsize (*RetroGetMemorySize) (RetroMemoryType id);
+typedef gsize (*RetroSerializeSize) ();
+typedef guint (*RetroApiVersion) ();
+typedef void (*RetroCallbackSetter) (gpointer cb);
+typedef void (*RetroDeinit) ();
+typedef gpointer (*RetroGetMemoryData) (RetroMemoryType id);
+typedef void (*RetroGetSystemAvInfo) (RetroSystemAvInfo *info);
+typedef void (*RetroGetSystemInfo) (RetroSystemInfo *info);
+typedef void (*RetroInit) ();
+typedef void (*RetroReset) ();
+typedef void (*RetroRun) ();
+typedef void (*RetroSetControllerPortDevice) (guint port, RetroDeviceType device);
+typedef void (*RetroUnloadGame) ();
+
+#define RETRO_TYPE_MODULE (retro_module_get_type())
+
+G_DECLARE_FINAL_TYPE (RetroModule, retro_module, RETRO, MODULE, GObject)
+
+RetroModule *retro_module_new (const gchar *file_name);
+const gchar *retro_module_get_file_name (RetroModule *self);
+RetroCallbackSetter retro_module_get_set_environment (RetroModule *self);
+RetroCallbackSetter retro_module_get_set_video_refresh (RetroModule *self);
+RetroCallbackSetter retro_module_get_set_audio_sample (RetroModule *self);
+RetroCallbackSetter retro_module_get_set_audio_sample_batch (RetroModule *self);
+RetroCallbackSetter retro_module_get_set_input_poll (RetroModule *self);
+RetroCallbackSetter retro_module_get_set_input_state (RetroModule *self);
+RetroInit retro_module_get_init (RetroModule *self);
+RetroDeinit retro_module_get_deinit (RetroModule *self);
+RetroApiVersion retro_module_get_api_version (RetroModule *self);
+RetroGetSystemInfo retro_module_get_get_system_info (RetroModule *self);
+RetroGetSystemAvInfo retro_module_get_get_system_av_info (RetroModule *self);
+RetroSetControllerPortDevice retro_module_get_set_controller_port_device (RetroModule *self);
+RetroReset retro_module_get_reset (RetroModule *self);
+RetroRun retro_module_get_run (RetroModule *self);
+RetroSerializeSize retro_module_get_serialize_size (RetroModule *self);
+RetroSerialize retro_module_get_serialize (RetroModule *self);
+RetroUnserialize retro_module_get_unserialize (RetroModule *self);
+RetroLoadGame retro_module_get_load_game (RetroModule *self);
+RetroUnloadGame retro_module_get_unload_game (RetroModule *self);
+RetroGetMemoryData retro_module_get_get_memory_data (RetroModule *self);
+RetroGetMemorySize retro_module_get_get_memory_size (RetroModule *self);
+
+G_END_DECLS
+
+#endif /* RETRO_MODULE_H */


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