[retro-gtk] retro-gobject: Refactor serialization functions
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [retro-gtk] retro-gobject: Refactor serialization functions
- Date: Wed, 25 Jan 2017 17:22:08 +0000 (UTC)
commit 7705f99bb1c126da24ae69a762b3ff5d077b797b
Author: Adrien Plazas <kekun plazas laposte net>
Date: Wed Jan 25 18:11:07 2017 +0100
retro-gobject: Refactor serialization functions
https://bugzilla.gnome.org/show_bug.cgi?id=777489
retro-gobject/core-error.vala | 7 +++
retro-gobject/core.vala | 51 ++-----------------
retro-gobject/retro-core.c | 110 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 121 insertions(+), 47 deletions(-)
---
diff --git a/retro-gobject/core-error.vala b/retro-gobject/core-error.vala
new file mode 100644
index 0000000..46ff478
--- /dev/null
+++ b/retro-gobject/core-error.vala
@@ -0,0 +1,7 @@
+// This file is part of Retro. License: GPLv3
+
+public errordomain Retro.CoreError {
+ COULDNT_SERIALIZE,
+ COULDNT_DESERIALIZE,
+ SERIALIZATION_NOT_SUPPORTED,
+}
diff --git a/retro-gobject/core.vala b/retro-gobject/core.vala
index f882553..224e9c4 100644
--- a/retro-gobject/core.vala
+++ b/retro-gobject/core.vala
@@ -313,55 +313,12 @@ public class Core : Object {
pop_cb_data ();
}
- /**
- * Returns the amount of data the implementation requires to serialize
- * the internal state.
- *
- * Beetween calls to {@link load_game} and
- * {@link unload_game}, the returned size is never allowed to
- * be larger than a previous returned value, to ensure that the frontend can
- * allocate a save state buffer once.
- *
- * @return the size needed to serialize the internal state
- */
- public size_t serialize_size () {
- push_cb_data ();
- var result = module.serialize_size ();
- pop_cb_data ();
-
- return result;
- }
-
- /**
- * Serializes the internal state.
- *
- * If failed, or size is lower than {@link serialize_size}, it
- * should return false, true otherwise.
- *
- * @param data the buffer where the data will be stored
- * @return false if the serialization failed, true otherwise
- */
- public bool serialize ([CCode (array_length_type = "gsize")] uint8[] data) {
- push_cb_data ();
- var result = module.serialize (data);
- pop_cb_data ();
+ public extern bool supports_serialization ();
- return result;
- }
+ [CCode (array_length_type = "gsize")]
+ public extern uint8[] serialize_state () throws Error;
- /**
- * Unserializes the internal state.
- *
- * @param data the buffer where the data is stored
- * @return false if the unserialization failed, true otherwise
- */
- public bool unserialize ([CCode (array_length_type = "gsize")] uint8[] data) {
- push_cb_data ();
- var result = module.unserialize (data);
- pop_cb_data ();
-
- return result;
- }
+ public extern void deserialize_state ([CCode (array_length_type = "gsize")] uint8[] data) throws
Error;
/**
* Load. a game.
diff --git a/retro-gobject/retro-core.c b/retro-gobject/retro-core.c
index 8efb5d3..1bcbf70 100644
--- a/retro-gobject/retro-core.c
+++ b/retro-gobject/retro-core.c
@@ -2,6 +2,116 @@
#include "retro-gobject-internal.h"
+gboolean retro_core_supports_serialization (RetroCore *self) {
+ RetroSerializeSize serialize_size = NULL;
+ gsize size;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ retro_core_push_cb_data (self);
+ serialize_size = retro_module_get_serialize_size (self->module);
+ size = serialize_size ();
+ retro_core_pop_cb_data ();
+
+ return size > 0;
+}
+
+guint8 *retro_core_serialize_state (RetroCore *self, gsize *length, GError **error) {
+ RetroSerializeSize serialize_size = NULL;
+ RetroSerialize serialize = NULL;
+ guint8 *data;
+ gsize size;
+ gboolean success;
+
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (length != NULL, NULL);
+
+ serialize_size = retro_module_get_serialize_size (self->module);
+
+ retro_core_push_cb_data (self);
+ size = serialize_size ();
+ retro_core_pop_cb_data ();
+
+ if (size <= 0) {
+ g_set_error (error,
+ RETRO_CORE_ERROR,
+ RETRO_CORE_ERROR_SERIALIZATION_NOT_SUPPORTED,
+ "Couldn't serialize the internal state: serialization not supported.");
+
+ return NULL;
+ }
+
+ serialize = retro_module_get_serialize (self->module);
+ data = g_new0 (guint8, size);
+
+ retro_core_push_cb_data (self);
+ success = serialize (data, size);
+ retro_core_pop_cb_data ();
+
+ if (!success) {
+ g_set_error (error,
+ RETRO_CORE_ERROR,
+ RETRO_CORE_ERROR_COULDNT_SERIALIZE,
+ "Couldn't serialize the internal state: serialization failed.");
+ g_free (data);
+
+ return NULL;
+ }
+
+ *length = size;
+
+ return data;
+}
+
+void retro_core_deserialize_state (RetroCore *self, guint8 *data, gsize length, GError **error) {
+ RetroSerializeSize serialize_size = NULL;
+ RetroUnserialize unserialize = NULL;
+ gsize size;
+ gboolean success;
+
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (data != NULL, NULL);
+
+ serialize_size = retro_module_get_serialize_size (self->module);
+
+ retro_core_push_cb_data (self);
+ size = serialize_size ();
+ retro_core_pop_cb_data ();
+
+ if (size <= 0) {
+ g_set_error (error,
+ RETRO_CORE_ERROR,
+ RETRO_CORE_ERROR_SERIALIZATION_NOT_SUPPORTED,
+ "Couldn't deserialize the internal state: serialization not supported.");
+
+ return NULL;
+ }
+
+ if (length > size) {
+ g_set_error (error,
+ RETRO_CORE_ERROR,
+ RETRO_CORE_ERROR_COULDNT_DESERIALIZE,
+ "Couldn't deserialize the internal state: expected at most %llu bytes, got
%llu.", size, length);
+
+ return NULL;
+ }
+
+ unserialize = retro_module_get_unserialize (self->module);
+
+ retro_core_push_cb_data (self);
+ success = unserialize (data, length);
+ retro_core_pop_cb_data ();
+
+ if (!success) {
+ g_set_error (error,
+ RETRO_CORE_ERROR,
+ RETRO_CORE_ERROR_COULDNT_DESERIALIZE,
+ "Couldn't deserialize the internal state: deserialization failed.");
+
+ return NULL;
+ }
+}
+
guint8 *retro_core_get_memory (RetroCore *self, RetroMemoryType id, gint *length) {
RetroGetMemoryData get_mem_data;
RetroGetMemorySize get_mem_size;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]