[gnome-games/wip/exalm/platform-preferences: 11/16] retro: Add RetroCoreManager



commit b4f4f2a95897d8f864d05caa9f7247d58a6e9020
Author: Alexander Mikhaylenko <exalm7659 gmail com>
Date:   Thu Sep 27 21:59:15 2018 +0500

    retro: Add RetroCoreManager
    
    Searching cores can take some time, so make it a singleton.

 data/org.gnome.Games.gschema.xml  |   7 +++
 src/meson.build                   |   1 +
 src/retro/retro-core-manager.vala | 113 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 121 insertions(+)
---
diff --git a/data/org.gnome.Games.gschema.xml b/data/org.gnome.Games.gschema.xml
index cb3e14fd..f732b3f5 100644
--- a/data/org.gnome.Games.gschema.xml
+++ b/data/org.gnome.Games.gschema.xml
@@ -26,4 +26,11 @@
       <description>Window size (width and height).</description>
     </key>
   </schema>
+  <schema id="org.gnome.Games.platforms" gettext-domain="gnome-games">
+    <key name="preferred-core" type="s">
+      <default>''</default>
+      <summary>Preferred core</summary>
+      <description>Preferred Libretro core to be used for running games. A different core may be used if the 
preferred core is missing firmware.</description>
+    </key>
+  </schema>
 </schemalist>
diff --git a/src/meson.build b/src/meson.build
index 82759acf..24ed087d 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -109,6 +109,7 @@ vala_sources = [
   'keyboard/keyboard-mapping-builder.vala',
   'keyboard/keyboard-mapping-manager.vala',
 
+  'retro/retro-core-manager.vala',
   'retro/retro-core-source.vala',
   'retro/retro-error.vala',
   'retro/retro-gamepad.vala',
diff --git a/src/retro/retro-core-manager.vala b/src/retro/retro-core-manager.vala
new file mode 100644
index 00000000..0e6a793a
--- /dev/null
+++ b/src/retro/retro-core-manager.vala
@@ -0,0 +1,113 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+public class Games.RetroCoreManager : Object {
+       private static RetroCoreManager instance;
+
+       private Retro.CoreDescriptor[] core_descriptors;
+       private HashTable<string, Retro.CoreDescriptor> core_descriptor_ids;
+       private bool searched;
+
+       public static RetroCoreManager get_instance () {
+               if (instance == null)
+                       instance = new RetroCoreManager ();
+
+               return instance;
+       }
+
+       private RetroCoreManager () {
+               searched = false;
+               core_descriptors = {};
+               core_descriptor_ids = new HashTable<string, Retro.CoreDescriptor> (str_hash, str_equal);
+       }
+
+       private void search_modules () {
+               var modules = new Retro.ModuleQuery (true);
+               foreach (var core_descriptor in modules) {
+                       try {
+                               if (!core_descriptor.get_is_emulator ())
+                                       continue;
+
+                               if (core_descriptor.get_module_file () == null)
+                                       continue;
+
+                               core_descriptors += core_descriptor;
+                               core_descriptor_ids[core_descriptor.get_id ()] = core_descriptor;
+                       }
+                       catch (Error e) {
+                               debug (e.message);
+                       }
+               }
+       }
+
+       public Retro.CoreDescriptor? get_core_for_id (string id) {
+               if (!(id in core_descriptor_ids))
+                       return null;
+
+               return core_descriptor_ids[id];
+       }
+
+       private Settings get_settings (RetroPlatform platform) {
+               var path = "/org/gnome/Games/platforms/%s/".printf (platform.get_id ());
+               return new Settings.with_path ("org.gnome.Games.platforms", path);
+       }
+
+       public void set_preferred_core (RetroPlatform platform, Retro.CoreDescriptor core_descriptor) {
+               get_settings (platform).set_string ("preferred-core", core_descriptor.get_id ());
+       }
+
+       public Retro.CoreDescriptor? get_preferred_core (RetroPlatform platform) {
+               if (!searched) {
+                       searched = true;
+                       search_modules ();
+               }
+
+               var preferred_core = get_settings (platform).get_string ("preferred-core");
+
+               var core_descriptor = core_descriptor_ids[preferred_core];
+               if (core_descriptor == null || !core_descriptor.has_platform (platform.get_id ())) {
+                       var cores = get_cores_for_platform (platform);
+
+                       if (cores.length > 0)
+                               return get_cores_for_platform (platform)[0];
+
+                       return null;
+               }
+
+               return core_descriptor;
+       }
+
+       public Retro.CoreDescriptor[] get_cores_for_platform (RetroPlatform platform) {
+               if (!searched) {
+                       searched = true;
+                       search_modules ();
+               }
+
+               var platform_id = platform.get_id ();
+               var mime_types = platform.get_mime_types ();
+
+               var result = new Array<Retro.CoreDescriptor> ();
+
+               var preferred_core = get_settings (platform).get_string ("preferred-core");
+
+               foreach (var core_descriptor in core_descriptors) {
+                       try {
+                               if (!core_descriptor.has_platform (platform_id))
+                                       continue;
+
+                               if (!core_descriptor.get_platform_supports_mime_types (platform_id, 
mime_types))
+                                       continue;
+
+                               // Insert preferred core at the start of the list
+                               if (core_descriptor.get_id () == preferred_core)
+                                       result.prepend_val (core_descriptor);
+                               else
+                                       result.append_val (core_descriptor);
+                       }
+                       catch (Error e) {
+                               debug (e.message);
+                       }
+               }
+
+               return result.data;
+       }
+}


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