[gnome-games/wip/aplazas/781334-refactor-playstation] playstation: Make game creation more flexible
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games/wip/aplazas/781334-refactor-playstation] playstation: Make game creation more flexible
- Date: Fri, 5 May 2017 16:21:31 +0000 (UTC)
commit 36c6590c724e8b31da7b0af0d2e084a0441d945e
Author: Adrien Plazas <kekun plazas laposte net>
Date: Fri Apr 14 15:48:04 2017 +0200
playstation: Make game creation more flexible
.../playstation/src/playstation-game-factory.vala | 187 +++++++++-----------
1 files changed, 84 insertions(+), 103 deletions(-)
---
diff --git a/plugins/playstation/src/playstation-game-factory.vala
b/plugins/playstation/src/playstation-game-factory.vala
index 489739b..26e3f87 100644
--- a/plugins/playstation/src/playstation-game-factory.vala
+++ b/plugins/playstation/src/playstation-game-factory.vala
@@ -1,166 +1,147 @@
// This file is part of GNOME Games. License: GPL-3.0+.
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 CUE_MIME_TYPE = "application/x-cue";
+ private const string PHONY_MIME_TYPE = "application/x-playstation-rom";
private const string PLATFORM = "PlayStation";
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 HashTable<string, string> discs;
- private HashTable<string, GenericSet<string>> disc_sets;
- private HashTable<string, Game> games;
+ private HashTable<string, Media> media_for_disc_id;
+ private HashTable<string, Game> game_for_uri;
+ private HashTable<string, Game> game_for_disc_set_id;
+ private GenericSet<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);
+ media_for_disc_id = new HashTable<string, Media> (str_hash, str_equal);
+ game_for_uri = new HashTable<string, Game> (GLib.str_hash, GLib.str_equal);
+ game_for_disc_set_id = new HashTable<string, Game> (GLib.str_hash, GLib.str_equal);
+ games = new GenericSet<Game> (direct_hash, direct_equal);
}
public string[] get_mime_types () {
- return { SEARCHED_MIME_TYPE };
+ return { CUE_MIME_TYPE };
}
public async Game? query_game_for_uri (string uri) {
Idle.add (this.query_game_for_uri.callback);
yield;
- // TODO
+ if (game_for_uri.contains (uri))
+ return game_for_uri[uri];
return null;
}
public async void add_uri (string uri) {
- string disc_id;
-
try {
- disc_id = get_disc_id (uri);
+ add_uri_with_error (uri);
}
catch (Error e) {
- return;
+ debug (e.message);
}
-
- 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;
+ // TODO support unknown games (not in DB)
+ private void add_uri_with_error (string uri) throws Error {
+ if (game_for_uri.contains (uri))
+ return;
- 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);
- }
+ var file = File.new_for_uri (uri);
+ var file_info = file.query_info (FileAttribute.STANDARD_CONTENT_TYPE,
FileQueryInfoFlags.NONE);
+ var mime_type = file_info.get_content_type ();
- if (!(disc_set_id in disc_sets))
- disc_sets[disc_set_id] = new GenericSet<string> (GLib.str_hash,
GLib.str_equal);
+ File bin_file;
+ switch (mime_type) {
+ case CUE_MIME_TYPE:
+ var cue = new CueSheet (file);
+ if (cue.tracks_number == 0)
+ return;
- disc_sets[disc_set_id].add (disc_id);
- });
+ var track = cue.get_track (0);
+ if (track.track_mode != CueSheetTrackMode.MODE2_2352)
+ return;
- 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);
- }
- });
+ bin_file = track.file.file;
- games.foreach ((disc_set_id, game) => {
- game_callback (game);
- });
- }
+ break;
+ // TODO Add support for binary files.
+ default:
+ return;
+ }
- 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 ();
+ var disc_id = header.disc_id;
- return header.disc_id;
- }
+ var gameinfo = get_gameinfo ();
+ var disc_set_id = gameinfo.get_disc_set_id_for_disc_id (disc_id);
- private Game game_for_disc_set (GenericSet<string> disc_set) throws Error {
- Media[] medias = {};
+ return_if_fail (media_for_disc_id.contains (disc_id) == game_for_disc_set_id.contains
(disc_set_id));
- var gameinfo = get_gameinfo ();
- var disc_list = disc_set.get_values ();
- disc_list.sort_with_data ((disc_id_a, disc_id_b) => {
- int index_a;
- int index_b;
- try {
- index_a = gameinfo.get_disc_set_index_for_disc_id (disc_id_a);
- index_b = gameinfo.get_disc_set_index_for_disc_id (disc_id_b);
- }
- catch (Error e) {
- debug (e.message);
-
- return 0;
- }
-
- return (int) (index_a > index_b) - (int) (index_a < index_b);
- });
+ // Check whether we already have a media and by extension a media set
+ // and a game for this disc ID. If such a case, simply add the new URI.
+ if (media_for_disc_id.contains (disc_id)) {
+ var media = media_for_disc_id.lookup (disc_id);
+ media.add_uri (uri);
+ game_for_uri[uri] = game_for_disc_set_id[disc_set_id];
+
+ return;
+ }
+
+ // 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));
- disc_list.foreach ((disc_id) => {
- var uri = discs[disc_id];
- var title = new GameinfoDiscIdDiscTitle (gameinfo, disc_id);
+ var title = new GameinfoDiscIdDiscTitle (gameinfo, new_disc_id);
var media = new Media (title);
- media.add_uri (uri);
- medias += media;
- });
+ new_medias_array += media;
+ new_medias[new_disc_id] = media;
+ }
+
+ var media = new_medias.lookup (disc_id);
+ media.add_uri (uri);
var icon = GLib.Icon.new_for_string (ICON_NAME);
- var media_set = new MediaSet (medias, icon);
+ var media_set = new MediaSet (new_medias_array, icon);
+ var game = create_game (media_set, disc_set_id, uri);
+
+ // Creating the Medias, MediaSet and Game worked, we can save them.
- var game = game_for_uris (media_set);
+ foreach (var new_disc_id in new_medias.get_keys ())
+ media_for_disc_id[new_disc_id] = new_medias[new_disc_id];
- return game;
+ game_for_uri[uri] = game;
+ game_for_disc_set_id[disc_set_id] = game;
+ games.add (game);
+ game_added (game);
}
- private Game game_for_uris (MediaSet media_set) throws Error {
- var selected_media = media_set.get_selected_media (0);
- var uris = selected_media.get_uris ();
- // FIXME Check that there is at least one URI.
- var uri = uris[0];
- 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 ();
+ public async void foreach_game (GameCallback game_callback) {
+ games.foreach ((game) => game_callback (game));
+ }
+ private Game create_game (MediaSet media_set, string disc_set_id, string uri) throws Error {
var gameinfo = get_gameinfo ();
- var uid = new PlayStationUid (header.disc_id);
+ var uid = new PlayStationUid (disc_set_id);
var title = new CompositeTitle ({
- new GameinfoDiscIdGameTitle (gameinfo, header.disc_id),
+ new GameinfoDiscIdGameTitle (gameinfo, disc_set_id),
new FilenameTitle (uri)
});
var icon = new DummyIcon ();
- var media = new GriloMedia (title, SPECIFIC_MIME_TYPE);
+ var media = new GriloMedia (title, PHONY_MIME_TYPE);
var cover = new CompositeCover ({
new LocalCover (uri),
new GriloCover (media, uid)});
- var input_capabilities = new GameinfoDiscIdInputCapabilities (gameinfo, header.disc_id);
- var core_source = new RetroCoreSource (PLATFORM, { SEARCHED_MIME_TYPE, SPECIFIC_MIME_TYPE });
+ var input_capabilities = new GameinfoDiscIdInputCapabilities (gameinfo, disc_set_id);
+ var core_source = new RetroCoreSource (PLATFORM, { CUE_MIME_TYPE, PHONY_MIME_TYPE });
var runner = new RetroRunner.for_media_set_and_input_capabilities (core_source, media_set,
uid, input_capabilities, title);
return new GenericGame (title, icon, cover, runner);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]