[retro-gtk/singleton] core: Make it a singleton



commit 9937f269ab71a5543a2114538f8448ee68aacadc
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Sat Feb 15 23:10:42 2020 +0100

    core: Make it a singleton
    
    As each core is guaranteed to live alone in its runner process, we don't
    need a core call stack anymore to handle multple cores living in the
    same process despite the Libretro API not supporting it. Instead, it is
    replaced by a singleton, as we still need to know which the RetroCore
    instance we should call back to.

 retro-runner/retro-core-private.h |   2 -
 retro-runner/retro-core.c         | 167 +++-----------------------------------
 retro-runner/retro-environment.c  |   5 --
 3 files changed, 13 insertions(+), 161 deletions(-)
---
diff --git a/retro-runner/retro-core-private.h b/retro-runner/retro-core-private.h
index 57a47e2..7a3ba38 100644
--- a/retro-runner/retro-core-private.h
+++ b/retro-runner/retro-core-private.h
@@ -59,8 +59,6 @@ struct _RetroCore
   glong main_loop;
 };
 
-void retro_core_push_cb_data (RetroCore *self);
-void retro_core_pop_cb_data (void);
 RetroCore *retro_core_get_cb_data (void);
 const gchar *retro_core_get_libretro_path (RetroCore *self);
 void retro_core_set_support_no_game (RetroCore *self,
diff --git a/retro-runner/retro-core.c b/retro-runner/retro-core.c
index c96ba19..814d84c 100644
--- a/retro-runner/retro-core.c
+++ b/retro-runner/retro-core.c
@@ -58,77 +58,17 @@ enum {
 
 static guint signals[N_SIGNALS];
 
-#define RETRO_CORE_OBJECTS_LENGTH 32
-
-static GRecMutex retro_core_r_mutex = { 0 };
-static GRecMutex retro_core_w_mutex = { 0 };
-static RetroCore *retro_core_objects[32];
-static gint retro_core_i = 0;
+static RetroCore *retro_core_singleton = NULL;
 
 static void retro_core_set_filename (RetroCore   *self,
                                      const gchar *filename);
 
 /* Private */
 
-void
-retro_core_push_cb_data (RetroCore *self)
-{
-  g_return_if_fail (RETRO_IS_CORE (self));
-
-  g_rec_mutex_lock (&retro_core_w_mutex);
-  g_rec_mutex_lock (&retro_core_r_mutex);
-
-  if (G_UNLIKELY (retro_core_i == RETRO_CORE_OBJECTS_LENGTH)) {
-    g_critical ("RetroCore callback data stack overflow.");
-
-    g_rec_mutex_unlock (&retro_core_r_mutex);
-    g_assert_not_reached ();
-  }
-
-  retro_core_objects[retro_core_i] = self;
-  retro_core_i++;
-
-  g_rec_mutex_unlock (&retro_core_r_mutex);
-}
-
-void
-retro_core_pop_cb_data (void)
-{
-  g_rec_mutex_lock (&retro_core_r_mutex);
-
-  if (G_UNLIKELY (retro_core_i == 0)) {
-    g_critical ("RetroCore callback data stack underflow.");
-
-    g_rec_mutex_unlock (&retro_core_r_mutex);
-    g_rec_mutex_unlock (&retro_core_w_mutex);
-    g_assert_not_reached ();
-  }
-  retro_core_i--;
-
-  retro_core_objects[retro_core_i] = NULL;
-
-  g_rec_mutex_unlock (&retro_core_r_mutex);
-  g_rec_mutex_unlock (&retro_core_w_mutex);
-}
-
 RetroCore *
 retro_core_get_cb_data (void)
 {
-  RetroCore *result;
-
-  g_rec_mutex_lock (&retro_core_r_mutex);
-
-  if (retro_core_i == 0) {
-    g_critical ("RetroCore callback data segmentation fault.");
-
-    g_rec_mutex_unlock (&retro_core_r_mutex);
-    g_assert_not_reached ();
-  }
-
-  result = retro_core_objects[retro_core_i - 1];
-  g_rec_mutex_unlock (&retro_core_r_mutex);
-
-  return result;
+  return retro_core_singleton;
 }
 
 void retro_core_set_callbacks (RetroCore *self);
@@ -169,14 +109,12 @@ retro_core_finalize (GObject *object)
 
   retro_core_stop (self);
 
-  retro_core_push_cb_data (self);
   if (retro_core_get_game_loaded (self)) {
     unload_game = retro_module_get_unload_game (self->module);
     unload_game ();
   }
   deinit = retro_module_get_deinit (self->module);
   deinit ();
-  retro_core_pop_cb_data ();
 
   if (self->media_uris != NULL)
     g_strfreev (self->media_uris);
@@ -682,10 +620,8 @@ retro_core_get_system_info (RetroCore       *self,
   g_return_if_fail (RETRO_IS_CORE (self));
   g_return_if_fail (system_info != NULL);
 
-  retro_core_push_cb_data (self);
   get_system_info = retro_module_get_get_system_info (self->module);
   get_system_info (system_info);
-  retro_core_pop_cb_data ();
 }
 
 static gboolean
@@ -770,7 +706,6 @@ retro_core_set_disk_ejected (RetroCore  *self,
                              GError    **error)
 {
   RetroDiskControlCallbackSetEjectState set_eject_state;
-  gboolean result;
 
   g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
@@ -785,11 +720,7 @@ retro_core_set_disk_ejected (RetroCore  *self,
     return FALSE;
   }
 
-  retro_core_push_cb_data (self);
-  result = set_eject_state (ejected);
-  retro_core_pop_cb_data ();
-
-  return result;
+  return set_eject_state (ejected);
 }
 
 static gboolean
@@ -798,7 +729,6 @@ retro_core_set_disk_image_index (RetroCore  *self,
                                  GError    **error)
 {
   RetroDiskControlCallbackSetImageIndex set_image_index;
-  gboolean result;
 
   g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
@@ -813,11 +743,7 @@ retro_core_set_disk_image_index (RetroCore  *self,
     return FALSE;
   }
 
-  retro_core_push_cb_data (self);
-  result = set_image_index (index);
-  retro_core_pop_cb_data ();
-
-  return result;
+  return set_image_index (index);
 }
 
 static guint
@@ -825,7 +751,6 @@ retro_core_get_disk_images_number (RetroCore  *self,
                                    GError    **error)
 {
   RetroDiskControlCallbackGetNumImages get_num_images;
-  guint result;
 
   g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
@@ -840,11 +765,7 @@ retro_core_get_disk_images_number (RetroCore  *self,
     return FALSE;
   }
 
-  retro_core_push_cb_data (self);
-  result = get_num_images ();
-  retro_core_pop_cb_data ();
-
-  return result;
+  return get_num_images ();
 }
 
 static gboolean
@@ -854,7 +775,6 @@ retro_core_replace_disk_image_index (RetroCore     *self,
                                      GError        **error)
 {
   RetroDiskControlCallbackReplaceImageIndex replace_image_index;
-  gboolean result;
 
   g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
@@ -869,11 +789,7 @@ retro_core_replace_disk_image_index (RetroCore     *self,
     return FALSE;
   }
 
-  retro_core_push_cb_data (self);
-  result = replace_image_index (index, info);
-  retro_core_pop_cb_data ();
-
-  return result;
+  return replace_image_index (index, info);
 }
 
 static gboolean
@@ -881,7 +797,6 @@ retro_core_add_disk_image_index (RetroCore  *self,
                                  GError    **error)
 {
   RetroDiskControlCallbackAddImageIndex add_image_index;
-  gboolean result;
 
   g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
@@ -896,11 +811,7 @@ retro_core_add_disk_image_index (RetroCore  *self,
     return FALSE;
   }
 
-  retro_core_push_cb_data (self);
-  result = add_image_index ();
-  retro_core_pop_cb_data ();
-
-  return result;
+  return add_image_index ();
 }
 
 static void
@@ -1001,20 +912,16 @@ retro_core_load_game (RetroCore     *self,
   g_return_val_if_fail (game != NULL, FALSE);
 
   if (retro_core_get_game_loaded (self)) {
-    retro_core_push_cb_data (self);
     unload_game = retro_module_get_unload_game (self->module);
     unload_game ();
-    retro_core_pop_cb_data ();
   }
 
-  retro_core_push_cb_data (self);
   load_game = retro_module_get_load_game (self->module);
   game_loaded = load_game (game);
   retro_core_set_game_loaded (self, game_loaded);
   get_system_av_info = retro_module_get_get_system_av_info (self->module);
   get_system_av_info (&info);
   retro_core_set_system_av_info (self, &info);
-  retro_core_pop_cb_data ();
 
   return game_loaded;
 }
@@ -1028,14 +935,12 @@ retro_core_prepare (RetroCore *self) {
 
   g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
-  retro_core_push_cb_data (self);
   load_game = retro_module_get_load_game (self->module);
   game_loaded = load_game (NULL);
   retro_core_set_game_loaded (self, game_loaded);
   get_system_av_info = retro_module_get_get_system_av_info (self->module);
   get_system_av_info (&info);
   retro_core_set_system_av_info (self, &info);
-  retro_core_pop_cb_data ();
 
   return game_loaded;
 }
@@ -1181,17 +1086,12 @@ retro_core_get_framebuffer_fd (RetroCore *self)
 guint
 retro_core_get_api_version (RetroCore *self)
 {
-  guint result;
   RetroApiVersion api_version;
 
   g_return_val_if_fail (RETRO_IS_CORE (self), 0U);
 
-  retro_core_push_cb_data (self);
   api_version = retro_module_get_api_version (self->module);
-  result = api_version ();
-  retro_core_pop_cb_data ();
-
-  return result;
+  return api_version ();
 }
 
 /**
@@ -1429,10 +1329,8 @@ retro_core_boot (RetroCore  *self,
 
   retro_core_set_environment_interface (self);
 
-  retro_core_push_cb_data (self);
   init = retro_module_get_init (self->module);
   init ();
-  retro_core_pop_cb_data ();
 
   retro_core_set_is_initiated (self, TRUE);
 
@@ -1541,10 +1439,8 @@ retro_core_set_controller (RetroCore           *self,
     g_hash_table_insert (self->controllers, GUINT_TO_POINTER (port),
                          retro_controller_state_new (fd));
 
-  retro_core_push_cb_data (self);
   set_controller_port_device = retro_module_get_set_controller_port_device (self->module);
   set_controller_port_device (port, controller_type);
-  retro_core_pop_cb_data ();
 }
 
 gboolean
@@ -1576,9 +1472,7 @@ retro_core_send_input_key_event (RetroCore                *self,
   if (self->keyboard_callback.callback == NULL)
     return;
 
-  retro_core_push_cb_data (self);
   self->keyboard_callback.callback (down, keycode, character, key_modifiers);
-  retro_core_pop_cb_data ();
 }
 
 static gboolean
@@ -1653,10 +1547,8 @@ retro_core_reset (RetroCore *self)
 
   g_return_if_fail (RETRO_IS_CORE (self));
 
-  retro_core_push_cb_data (self);
   reset = retro_module_get_reset (self->module);
   reset ();
-  retro_core_pop_cb_data ();
 }
 
 /**
@@ -1683,9 +1575,7 @@ retro_core_iteration (RetroCore *self)
 
   if (self->runahead == 0) {
     self->run_remaining = 0;
-    retro_core_push_cb_data (self);
     run ();
-    retro_core_pop_cb_data ();
 
     g_signal_emit (self, signals[SIG_ITERATED_SIGNAL], 0);
 
@@ -1693,16 +1583,11 @@ retro_core_iteration (RetroCore *self)
   }
 
   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) {
     self->run_remaining = 0;
-    retro_core_push_cb_data (self);
     run ();
-    retro_core_pop_cb_data ();
 
     g_critical ("Couldn't run ahead: serialization not supported.");
 
@@ -1712,10 +1597,7 @@ retro_core_iteration (RetroCore *self)
   }
 
   self->run_remaining = self->runahead;
-
-  retro_core_push_cb_data (self);
   run ();
-  retro_core_pop_cb_data ();
 
   self->run_remaining--;
 
@@ -1735,9 +1617,7 @@ retro_core_iteration (RetroCore *self)
   data = g_new0 (guint8, size);
 
   serialize = retro_module_get_serialize (self->module);
-  retro_core_push_cb_data (self);
   success = serialize (data, size);
-  retro_core_pop_cb_data ();
 
   if (!success) {
     g_critical ("Couldn't run ahead: serialization unexpectedly failed.");
@@ -1749,10 +1629,8 @@ retro_core_iteration (RetroCore *self)
     return;
   }
 
-  retro_core_push_cb_data (self);
   for (; self->run_remaining >= 0; self->run_remaining--)
     run ();
-  retro_core_pop_cb_data ();
 
   new_size = serialize_size ();
 
@@ -1769,9 +1647,7 @@ retro_core_iteration (RetroCore *self)
   }
 
   unserialize = retro_module_get_unserialize (self->module);
-  retro_core_push_cb_data (self);
   success = unserialize ((guint8 *) data, size);
-  retro_core_pop_cb_data ();
 
   if (!success) {
     g_critical ("Couldn't run ahead: deserialization unexpectedly failed.");
@@ -1804,10 +1680,8 @@ retro_core_get_can_access_state (RetroCore *self)
 
   g_return_val_if_fail (RETRO_IS_CORE (self), 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;
 }
@@ -1836,10 +1710,7 @@ retro_core_save_state (RetroCore    *self,
   g_return_if_fail (filename != 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,
@@ -1853,9 +1724,7 @@ retro_core_save_state (RetroCore    *self,
   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,
@@ -1909,9 +1778,7 @@ retro_core_load_state (RetroCore    *self,
 
   serialize_size = retro_module_get_serialize_size (self->module);
 
-  retro_core_push_cb_data (self);
   expected_size = serialize_size ();
-  retro_core_pop_cb_data ();
 
   if (expected_size == 0) {
     g_set_error (error,
@@ -1931,9 +1798,7 @@ retro_core_load_state (RetroCore    *self,
 
   unserialize = retro_module_get_unserialize (self->module);
 
-  retro_core_push_cb_data (self);
   success = unserialize ((guint8 *) data, data_size);
-  retro_core_pop_cb_data ();
 
   if (!success) {
     g_set_error (error,
@@ -1956,17 +1821,12 @@ gsize
 retro_core_get_memory_size (RetroCore       *self,
                             RetroMemoryType  memory_type)
 {
-  gsize size;
   RetroGetMemorySize get_memory_size;
 
   g_return_val_if_fail (RETRO_IS_CORE (self), 0UL);
 
-  retro_core_push_cb_data (self);
   get_memory_size = retro_module_get_get_memory_size (self->module);
-  size = get_memory_size (memory_type);
-  retro_core_pop_cb_data ();
-
-  return size;
+  return get_memory_size (memory_type);
 }
 
 /**
@@ -1996,10 +1856,8 @@ retro_core_save_memory (RetroCore        *self,
   get_mem_data = retro_module_get_get_memory_data (self->module);
   get_mem_size = retro_module_get_get_memory_size (self->module);
 
-  retro_core_push_cb_data (self);
   data = get_mem_data (memory_type);
   size = get_mem_size (memory_type);
-  retro_core_pop_cb_data ();
 
   g_file_set_contents (filename, data, size, &tmp_error);
   if (G_UNLIKELY (tmp_error != NULL))
@@ -2038,10 +1896,8 @@ retro_core_load_memory (RetroCore        *self,
   get_mem_region = retro_module_get_get_memory_data (self->module);
   get_mem_region_size = retro_module_get_get_memory_size (self->module);
 
-  retro_core_push_cb_data (self);
   memory_region = get_mem_region (memory_type);
   memory_region_size = get_mem_region_size (memory_type);
-  retro_core_pop_cb_data ();
 
   g_file_get_contents (filename, &data, &data_size, &tmp_error);
   if (G_UNLIKELY (tmp_error != NULL)) {
@@ -2284,6 +2140,9 @@ RetroCore *
 retro_core_new (const gchar *filename)
 {
   g_return_val_if_fail (filename != NULL, NULL);
+  g_return_val_if_fail (retro_core_singleton == NULL, NULL);
+
+  retro_core_singleton = g_object_new (RETRO_TYPE_CORE, "filename", filename, NULL);
 
-  return g_object_new (RETRO_TYPE_CORE, "filename", filename, NULL);
+  return retro_core_singleton;
 }
diff --git a/retro-runner/retro-environment.c b/retro-runner/retro-environment.c
index eec4eaf..4bb1196 100644
--- a/retro-runner/retro-environment.c
+++ b/retro-runner/retro-environment.c
@@ -650,10 +650,7 @@ retro_core_set_environment_interface (RetroCore *self)
 
   module = self->module;
   set_environment = retro_module_get_set_environment (module);
-
-  retro_core_push_cb_data (self);
   set_environment (on_environment_interface);
-  retro_core_pop_cb_data ();
 }
 
 // TODO This is internal, make it private as soon as possible.
@@ -674,11 +671,9 @@ retro_core_set_callbacks (RetroCore *self)
   set_input_poll = retro_module_get_set_input_poll (module);
   set_input_state = retro_module_get_set_input_state (module);
 
-  retro_core_push_cb_data (self);
   set_video_refresh (on_video_refresh);
   set_audio_sample (on_audio_sample);
   set_audio_sample_batch (on_audio_sample_batch);
   set_input_poll (on_input_poll);
   set_input_state (on_input_state);
-  retro_core_pop_cb_data ();
 }


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