[gnome-games] playstation: Add PlayStationGameFactory



commit 1843a7d73f82638d6b3ff470d1eaf216b2f163fd
Author: Ricard Gascons <gascons1995 gmail com>
Date:   Fri Aug 19 11:44:22 2016 +0200

    playstation: Add PlayStationGameFactory
    
    This class manages the game creation and grouping of single and
    multi-source games for the PlayStation platform.
    
    This is part of a series of commits to add multi-source support.

 .../playstation/src/playstation-game-factory.vala  |  162 ++++++++++++++++++++
 1 files changed, 162 insertions(+), 0 deletions(-)
---
diff --git a/plugins/playstation/src/playstation-game-factory.vala 
b/plugins/playstation/src/playstation-game-factory.vala
new file mode 100644
index 0000000..8c65e2d
--- /dev/null
+++ b/plugins/playstation/src/playstation-game-factory.vala
@@ -0,0 +1,162 @@
+// This file is part of GNOME Games. License: GPLv3
+
+public class Games.PlayStationGameFactory : Object, UriGameFactory {
+       private const string SEARCHED_MIME_TYPE = "application/x-cue";
+       private const string SPECIFIC_MIME_TYPE = "application/x-playstation-rom";
+       private const string MODULE_BASENAME = "libretro-playstation.so";
+       private const string ICON_NAME = "media-optical-symbolic";
+       private const bool SUPPORTS_SNAPSHOTTING = true;
+       private const string GAMEINFO = 
"resource:///org/gnome/Games/plugin/playstation/playstation.gameinfo.xml";
+
+       private static GameinfoDoc gameinfo;
+
+       private HashTable<string, string> discs;
+       private HashTable<string, GenericSet<string>> disc_sets;
+       private HashTable<string, Game> games;
+
+
+       public PlayStationGameFactory () {
+               discs = new HashTable<string, string> (GLib.str_hash, GLib.str_equal);
+               disc_sets = new HashTable<string, GenericSet<string>> (GLib.str_hash, GLib.str_equal);
+               games = new HashTable<string, Game> (GLib.str_hash, GLib.str_equal);
+       }
+
+       public bool is_cursor_valid (Tracker.Sparql.Cursor cursor) {
+               var uri = cursor.get_string (0);
+
+               return is_uri_valid (uri);
+       }
+
+       public bool is_uri_valid (string uri) {
+               File file = File.new_for_uri(uri);
+
+               return file.query_exists ();
+       }
+
+       public void add_uri (string uri) {
+               string disc_id;
+
+               try {
+                       disc_id = get_disc_id (uri);
+               }
+               catch (Error e) {
+                       return;
+               }
+
+               discs[disc_id] = uri;
+       }
+
+       public async void foreach_game (GameCallback game_callback) {
+               GameinfoDoc gameinfo = null;
+               try {
+                       gameinfo = get_gameinfo ();
+               }
+               catch (Error e) {
+                       warning (e.message);
+               }
+
+               discs.foreach((disc_id, uri) => {
+                       var disc_set_id = disc_id;
+
+                       try {
+                               if (gameinfo != null)
+                                       disc_set_id = gameinfo.get_disc_set_id_for_disc_id (disc_id);
+                       }
+                       catch (Error e) {
+                               debug (_("Disc with disc_id %s is unknown"), disc_id);
+                       }
+
+                       if (!(disc_set_id in disc_sets))
+                               disc_sets[disc_set_id] = new GenericSet<string> (GLib.str_hash, 
GLib.str_equal);
+
+                       disc_sets[disc_set_id].add (disc_id);
+               });
+
+               disc_sets.foreach ((disc_set_id, disc_set) => {
+                       try {
+                               if (!(disc_set_id in games))
+                                       games[disc_set_id] = game_for_disc_set (disc_set);
+                       }
+                       catch (Error e) {
+                               warning (e.message);
+                       }
+               });
+
+               games.foreach ((disc_set_id, game) => {
+                       game_callback (game);
+               });
+       }
+
+       private string get_disc_id (string uri) throws Error {
+               var cue_file = File.new_for_uri (uri);
+               var cue_sheet = new CueSheet (cue_file);
+               var cue_track_node = cue_sheet.get_track (0);
+               var bin_file = cue_track_node.file.file;
+               var header = new PlayStationHeader (bin_file);
+
+               header.check_validity ();
+
+               return header.disc_id;
+       }
+
+       private Game game_for_disc_set (GenericSet<string> disc_set) throws Error {
+               Media[] medias = {};
+
+               var gameinfo = get_gameinfo ();
+               disc_set.foreach ((disc_id) => {
+                       var uri = discs[disc_id];
+                       var title = new GameinfoDiscIdDiscTitle (gameinfo, disc_id);
+                       medias += new Media (uri, title);
+               });
+
+               var icon = GLib.Icon.new_for_string (ICON_NAME);
+               var media_set = new MediaSet (medias, icon);
+
+               var game = game_for_uris (media_set);
+
+               return game;
+       }
+
+       private Game game_for_uris (MediaSet media_set) throws Error {
+               var uri = media_set.get_selected_media (0).uri;
+               var cue_file = File.new_for_uri (uri);
+               var cue_sheet = new CueSheet (cue_file);
+               var cue_track_node = cue_sheet.get_track (0);
+               var bin_file = cue_track_node.file.file;
+               var header = new PlayStationHeader (bin_file);
+               header.check_validity ();
+
+               var gameinfo = get_gameinfo ();
+               var uid = new PlayStationUid (header);
+               var title = new CompositeTitle ({
+                       new GameinfoDiscIdGameTitle (gameinfo, header.disc_id),
+                       new FilenameTitle (uri)
+               });
+               var icon = new DummyIcon ();
+               var cover = new LocalCover (uri);
+               var runner = new RetroRunner.for_media_set (media_set, uid, { SEARCHED_MIME_TYPE, 
SPECIFIC_MIME_TYPE }, MODULE_BASENAME, SUPPORTS_SNAPSHOTTING);
+
+               return new GenericGame (title, icon, cover, runner);
+       }
+
+       private static GameinfoDoc get_gameinfo () throws Error {
+               if (gameinfo != null)
+                       return gameinfo;
+
+               var file = File.new_for_uri (GAMEINFO);
+               var input_stream = file.read ();
+
+               input_stream.seek (0, SeekType.END);
+               var length = input_stream.tell ();
+               input_stream.seek (0, SeekType.SET);
+
+               var buffer = new uint8[length];
+               size_t size = 0;
+
+               input_stream.read_all (buffer, out size);
+
+               gameinfo = new GameinfoDoc.from_data (buffer);
+
+               return gameinfo;
+       }
+}


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