[gnome-games/wip/exalm/rebrand: 86/124] playstation: Make PlayStationGameFactory use a parser




commit dd0b3942c32b210223ee7ff522f790be873b0c56
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Tue Mar 30 15:15:57 2021 +0500

    playstation: Make PlayStationGameFactory use a parser
    
    Thin it down to the point it's generic enough to be merged with
    GenericUriGameFactory.

 plugins/playstation/src/meson.build                |   1 +
 plugins/playstation/src/playstation-error.vala     |   2 +
 .../playstation/src/playstation-game-factory.vala  | 102 +++----------------
 plugins/playstation/src/playstation-parser.vala    | 109 +++++++++++++++++++++
 plugins/playstation/src/playstation-plugin.vala    |   1 +
 src/core/game-parser.vala                          |  12 +++
 6 files changed, 141 insertions(+), 86 deletions(-)
---
diff --git a/plugins/playstation/src/meson.build b/plugins/playstation/src/meson.build
index 26eafeb6..af1fd603 100644
--- a/plugins/playstation/src/meson.build
+++ b/plugins/playstation/src/meson.build
@@ -2,6 +2,7 @@ vala_sources = [
   'playstation-error.vala',
   'playstation-game-factory.vala',
   'playstation-header.vala',
+  'playstation-parser.vala',
   'playstation-plugin.vala',
 ]
 
diff --git a/plugins/playstation/src/playstation-error.vala b/plugins/playstation/src/playstation-error.vala
index 31591b6b..a94210b7 100644
--- a/plugins/playstation/src/playstation-error.vala
+++ b/plugins/playstation/src/playstation-error.vala
@@ -2,4 +2,6 @@
 
 errordomain Games.PlayStationError {
        INVALID_HEADER,
+       INVALID_FILE_TYPE,
+       INVALID_CUE_SHEET,
 }
