[retro-gtk: 2/2] Port the variable interface to C
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [retro-gtk: 2/2] Port the variable interface to C
- Date: Tue, 12 Sep 2017 09:57:18 +0000 (UTC)
commit f9f780192e5c5def12b31d782b9038e29aaa4dd4
Author: Adrien Plazas <kekun plazas laposte net>
Date: Thu May 18 16:33:22 2017 +0200
Port the variable interface to C
Also tweak the API to make it simpler and drop the useless Variables
interface.
https://bugzilla.gnome.org/show_bug.cgi?id=782501
retro-gtk/Makefile.am | 8 +-
retro-gtk/core.vala | 2 -
retro-gtk/retro-core.c | 2 +-
retro-gtk/retro-core.h | 2 +
retro-gtk/retro-environment.c | 33 ++++--
retro-gtk/retro-option.c | 160 ++++++++++++++++++++++++++++
retro-gtk/retro-option.h | 27 +++++
retro-gtk/retro-options.c | 187 +++++++++++++++++++++++++++++++++
retro-gtk/retro-options.h | 35 ++++++
retro-gtk/retro-variable.h | 20 ++++
retro-gtk/variable/options.vala | 206 -------------------------------------
retro-gtk/variable/variables.vala | 67 ------------
12 files changed, 458 insertions(+), 291 deletions(-)
---
diff --git a/retro-gtk/Makefile.am b/retro-gtk/Makefile.am
index b506789..ad059da 100644
--- a/retro-gtk/Makefile.am
+++ b/retro-gtk/Makefile.am
@@ -38,9 +38,6 @@ libretro_gtk_la_SOURCES = \
\
loop/main-loop.vala \
\
- variable/options.vala \
- variable/variables.vala \
- \
core.vala \
core-error.vala \
memory.vala \
@@ -55,6 +52,8 @@ libretro_gtk_la_SOURCES = \
retro-module.c \
retro-module-query.vala \
retro-module-iterator.vala \
+ retro-option.c \
+ retro-options.c \
rumble.vala \
video.vala \
retro-core.c \
@@ -107,6 +106,9 @@ libretro_gtk_la_LIBADD = $(RETRO_GTK_LIBS)
retro_gtkincludedir = $(includedir)/retro-gtk-0.12
retro_gtkinclude_HEADERS = \
retro-gtk.h \
+ retro-option.h \
+ retro-options.h \
+ retro-variable.h \
$(NULL)
# Add unstable API guard
diff --git a/retro-gtk/core.vala b/retro-gtk/core.vala
index e898f2f..3778337 100644
--- a/retro-gtk/core.vala
+++ b/retro-gtk/core.vala
@@ -138,8 +138,6 @@ public class Core : Object {
*/
public signal bool message (string message, uint frames);
- internal Variables variables_interface;
-
internal void *environment_internal;
/**
diff --git a/retro-gtk/retro-core.c b/retro-gtk/retro-core.c
index d925c85..5ff2763 100644
--- a/retro-gtk/retro-core.c
+++ b/retro-gtk/retro-core.c
@@ -668,7 +668,7 @@ retro_core_constructor (RetroCore *self,
g_free (libretro_path);
retro_core_set_callbacks (self);
- self->variables_interface = RETRO_VARIABLES (retro_options_new ());
+ internal->options = retro_options_new ();
}
// FIXME Make static as soon as possible.
diff --git a/retro-gtk/retro-core.h b/retro-gtk/retro-core.h
index d651c05..b5c9369 100644
--- a/retro-gtk/retro-core.h
+++ b/retro-gtk/retro-core.h
@@ -6,6 +6,7 @@
#include "retro-disk-control-callback.h"
#include "retro-gtk-internal.h"
#include "retro-module.h"
+#include "retro-options.h"
#include "retro-rotation.h"
G_BEGIN_DECLS
@@ -30,6 +31,7 @@ struct _RetroCoreEnvironmentInternal {
gdouble sample_rate;
RetroKeyboardCallback keyboard_callback;
+ RetroOptions *options;
};
gchar *retro_core_get_name (RetroCore *self);
diff --git a/retro-gtk/retro-environment.c b/retro-gtk/retro-environment.c
index b401556..afef623 100644
--- a/retro-gtk/retro-environment.c
+++ b/retro-gtk/retro-environment.c
@@ -195,20 +195,29 @@ static gboolean
get_variable (RetroCore *self,
RetroVariable *variable)
{
- gchar *result;
+ RetroCoreEnvironmentInternal *internal;
+ const gchar *value;
+
+ internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
- result = retro_variables_get_variable (self->variables_interface,
- variable->key);
- variable->value = result ? result : "";
+ if (!retro_options_contains (internal->options, variable->key))
+ return FALSE;
- return !!result;
+ value = retro_options_get_option_value (internal->options, variable->key);
+ variable->value = g_strdup (value); // FIXME Is that a memory leak?
+
+ return TRUE;
}
static gboolean
get_variable_update (RetroCore *self,
gboolean *update)
{
- *update = retro_variables_get_variable_update (self->variables_interface);
+ RetroCoreEnvironmentInternal *internal;
+
+ internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+
+ *update = retro_options_get_variable_update (internal->options);
return TRUE;
}
@@ -299,13 +308,13 @@ static gboolean
set_variables (RetroCore *self,
RetroVariable *variable_array)
{
- int length;
+ RetroCoreEnvironmentInternal *internal;
+ int i;
+
+ internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
- for (length = 0 ;
- variable_array[length].key && variable_array[length].value ;
- length++);
- retro_variables_set_variable (self->variables_interface,
- variable_array, length);
+ for (i = 0 ; variable_array[i].key && variable_array[i].value ; i++)
+ retro_options_insert_variable (internal->options, &variable_array[i]);
return TRUE;
}
diff --git a/retro-gtk/retro-option.c b/retro-gtk/retro-option.c
new file mode 100644
index 0000000..2368293
--- /dev/null
+++ b/retro-gtk/retro-option.c
@@ -0,0 +1,160 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#include "retro-option.h"
+
+struct _RetroOption
+{
+ GObject parent_instance;
+ gchar *key;
+ gchar *description;
+ gchar **values;
+ gchar *current;
+};
+
+G_DEFINE_TYPE (RetroOption, retro_option, G_TYPE_OBJECT)
+
+#define RETRO_OPTION_ERROR (retro_option_error_quark ())
+
+enum {
+ RETRO_OPTION_ERROR_NO_DESCRIPTION_SEPARATOR,
+ RETRO_OPTION_ERROR_NO_VALUES,
+ RETRO_OPTION_ERROR_INVALID_VALUE,
+};
+
+/* Private */
+
+static GQuark
+retro_option_error_quark (void)
+{
+ return g_quark_from_static_string ("retro-option-error-quark");
+}
+
+static void
+retro_option_finalize (GObject *object)
+{
+ RetroOption *self = (RetroOption *)object;
+
+ g_free (self->key);
+ g_free (self->description);
+ g_strfreev (self->values);
+ g_free (self->current);
+
+ G_OBJECT_CLASS (retro_option_parent_class)->finalize (object);
+}
+
+static void
+retro_option_class_init (RetroOptionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = retro_option_finalize;
+}
+
+static void
+retro_option_init (RetroOption *self)
+{
+}
+
+/* Public */
+
+const gchar *
+retro_option_get_key (RetroOption *self)
+{
+ g_return_val_if_fail (RETRO_IS_OPTION (self), NULL);
+
+ return self->key;
+}
+
+const gchar *
+retro_option_get_description (RetroOption *self)
+{
+ g_return_val_if_fail (RETRO_IS_OPTION (self), NULL);
+
+ return self->description;
+}
+
+const gchar **
+retro_option_get_values (RetroOption *self)
+{
+ g_return_val_if_fail (RETRO_IS_OPTION (self), NULL);
+
+ return self->values;
+}
+
+const gchar *
+retro_option_get_current (RetroOption *self)
+{
+ g_return_val_if_fail (RETRO_IS_OPTION (self), NULL);
+
+ return self->current;
+}
+
+void
+retro_option_set_current (RetroOption *self,
+ const gchar *current,
+ GError **error)
+{
+ g_return_if_fail (RETRO_IS_OPTION (self));
+ g_return_if_fail (current != NULL);
+
+ g_message ("%s, %s", self->current, current);
+ if (g_strcmp0 (self->current, current) == 0)
+ return;
+
+ if (G_UNLIKELY (g_strv_contains ((const gchar *const *) self->values, current))) {
+ g_set_error_literal (error,
+ RETRO_OPTION_ERROR,
+ RETRO_OPTION_ERROR_INVALID_VALUE,
+ "Unexpected option value: option %s doesn’t have value %s.");
+
+ return;
+ }
+
+ g_free (self->current);
+ self->current = g_strdup (current);
+}
+
+RetroOption *
+retro_option_new (const RetroVariable *variable,
+ GError **error)
+{
+ RetroOption *self;
+ gchar *description_separator;
+ gchar **values;
+
+ g_return_val_if_fail (variable != NULL, NULL);
+ g_return_val_if_fail (variable->key != NULL, NULL);
+ g_return_val_if_fail (variable->value != NULL, NULL);
+
+ description_separator = g_strstr_len (variable->value, -1, "; ");
+ if (G_UNLIKELY (description_separator == NULL)) {
+ g_set_error_literal (error,
+ RETRO_OPTION_ERROR,
+ RETRO_OPTION_ERROR_NO_DESCRIPTION_SEPARATOR,
+ "Unexpected variable format: no description separator found.");
+
+ return NULL;
+ }
+
+ values = g_strsplit (description_separator + 2, "|", 0);
+ if (G_UNLIKELY (*values == NULL)) {
+ g_strfreev (values);
+
+ g_set_error_literal (error,
+ RETRO_OPTION_ERROR,
+ RETRO_OPTION_ERROR_NO_VALUES,
+ "Unexpected variable format: no values.");
+
+ return NULL;
+ }
+
+ self = g_object_new (RETRO_TYPE_OPTION, NULL);
+
+ self->key = g_strdup (variable->key);
+ self->description = g_strndup (variable->value,
+ description_separator - variable->value);
+ self->values = values;
+ self->current = g_strdup (values[0]);
+
+ return self;
+}
diff --git a/retro-gtk/retro-option.h b/retro-gtk/retro-option.h
new file mode 100644
index 0000000..b49ca09
--- /dev/null
+++ b/retro-gtk/retro-option.h
@@ -0,0 +1,27 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#ifndef RETRO_OPTION_H
+#define RETRO_OPTION_H
+
+#include <glib-object.h>
+#include "retro-variable.h"
+
+G_BEGIN_DECLS
+
+#define RETRO_TYPE_OPTION (retro_option_get_type())
+
+G_DECLARE_FINAL_TYPE (RetroOption, retro_option, RETRO, OPTION, GObject)
+
+RetroOption *retro_option_new (const RetroVariable *variable,
+ GError **error);
+const gchar *retro_option_get_key (RetroOption *self);
+const gchar *retro_option_get_description (RetroOption *self);
+const gchar **retro_option_get_values (RetroOption *self);
+const gchar *retro_option_get_current (RetroOption *self);
+void retro_option_set_current (RetroOption *self,
+ const gchar *current,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* RETRO_OPTION_H */
diff --git a/retro-gtk/retro-options.c b/retro-gtk/retro-options.c
new file mode 100644
index 0000000..059b53d
--- /dev/null
+++ b/retro-gtk/retro-options.c
@@ -0,0 +1,187 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#include "retro-options.h"
+
+#include "retro-option.h"
+
+struct _RetroOptions
+{
+ GObject parent_instance;
+ GHashTable *options;
+ gboolean updated;
+};
+
+G_DEFINE_TYPE (RetroOptions, retro_options, G_TYPE_OBJECT)
+
+enum {
+ SIG_VALUE_CHANGED,
+ N_SIGNALS,
+};
+
+static guint signals[N_SIGNALS];
+
+RetroOptions *
+retro_options_new (void)
+{
+ return g_object_new (RETRO_TYPE_OPTIONS, NULL);
+}
+
+static void
+retro_options_finalize (GObject *object)
+{
+ RetroOptions *self = (RetroOptions *)object;
+
+ g_hash_table_unref (self->options);
+
+ G_OBJECT_CLASS (retro_options_parent_class)->finalize (object);
+}
+
+static void
+retro_options_class_init (RetroOptionsClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = retro_options_finalize;
+
+ signals[SIG_VALUE_CHANGED] =
+ g_signal_new ("value-changed", RETRO_TYPE_OPTIONS, G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+}
+
+static void
+retro_options_init (RetroOptions *self)
+{
+ self->options = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_object_unref);
+}
+
+/* Public */
+
+gboolean
+retro_options_contains (RetroOptions *self,
+ const gchar *key)
+{
+ g_return_val_if_fail (RETRO_IS_OPTIONS (self), FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ return g_hash_table_contains (self->options, key);
+}
+
+const gchar *
+retro_options_get_option_value (RetroOptions *self,
+ const gchar *key)
+{
+ RetroOption *option;
+
+ g_return_val_if_fail (RETRO_IS_OPTIONS (self), FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ option = RETRO_OPTION (g_hash_table_lookup (self->options, key));
+
+ return retro_option_get_current (option);
+}
+
+void
+retro_options_set_option_value (RetroOptions *self,
+ const gchar *key,
+ const gchar *value)
+{
+ RetroOption *option;
+ GError *tmp_error = NULL;
+
+ g_return_if_fail (RETRO_IS_OPTIONS (self));
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (value != NULL);
+
+ option = RETRO_OPTION (g_hash_table_lookup (self->options, key));
+
+ retro_option_set_current (option, value, &tmp_error);
+ if (G_UNLIKELY (tmp_error != NULL)) {
+ g_clear_error (&tmp_error);
+
+ return;
+ }
+
+ g_signal_emit (self, signals[SIG_VALUE_CHANGED], 0, key);
+ self->updated = TRUE;
+}
+
+const gchar *
+retro_options_get_option_description (RetroOptions *self,
+ const gchar *key)
+{
+ RetroOption *option;
+
+ g_return_val_if_fail (RETRO_IS_OPTIONS (self), FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ option = RETRO_OPTION (g_hash_table_lookup (self->options, key));
+
+ return retro_option_get_description (option);
+}
+
+const gchar **
+retro_options_get_option_values (RetroOptions *self,
+ const gchar *key)
+{
+ RetroOption *option;
+
+ g_return_val_if_fail (RETRO_IS_OPTIONS (self), FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ option = RETRO_OPTION (g_hash_table_lookup (self->options, key));
+
+ return retro_option_get_values (option);
+}
+
+GList *
+retro_options_get_keys (RetroOptions *self)
+{
+ g_return_val_if_fail (RETRO_IS_OPTIONS (self), NULL);
+
+ return g_hash_table_get_keys (self->options);
+}
+
+void
+retro_options_insert_variable (RetroOptions *self,
+ const RetroVariable *variable)
+{
+ RetroOption *option;
+ const gchar *key;
+ GError *tmp_error = NULL;
+
+ g_return_if_fail (RETRO_IS_OPTIONS (self));
+ g_return_if_fail (variable != NULL);
+
+ option = retro_option_new (variable, &tmp_error);
+ if (G_UNLIKELY (tmp_error != NULL)) {
+ g_debug ("%s", tmp_error->message);
+ g_clear_error (&tmp_error);
+
+ return;
+ }
+
+ key = retro_option_get_key (option);
+
+ g_hash_table_insert (self->options, g_strdup (key), option);
+ g_signal_emit (self, signals[SIG_VALUE_CHANGED], 0, key);
+
+ self->updated = TRUE;
+}
+
+gboolean
+retro_options_get_variable_update (RetroOptions *self)
+{
+ g_return_val_if_fail (RETRO_IS_OPTIONS (self), FALSE);
+
+ if (!self->updated)
+ return FALSE;
+
+ self->updated = FALSE;
+
+ return TRUE;
+}
diff --git a/retro-gtk/retro-options.h b/retro-gtk/retro-options.h
new file mode 100644
index 0000000..e4c1d2e
--- /dev/null
+++ b/retro-gtk/retro-options.h
@@ -0,0 +1,35 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#ifndef RETRO_OPTIONS_H
+#define RETRO_OPTIONS_H
+
+#include <glib-object.h>
+#include "retro-variable.h"
+
+G_BEGIN_DECLS
+
+#define RETRO_TYPE_OPTIONS (retro_options_get_type())
+
+G_DECLARE_FINAL_TYPE (RetroOptions, retro_options, RETRO, OPTIONS, GObject)
+
+RetroOptions *retro_options_new (void);
+
+gboolean retro_options_contains (RetroOptions *self,
+ const gchar *key);
+const gchar *retro_options_get_option_value (RetroOptions *self,
+ const gchar *key);
+void retro_options_set_option_value (RetroOptions *self,
+ const gchar *key,
+ const gchar *value);
+const gchar *retro_options_get_option_description (RetroOptions *self,
+ const gchar *key);
+const gchar **retro_options_get_option_values (RetroOptions *self,
+ const gchar *key);
+GList *retro_options_get_keys (RetroOptions *self);
+void retro_options_insert_variable (RetroOptions *self,
+ const RetroVariable *variable);
+gboolean retro_options_get_variable_update (RetroOptions *self);
+
+G_END_DECLS
+
+#endif /* RETRO_OPTIONS_H */
diff --git a/retro-gtk/retro-variable.h b/retro-gtk/retro-variable.h
new file mode 100644
index 0000000..bd569de
--- /dev/null
+++ b/retro-gtk/retro-variable.h
@@ -0,0 +1,20 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#ifndef RETRO_VARIABLE_H
+#define RETRO_VARIABLE_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _RetroVariable RetroVariable;
+
+struct _RetroVariable
+{
+ const gchar *key;
+ const gchar *value;
+};
+
+G_END_DECLS
+
+#endif /* RETRO_VARIABLE_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]