diff --git a/plugins/playstation/src/playstation-game-factory.vala 
b/plugins/playstation/src/playstation-game-factory.vala
index 09a859ce..e0946706 100644
--- a/plugins/playstation/src/playstation-game-factory.vala
+++ b/plugins/playstation/src/playstation-game-factory.vala
@@ -1,14 +1,6 @@
 // This file is part of GNOME Games. License: GPL-3.0+.
 
 public class Games.PlayStationGameFactory : Object, UriGameFactory {
-       private const string CUE_MIME_TYPE = "application/x-cue";
-       private const string PHONY_MIME_TYPE = "application/x-playstation-rom";
-       private const string ICON_NAME = "media-optical-symbolic";
-       private const string GAMEINFO = 
"resource:///org/gnome/Games/plugin/playstation/playstation.gameinfo.xml";
-       private const string PLATFORM_UID_PREFIX = "playstation";
-
-       private static GameinfoDoc gameinfo;
-
        private HashTable<string, Media> media_for_disc_id;
        private HashTable<Uri, Game> game_for_uri;
        private HashTable<string, Game> game_for_disc_set_id;
@@ -25,7 +17,7 @@ public class Games.PlayStationGameFactory : Object, UriGameFactory {
        }
 
        public string[] get_mime_types () {
-               return { CUE_MIME_TYPE };
+               return platform.get_mime_types ();
        }
 
        public Game? query_game_for_uri (Uri uri) {
@@ -49,36 +41,11 @@ public class Games.PlayStationGameFactory : Object, UriGameFactory {
                if (game_for_uri.contains (uri))
                        return;
 
-               var file = uri.to_file ();
-               var file_info = file.query_info (FileAttribute.STANDARD_CONTENT_TYPE, 
FileQueryInfoFlags.NONE);
-               var mime_type = file_info.get_content_type ();
-
-               File bin_file;
-               switch (mime_type) {
-               case CUE_MIME_TYPE:
-                       var cue = new CueSheet (file);
-                       if (cue.tracks_number == 0)
-                               return;
+               var parser = Object.new (platform.parser_type, platform: platform, uri: uri) as GameParser;
+               parser.parse ();
 
-                       var track = cue.get_track (0);
-                       if (track.track_mode != CueSheetTrackMode.MODE1_2352 &&
-                           track.track_mode != CueSheetTrackMode.MODE2_2352)
-                               return;
-
-                       bin_file = track.file.file;
-
-                       break;
-               // TODO Add support for binary files.
-               default:
-                       return;
-               }
-
-               var header = new PlayStationHeader (bin_file);
-               header.check_validity ();
-               var disc_id = header.disc_id;
-
-               var gameinfo = get_gameinfo ();
-               var disc_set_id = gameinfo.get_disc_set_id_for_disc_id (disc_id);
+               var disc_id = parser.get_media_id ();
+               var disc_set_id = parser.get_media_set_id ();
 
                return_if_fail (media_for_disc_id.contains (disc_id) == game_for_disc_set_id.contains 
(disc_set_id));
 
@@ -96,31 +63,14 @@ public class Games.PlayStationGameFactory : Object, UriGameFactory {
 
                // A game correspond to this URI but we don't have it yet: create it.
 
-               var new_medias = new HashTable<string, Media> (str_hash, str_equal);
-               Media[] new_medias_array = {};
-               var new_disc_ids = gameinfo.get_disc_set_ids_for_disc_id (disc_id);
-               foreach (var new_disc_id in new_disc_ids) {
-                       assert (!media_for_disc_id.contains (new_disc_id));
-
-                       var title = new GameinfoDiscIdDiscTitle (gameinfo, new_disc_id);
-                       var media = new Media (new_disc_id, title);
-                       new_medias_array += media;
-                       new_medias[new_disc_id] = media;
-               }
-
-               var media = new_medias.lookup (disc_id);
-               media.add_uri (uri);
-
-               var media_set = new MediaSet (disc_set_id, new GameinfoDiscIdGameTitle (gameinfo, 
disc_set_id));
-               foreach (var game_media in new_medias_array)
-                       media_set.add_media (game_media);
-               media_set.icon_name = ICON_NAME;
-               var game = create_game (media_set, disc_set_id, uri);
+               var media_set = parser.create_media_set ();
+               var game = create_game (media_set, uri);
 
                // Creating the Medias, MediaSet and Game worked, we can save them.
 
-               foreach (var new_disc_id in new_medias.get_keys ())
-                       media_for_disc_id[new_disc_id] = new_medias[new_disc_id];
+               media_set.foreach_media (media => {
+                       media_for_disc_id[media.id] = media;
+               });
 
                game_for_uri[uri] = game;
                game_for_disc_set_id[disc_set_id] = game;
@@ -148,16 +98,17 @@ public class Games.PlayStationGameFactory : Object, UriGameFactory {
                games.foreach ((game) => game_callback (game));
        }
 
-       private Game create_game (MediaSet media_set, string disc_set_id, Uri uri) throws Error {
-               var uid_string = @"$PLATFORM_UID_PREFIX-$disc_set_id".down ();
+       private Game create_game (MediaSet media_set, Uri uri) throws Error {
+               var prefix = platform.get_uid_prefix ();
+               var media_set_id = media_set.id;
+               var uid_string = @"$prefix-$media_set_id".down ();
 
-               var gameinfo = get_gameinfo ();
                var uid = new Uid (uid_string);
                var title = new CompositeTitle ({
-                       new GameinfoDiscIdGameTitle (gameinfo, disc_set_id),
+                       media_set.title,
                        new FilenameTitle (uri)
                });
-               var media = new GriloMedia (title, PHONY_MIME_TYPE);
+               var media = new GriloMedia (title, platform.get_presentation_mime_type ());
                var cover = new CompositeCover ({
                        new LocalCover (uri),
                        new GriloCover (media, uid)});
@@ -169,27 +120,6 @@ public class Games.PlayStationGameFactory : Object, UriGameFactory {
                return game;
        }
 
-       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;
-       }
-
        public void set_game_added_callback (GameCallback game_callback) {
                game_added_callback = game_callback;
        }
diff --git a/plugins/playstation/src/playstation-parser.vala b/plugins/playstation/src/playstation-parser.vala
new file mode 100644
index 00000000..5a388cc2
--- /dev/null
+++ b/plugins/playstation/src/playstation-parser.vala
@@ -0,0 +1,109 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+// TODO support unknown games (not in DB)
+public class Games.PlayStationParser : GameParser {
+       private const string CUE_MIME_TYPE = "application/x-cue";
+       private const string ICON_NAME = "media-optical-symbolic";
+       private const string GAMEINFO = 
"resource:///org/gnome/Games/plugin/playstation/playstation.gameinfo.xml";
+
+       private static GameinfoDoc gameinfo;
+       private string uid;
+       private string disc_id;
+       private string disc_set_id;
+
+       public PlayStationParser (Platform platform, Uri uri) {
+               base (platform, uri);
+       }
+
+       public override void parse () throws Error {
+               var file = uri.to_file ();
+               var file_info = file.query_info (FileAttribute.STANDARD_CONTENT_TYPE, 
FileQueryInfoFlags.NONE);
+               var mime_type = file_info.get_content_type ();
+
+               File bin_file;
+               switch (mime_type) {
+               case CUE_MIME_TYPE:
+                       var cue = new CueSheet (file);
+                       if (cue.tracks_number == 0)
+                               throw new PlayStationError.INVALID_CUE_SHEET ("The file “%s” doesn’t have a 
track.", cue.file.get_uri ());
+
+                       var track = cue.get_track (0);
+                       if (track.track_mode != CueSheetTrackMode.MODE1_2352 &&
+                           track.track_mode != CueSheetTrackMode.MODE2_2352)
+                               throw new PlayStationError.INVALID_CUE_SHEET ("The file “%s” doesn’t have a 
valid track mode for track %d.", cue.file.get_uri (), track.track_number);
+
+                       bin_file = track.file.file;
+
+                       break;
+               // TODO Add support for binary files.
+               default:
+                       throw new PlayStationError.INVALID_FILE_TYPE ("Invalid file type: expected %s but got 
%s for file %s.", CUE_MIME_TYPE, mime_type, uri.to_string ());
+               }
+
+               var header = new PlayStationHeader (bin_file);
+               header.check_validity ();
+
+               disc_id = header.disc_id;
+
+               var gameinfo = get_gameinfo ();
+               disc_set_id = gameinfo.get_disc_set_id_for_disc_id (disc_id);
+
+               var prefix = platform.get_uid_prefix ();
+               uid = @"$prefix-$disc_set_id".down ();
+       }
+
+       public override string get_uid () {
+               return uid;
+       }
+
+       public override string? get_media_id () {
+               return disc_id;
+       }
+
+       public override string? get_media_set_id () {
+               return disc_set_id;
+       }
+
+       public override MediaSet? create_media_set () throws Error {
+               var new_medias = new HashTable<string, Media> (str_hash, str_equal);
+               Media[] new_medias_array = {};
+               var new_disc_ids = gameinfo.get_disc_set_ids_for_disc_id (disc_id);
+               foreach (var new_disc_id in new_disc_ids) {
+                       var title = new GameinfoDiscIdDiscTitle (gameinfo, new_disc_id);
+                       var media = new Media (new_disc_id, title);
+                       new_medias_array += media;
+                       new_medias[new_disc_id] = media;
+               }
+
+               var media = new_medias.lookup (disc_id);
+               media.add_uri (uri);
+
+               var media_set = new MediaSet (disc_set_id, new GameinfoDiscIdGameTitle (gameinfo, 
disc_set_id));
+               foreach (var game_media in new_medias_array)
+                       media_set.add_media (game_media);
+               media_set.icon_name = ICON_NAME;
+
+               return media_set;
+       }
+
+       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;
+       }
+}
diff --git a/plugins/playstation/src/playstation-plugin.vala b/plugins/playstation/src/playstation-plugin.vala
index 3daeed0e..526c7a9d 100644
--- a/plugins/playstation/src/playstation-plugin.vala
+++ b/plugins/playstation/src/playstation-plugin.vala
@@ -12,6 +12,7 @@ private class Games.PlayStation : Object, Plugin {
        static construct {
                string[] mime_types = { CUE_MIME_TYPE };
                platform = new Platform.with_mime_types (PLATFORM_ID, PLATFORM_NAME, mime_types, 
PHONY_MIME_TYPE, PLATFORM_UID_PREFIX);
+               platform.parser_type = typeof (PlayStationParser);
        }
 
        public Platform[] get_platforms () {
diff --git a/src/core/game-parser.vala b/src/core/game-parser.vala
index ccf903d0..243e4eb4 100644
--- a/src/core/game-parser.vala
+++ b/src/core/game-parser.vala
@@ -22,4 +22,16 @@ public class Games.GameParser : Object {
        public virtual Icon? get_icon () {
                return null;
        }
+
+       public virtual string? get_media_id () {
+               return null;
+       }
+
+       public virtual string? get_media_set_id () {
+               return null;
+       }
+
+       public virtual MediaSet? create_media_set () throws Error {
+               return null;
+       }
 }


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