diff --git a/src/core/cooperative.vala b/src/core/cooperative.vala index 40945b3dc9ef131d9167bf0190470088574528e7..ffc62fbf6cba3a254cb4fe0dbed827dd943ec15c 100644 --- a/src/core/cooperative.vala +++ b/src/core/cooperative.vala @@ -1,7 +1,7 @@ // This file is part of GNOME Games. License: GPL-3.0+. public interface Games.Cooperative : Object { - public signal void changed (); + public abstract bool has_loaded { get; protected set; } public abstract bool get_cooperative (); } diff --git a/src/core/description.vala b/src/core/description.vala index 69058c8a1ee41640d500c019898450ca8545bed1..b4d771de755e0819acc6ed82025450e963afeb11 100644 --- a/src/core/description.vala +++ b/src/core/description.vala @@ -1,7 +1,7 @@ // This file is part of GNOME Games. License: GPL-3.0+. public interface Games.Description : Object { - public signal void changed (); + public abstract bool has_loaded { get; protected set; } public abstract string get_description (); } diff --git a/src/core/developer.vala b/src/core/developer.vala index a0507c176fde1aa4e66aa031c417f4697dcc663b..771fa30c6fbe77bef2fe7503a9acbb44388f8ff5 100644 --- a/src/core/developer.vala +++ b/src/core/developer.vala @@ -1,7 +1,7 @@ // This file is part of GNOME Games. License: GPL-3.0+. public interface Games.Developer : Object { - public signal void changed (); + public abstract bool has_loaded { get; protected set; } public abstract string get_developer (); diff --git a/src/core/genre.vala b/src/core/genre.vala index 8411d214d0493e5a0d63bd02729bd4d22445b54d..84a0be86e60f92dd0c9b5618109db933c3bc785b 100644 --- a/src/core/genre.vala +++ b/src/core/genre.vala @@ -1,7 +1,7 @@ // This file is part of GNOME Games. License: GPL-3.0+. public interface Games.Genre : Object { - public signal void changed (); + public abstract bool has_loaded { get; protected set; } public abstract unowned string[] get_genre (); } diff --git a/src/core/players.vala b/src/core/players.vala index bcf285555a6ec18422f2e6dbc26e003557f9bf00..35905b3d13e2b01ef506705f69ee9d1bc001453f 100644 --- a/src/core/players.vala +++ b/src/core/players.vala @@ -1,7 +1,7 @@ // This file is part of GNOME Games. License: GPL-3.0+. public interface Games.Players : Object { - public signal void changed (); + public abstract bool has_loaded { get; protected set; } public abstract string get_players (); } diff --git a/src/core/publisher.vala b/src/core/publisher.vala index f50ea2c9b29e63d6449e31a9bfd8c32215881ba9..753542d2e27d8808ea2e4823fafa5b8620872a2e 100644 --- a/src/core/publisher.vala +++ b/src/core/publisher.vala @@ -1,7 +1,7 @@ // This file is part of GNOME Games. License: GPL-3.0+. public interface Games.Publisher : Object { - public signal void changed (); + public abstract bool has_loaded { get; protected set; } public abstract string get_publisher (); } diff --git a/src/core/rating.vala b/src/core/rating.vala index 88313378d20af3aca0266e7e2e212cdd8dc57895..b2bc2f2375536b416a1e235ce05ab401a9e0a6bb 100644 --- a/src/core/rating.vala +++ b/src/core/rating.vala @@ -1,7 +1,7 @@ // This file is part of GNOME Games. License: GPL-3.0+. public interface Games.Rating : Object { - public signal void changed (); + public abstract bool has_loaded { get; protected set; } public abstract float get_rating (); } diff --git a/src/core/release-date.vala b/src/core/release-date.vala index 6461f2e6c14b323e81d25c74c19af1647eb15d9d..ba00f60e64871dedf1bba2ccb0c30226f060ecb4 100644 --- a/src/core/release-date.vala +++ b/src/core/release-date.vala @@ -1,7 +1,7 @@ // This file is part of GNOME Games. License: GPL-3.0+. public interface Games.ReleaseDate : Object { - public signal void changed (); + public abstract bool has_loaded { get; protected set; } public abstract DateTime get_release_date (); } diff --git a/src/database/database-cooperative.vala b/src/database/database-cooperative.vala new file mode 100644 index 0000000000000000000000000000000000000000..b513159e7f50504633db639c393631c28fa57f3e --- /dev/null +++ b/src/database/database-cooperative.vala @@ -0,0 +1,26 @@ +// This file is part of GNOME Games. License: GPL-3.0+. + +private class Games.DatabaseCooperative : Object, Cooperative { + private DatabaseMetadata metadata; + + public bool has_loaded { get; protected set; } + + public DatabaseCooperative (DatabaseMetadata metadata) { + this.metadata = metadata; + + if (metadata.cooperative_loaded) + has_loaded = true; + else { + metadata.notify["cooperative-loaded"].connect (on_cooperative_loaded); + metadata.get_cooperative (); + } + } + + private void on_cooperative_loaded (Object object, ParamSpec param) { + has_loaded = metadata.cooperative_loaded; + } + + public bool get_cooperative () { + return metadata.get_cooperative (); + } +} diff --git a/src/database/database-description.vala b/src/database/database-description.vala new file mode 100644 index 0000000000000000000000000000000000000000..7c786ff86502bb251f13550a8d54c9ea710bb7f2 --- /dev/null +++ b/src/database/database-description.vala @@ -0,0 +1,26 @@ +// This file is part of GNOME Games. License: GPL-3.0+. + +private class Games.DatabaseDescription : Object, Description { + private DatabaseMetadata metadata; + + public bool has_loaded { get; protected set; } + + public DatabaseDescription (DatabaseMetadata metadata) { + this.metadata = metadata; + + if (metadata.description_loaded) + has_loaded = true; + else { + metadata.notify["description-loaded"].connect (on_description_loaded); + metadata.get_description (); + } + } + + private void on_description_loaded (Object object, ParamSpec param) { + has_loaded = metadata.description_loaded; + } + + public string get_description () { + return metadata.get_description (); + } +} diff --git a/src/database/database-developer.vala b/src/database/database-developer.vala index ef17dd87b935b1ebc7d3f2db2270a04ee389ccf4..8293ba4bcbe350906a25d4b2b2cd35d9ba47e873 100644 --- a/src/database/database-developer.vala +++ b/src/database/database-developer.vala @@ -1,75 +1,26 @@ // This file is part of GNOME Games. License: GPL-3.0+. private class Games.DatabaseDeveloper : Object, Developer { - private const string LOAD_DEVELOPER_QUERY = """ - SELECT developer FROM game_metadata WHERE uid=$UID; - """; + private DatabaseMetadata metadata; - private const string SAVE_DEVELOPER_QUERY = """ - UPDATE game_metadata SET developer=$DEVELOPER WHERE uid=$UID; - """; + public bool has_loaded { get; protected set; } - private Developer developer; - private Uid uid; - private Sqlite.Statement load_statement; - private Sqlite.Statement save_statement; - private string loaded; + public DatabaseDeveloper (DatabaseMetadata metadata) { + this.metadata = metadata; - public DatabaseDeveloper (Sqlite.Database database, Developer developer, Uid uid) { - this.developer = developer; - this.uid = uid; - - developer.changed.connect (() => changed ()); - - try { - load_statement = Database.prepare (database, LOAD_DEVELOPER_QUERY); - save_statement = Database.prepare (database, SAVE_DEVELOPER_QUERY); - } - catch (Error e) { - warning (e.message); + if (metadata.developer_loaded) + has_loaded = true; + else { + metadata.notify["developer-loaded"].connect (on_developer_loaded); + metadata.get_developer (); } } - public string get_developer () { - try { - if (loaded == null) - load_developer (); - if (loaded != "") - return loaded; - else - save_developer (); - } - catch (Error e) { - warning (e.message); - } - - return developer.get_developer (); + private void on_developer_loaded (Object object, ParamSpec param) { + has_loaded = metadata.developer_loaded; } - private void load_developer () throws Error { - if (load_statement == null) - return; - - Database.bind_text (load_statement, "$UID", uid.get_uid ()); - - if (load_statement.step () == Sqlite.ROW) - loaded = load_statement.column_text (0) ?? ""; - else - warning ("Execution failed."); - } - - private void save_developer () throws Error { - if (save_statement == null) - return; - - loaded = developer.get_developer (); - if (loaded == "") - return; - - Database.bind_text (save_statement, "$UID", uid.get_uid ()); - Database.bind_text (save_statement, "$DEVELOPER", loaded); - - if (save_statement.step () != Sqlite.DONE) - warning ("Execution failed."); + public string get_developer () { + return metadata.get_developer (); } } diff --git a/src/database/database-game.vala b/src/database/database-game.vala index fe322f5b34f0688f56a41cbb60fd8d7070b05fa3..af2526e22f33ee65b0a8f033fea72015adf882b4 100644 --- a/src/database/database-game.vala +++ b/src/database/database-game.vala @@ -8,13 +8,33 @@ private class Games.DatabaseGame : Object, Game { private Database database; private Game game; + private Cooperative cooperative; + private Description description; + private Developer developer; + private Genre genre; + private Players players; + private Publisher publisher; + private Rating rating; + private ReleaseDate release_date; + public DatabaseGame (Database database, Game game) { this.database = database; this.game = game; + + var metadata = database.get_metadata (game); + + cooperative = new DatabaseCooperative (metadata); + description = new DatabaseDescription (metadata); + developer = new DatabaseDeveloper (metadata); + genre = new DatabaseGenre (metadata); + players = new DatabasePlayers (metadata); + publisher = new DatabasePublisher (metadata); + rating = new DatabaseRating (metadata); + release_date = new DatabaseReleaseDate (metadata); } public Uid get_uid () { - return database.get_uid (game.get_uid ()); + return game.get_uid (); } public Icon get_icon () { @@ -26,35 +46,35 @@ private class Games.DatabaseGame : Object, Game { } public ReleaseDate get_release_date () { - return game.get_release_date (); + return release_date; } public Cooperative get_cooperative () { - return game.get_cooperative (); + return cooperative; } public Genre get_genre () { - return game.get_genre (); + return genre; } public Players get_players () { - return game.get_players (); + return players; } public Developer get_developer () { - return database.get_developer (game.get_developer (), get_uid ()); + return developer; } public Publisher get_publisher () { - return game.get_publisher (); + return publisher; } public Description get_description () { - return game.get_description (); + return description; } public Rating get_rating () { - return game.get_rating (); + return rating; } public Platform get_platform () { diff --git a/src/database/database-genre.vala b/src/database/database-genre.vala new file mode 100644 index 0000000000000000000000000000000000000000..4ab213342443d69adc66ee2fe7975f39a47fd94f --- /dev/null +++ b/src/database/database-genre.vala @@ -0,0 +1,26 @@ +// This file is part of GNOME Games. License: GPL-3.0+. + +private class Games.DatabaseGenre : Object, Genre { + private DatabaseMetadata metadata; + + public bool has_loaded { get; protected set; } + + public DatabaseGenre (DatabaseMetadata metadata) { + this.metadata = metadata; + + if (metadata.genre_loaded) + has_loaded = true; + else { + metadata.notify["genre-loaded"].connect (on_genre_loaded); + metadata.get_genre (); + } + } + + private void on_genre_loaded (Object object, ParamSpec param) { + has_loaded = metadata.genre_loaded; + } + + public unowned string[] get_genre () { + return metadata.get_genre (); + } +} diff --git a/src/database/database-metadata.vala b/src/database/database-metadata.vala new file mode 100644 index 0000000000000000000000000000000000000000..8ef24d4d5dafb7efe88fe168aa55058aef5091b9 --- /dev/null +++ b/src/database/database-metadata.vala @@ -0,0 +1,493 @@ +// This file is part of GNOME Games. License: GPL-3.0+. + +private class Games.DatabaseMetadata : Object { + private const string LOAD_QUERY = """ + SELECT + cooperative, + description, + developer, + genre, + players, + publisher, + rating, + release_date + FROM game_metadata WHERE uid=$UID; + """; + + private const string ADD_GAME_QUERY = """ + INSERT OR IGNORE INTO game_metadata (uid) VALUES ($UID); + """; + + private const string SAVE_COOPERATIVE_QUERY = """ + UPDATE game_metadata SET cooperative=$COOPERATIVE WHERE uid=$UID; + """; + + private const string SAVE_DESCRIPTION_QUERY = """ + UPDATE game_metadata SET description=$DESCRIPTION WHERE uid=$UID; + """; + + private const string SAVE_DEVELOPER_QUERY = """ + UPDATE game_metadata SET developer=$DEVELOPER WHERE uid=$UID; + """; + + private const string SAVE_GENRE_QUERY = """ + UPDATE game_metadata SET genre=$GENRE WHERE uid=$UID; + """; + + private const string SAVE_PLAYERS_QUERY = """ + UPDATE game_metadata SET players=$PLAYERS WHERE uid=$UID; + """; + + private const string SAVE_PUBLISHER_QUERY = """ + UPDATE game_metadata SET publisher=$PUBLISHER WHERE uid=$UID; + """; + + private const string SAVE_RATING_QUERY = """ + UPDATE game_metadata SET rating=$RATING WHERE uid=$UID; + """; + + private const string SAVE_RELEASE_DATE_QUERY = """ + UPDATE game_metadata SET release_date=$RELEASE_DATE WHERE uid=$UID; + """; + + private Game game; + private Uid uid; + private Cooperative cooperative; + private Description description; + private Developer developer; + private Genre genre; + private Players players; + private Publisher publisher; + private Rating rating; + private ReleaseDate release_date; + + private string uid_value; + private bool cooperative_value; + private string description_value; + private string developer_value; + private string[] genre_value; + private string players_value; + private string publisher_value; + private float rating_value; + private DateTime release_date_value; + + private Sqlite.Statement add_game_statement; + private Sqlite.Statement load_statement; + private Sqlite.Statement save_cooperative_statement; + private Sqlite.Statement save_description_statement; + private Sqlite.Statement save_developer_statement; + private Sqlite.Statement save_genre_statement; + private Sqlite.Statement save_players_statement; + private Sqlite.Statement save_publisher_statement; + private Sqlite.Statement save_rating_statement; + private Sqlite.Statement save_release_date_statement; + + public bool cooperative_loaded { get; set; } + public bool description_loaded { get; set; } + public bool developer_loaded { get; set; } + public bool genre_loaded { get; set; } + public bool players_loaded { get; set; } + public bool publisher_loaded { get; set; } + public bool rating_loaded { get; set; } + public bool release_date_loaded { get; set; } + + private bool game_added; + + public DatabaseMetadata (Sqlite.Database database, Game game) { + this.game = game; + + uid = game.get_uid (); + cooperative = game.get_cooperative (); + description = game.get_description (); + developer = game.get_developer (); + genre = game.get_genre (); + players = game.get_players (); + publisher = game.get_publisher (); + rating = game.get_rating (); + release_date = game.get_release_date (); + + try { + uid_value = game.get_uid ().get_uid (); + + add_game_statement = Database.prepare (database, ADD_GAME_QUERY); + load_statement = Database.prepare (database, LOAD_QUERY); + save_cooperative_statement = Database.prepare (database, SAVE_COOPERATIVE_QUERY); + save_description_statement = Database.prepare (database, SAVE_DESCRIPTION_QUERY); + save_developer_statement = Database.prepare (database, SAVE_DEVELOPER_QUERY); + save_genre_statement = Database.prepare (database, SAVE_GENRE_QUERY); + save_players_statement = Database.prepare (database, SAVE_PLAYERS_QUERY); + save_publisher_statement = Database.prepare (database, SAVE_PUBLISHER_QUERY); + save_rating_statement = Database.prepare (database, SAVE_RATING_QUERY); + save_release_date_statement = Database.prepare (database, SAVE_RELEASE_DATE_QUERY); + + load_metadata (); + } + catch (Error e) { + warning (e.message); + } + } + + public bool get_cooperative () { + if (!cooperative_loaded) { + on_cooperative_loaded (); + cooperative.notify.connect (on_cooperative_loaded); + return cooperative.get_cooperative (); + } + + return cooperative_value; + } + + public string get_description () { + if (!description_loaded) { + on_description_loaded (); + description.notify.connect (on_description_loaded); + return description.get_description (); + } + + return description_value; + } + + public string get_developer () { + if (!developer_loaded) { + on_developer_loaded (); + developer.notify.connect (on_developer_loaded); + return developer.get_developer (); + } + + return developer_value; + } + + public unowned string[] get_genre () { + if (!genre_loaded) { + on_genre_loaded (); + genre.notify.connect (on_genre_loaded); + return genre.get_genre (); + } + + return genre_value; + } + + public string get_players () { + if (!players_loaded) { + on_players_loaded (); + players.notify.connect (on_players_loaded); + return players.get_players (); + } + + return players_value; + } + + public string get_publisher () { + if (!publisher_loaded) { + on_publisher_loaded (); + publisher.notify.connect (on_publisher_loaded); + return publisher.get_publisher (); + } + + return publisher_value; + } + + public float get_rating () { + if (!rating_loaded) { + on_rating_loaded (); + rating.notify.connect (on_rating_loaded); + return rating.get_rating (); + } + + return rating_value; + } + + public DateTime get_release_date () { + if (!release_date_loaded) { + on_release_date_loaded (); + release_date.notify.connect (on_release_date_loaded); + return release_date.get_release_date (); + } + + return release_date_value; + } + + private void on_cooperative_loaded () { + if (!cooperative.has_loaded) + return; + + cooperative_value = cooperative.get_cooperative (); + cooperative_loaded = true; + + add_game (); + save_cooperative (); + } + + private void on_description_loaded () { + if (!description.has_loaded) + return; + + description_value = description.get_description (); + description_loaded = true; + + add_game (); + save_description (); + } + + private void on_developer_loaded () { + if (!developer.has_loaded) + return; + + developer_value = developer.get_developer (); + developer_loaded = true; + + add_game (); + save_developer (); + } + + private void on_genre_loaded () { + if (!genre.has_loaded) + return; + + genre_value = genre.get_genre ().copy (); + genre_loaded = true; + + add_game (); + save_genre (); + } + + private void on_players_loaded () { + if (!players.has_loaded) + return; + + players_value = players.get_players (); + players_loaded = true; + + add_game (); + save_players (); + } + + private void on_publisher_loaded () { + if (!publisher.has_loaded) + return; + + publisher_value = publisher.get_publisher (); + publisher_loaded = true; + + add_game (); + save_publisher (); + } + + private void on_rating_loaded () { + if (!rating.has_loaded) + return; + + rating_value = rating.get_rating (); + rating_loaded = true; + + add_game (); + save_rating (); + } + + private void on_release_date_loaded () { + if (!release_date.has_loaded) + return; + + release_date_value = release_date.get_release_date (); + release_date_loaded = true; + + add_game (); + save_release_date (); + } + + private void save_cooperative () { + try { + save_cooperative_statement.reset (); + Database.bind_text (save_cooperative_statement, "$UID", uid_value); + Database.bind_int (save_cooperative_statement, "$COOPERATIVE", cooperative_value ? 1 : 0); + + if (save_cooperative_statement.step () != Sqlite.DONE) + warning ("Execution failed."); + } + catch (Error e) { + warning (e.message); + } + } + + private void save_description () { + try { + save_description_statement.reset (); + Database.bind_text (save_description_statement, "$UID", uid_value); + Database.bind_text (save_description_statement, "$DESCRIPTION", description_value); + + if (save_description_statement.step () != Sqlite.DONE) + warning ("Execution failed."); + } + catch (Error e) { + warning (e.message); + } + } + + private void save_developer () { + try { + save_developer_statement.reset (); + Database.bind_text (save_developer_statement, "$UID", uid_value); + Database.bind_text (save_developer_statement, "$DEVELOPER", developer_value); + + if (save_developer_statement.step () != Sqlite.DONE) + warning ("Execution failed."); + } + catch (Error e) { + warning (e.message); + } + } + + private void save_genre () { + try { + var variant = new Variant.strv (genre_value); + var string_value = variant.print (false); + + save_genre_statement.reset (); + Database.bind_text (save_genre_statement, "$UID", uid_value); + Database.bind_text (save_genre_statement, "$GENRE", string_value); + + if (save_genre_statement.step () != Sqlite.DONE) + warning ("Execution failed."); + } + catch (Error e) { + warning (e.message); + } + } + + private void save_players () { + try { + save_players_statement.reset (); + Database.bind_text (save_players_statement, "$UID", uid_value); + Database.bind_text (save_players_statement, "$PLAYERS", players_value); + + if (save_players_statement.step () != Sqlite.DONE) + warning ("Execution failed."); + } + catch (Error e) { + warning (e.message); + } + } + + private void save_publisher () { + try { + save_publisher_statement.reset (); + Database.bind_text (save_publisher_statement, "$UID", uid_value); + Database.bind_text (save_publisher_statement, "$PUBLISHER", publisher_value); + + if (save_publisher_statement.step () != Sqlite.DONE) + warning ("Execution failed."); + } + catch (Error e) { + warning (e.message); + } + } + + private void save_rating () { + try { + save_rating_statement.reset (); + Database.bind_text (save_rating_statement, "$UID", uid_value); + Database.bind_double (save_rating_statement, "$RATING", rating_value); + + if (save_rating_statement.step () != Sqlite.DONE) + warning ("Execution failed."); + } + catch (Error e) { + warning (e.message); + } + } + + private void save_release_date () { + try { + var string_value = ""; + if (release_date_value != null) + string_value = release_date_value.format ("%F"); + + save_release_date_statement.reset (); + Database.bind_text (save_release_date_statement, "$UID", uid_value); + Database.bind_text (save_release_date_statement, "$RELEASE_DATE", string_value); + + if (save_release_date_statement.step () != Sqlite.DONE) + warning ("Execution failed."); + } + catch (Error e) { + warning (e.message); + } + } + + private void add_game () { + if (game_added) + return; + + game_added = true; + + try { + add_game_statement.reset (); + + Database.bind_text (add_game_statement, "$UID", uid_value); + + if (add_game_statement.step () != Sqlite.DONE) + warning ("Execution failed."); + } + catch (Error e) { + warning (e.message); + } + } + + private void load_metadata () throws Error { + load_statement.reset (); + + Database.bind_text (load_statement, "$UID", uid_value); + + if (load_statement.step () == Sqlite.ROW) { + if (load_statement.column_type (0) != Sqlite.NULL) { + cooperative_value = load_statement.column_int (0) == 1; + cooperative_loaded = true; + } + + if (load_statement.column_type (1) != Sqlite.NULL) { + description_value = load_statement.column_text (1); + description_loaded = true; + } + + if (load_statement.column_type (2) != Sqlite.NULL) { + developer_value = load_statement.column_text (2); + developer_loaded = true; + } + + if (load_statement.column_type (3) != Sqlite.NULL) { + var string_value = load_statement.column_text (3); + var variant = Variant.parse (VariantType.STRING_ARRAY, string_value); + genre_value = variant.get_strv (); + + genre_loaded = true; + } + + if (load_statement.column_type (4) != Sqlite.NULL) { + players_value = load_statement.column_text (4); + players_loaded = true; + } + + if (load_statement.column_type (5) != Sqlite.NULL) { + publisher_value = load_statement.column_text (5); + publisher_loaded = true; + } + + if (load_statement.column_type (6) != Sqlite.NULL) { + rating_value = (float) load_statement.column_double (6); + rating_loaded = true; + } + + if (load_statement.column_type (7) != Sqlite.NULL) { + var string_value = load_statement.column_text (7); + + if (string_value != "") { + var timezone = new TimeZone.utc (); + + release_date_value = new DateTime.from_iso8601 (string_value, timezone); + } + + release_date_loaded = true; + } + } + } +} diff --git a/src/database/database-players.vala b/src/database/database-players.vala new file mode 100644 index 0000000000000000000000000000000000000000..be79af765161db8d8d05b2a8a19cb55327707c7e --- /dev/null +++ b/src/database/database-players.vala @@ -0,0 +1,26 @@ +// This file is part of GNOME Games. License: GPL-3.0+. + +private class Games.DatabasePlayers : Object, Players { + private DatabaseMetadata metadata; + + public bool has_loaded { get; protected set; } + + public DatabasePlayers (DatabaseMetadata metadata) { + this.metadata = metadata; + + if (metadata.players_loaded) + has_loaded = true; + else { + metadata.notify["players-loaded"].connect (on_players_loaded); + metadata.get_players (); + } + } + + private void on_players_loaded (Object object, ParamSpec param) { + has_loaded = metadata.players_loaded; + } + + public string get_players () { + return metadata.get_players (); + } +} diff --git a/src/database/database-publisher.vala b/src/database/database-publisher.vala new file mode 100644 index 0000000000000000000000000000000000000000..c19bc48a215d1ea31d414366f18fd3ed7f864f2b --- /dev/null +++ b/src/database/database-publisher.vala @@ -0,0 +1,26 @@ +// This file is part of GNOME Games. License: GPL-3.0+. + +private class Games.DatabasePublisher : Object, Publisher { + private DatabaseMetadata metadata; + + public bool has_loaded { get; protected set; } + + public DatabasePublisher (DatabaseMetadata metadata) { + this.metadata = metadata; + + if (metadata.publisher_loaded) + has_loaded = true; + else { + metadata.notify["publisher-loaded"].connect (on_publisher_loaded); + metadata.get_publisher (); + } + } + + private void on_publisher_loaded (Object object, ParamSpec param) { + has_loaded = metadata.publisher_loaded; + } + + public string get_publisher () { + return metadata.get_publisher (); + } +} diff --git a/src/database/database-rating.vala b/src/database/database-rating.vala new file mode 100644 index 0000000000000000000000000000000000000000..a4e9e9c0976a0d206d3360689c008082c9919fc5 --- /dev/null +++ b/src/database/database-rating.vala @@ -0,0 +1,26 @@ +// This file is part of GNOME Games. License: GPL-3.0+. + +private class Games.DatabaseRating : Object, Rating { + private DatabaseMetadata metadata; + + public bool has_loaded { get; protected set; } + + public DatabaseRating (DatabaseMetadata metadata) { + this.metadata = metadata; + + if (metadata.rating_loaded) + has_loaded = true; + else { + metadata.notify["rating-loaded"].connect (on_rating_loaded); + metadata.get_rating (); + } + } + + private void on_rating_loaded (Object object, ParamSpec param) { + has_loaded = metadata.rating_loaded; + } + + public float get_rating () { + return metadata.get_rating (); + } +} diff --git a/src/database/database-release-date.vala b/src/database/database-release-date.vala new file mode 100644 index 0000000000000000000000000000000000000000..97ce9ed6565cf6cad796b945150940db4cf06a20 --- /dev/null +++ b/src/database/database-release-date.vala @@ -0,0 +1,26 @@ +// This file is part of GNOME Games. License: GPL-3.0+. + +private class Games.DatabaseReleaseDate : Object, ReleaseDate { + private DatabaseMetadata metadata; + + public bool has_loaded { get; protected set; } + + public DatabaseReleaseDate (DatabaseMetadata metadata) { + this.metadata = metadata; + + if (metadata.release_date_loaded) + has_loaded = true; + else { + metadata.notify["release-date-loaded"].connect (on_release_date_loaded); + metadata.get_release_date (); + } + } + + private void on_release_date_loaded (Object object, ParamSpec param) { + has_loaded = metadata.release_date_loaded; + } + + public DateTime get_release_date () { + return metadata.get_release_date (); + } +} diff --git a/src/database/database-uid.vala b/src/database/database-uid.vala deleted file mode 100644 index b5700e18ce2d6ebffdd916890634f7855252e049..0000000000000000000000000000000000000000 --- a/src/database/database-uid.vala +++ /dev/null @@ -1,66 +0,0 @@ -// This file is part of GNOME Games. License: GPL-3.0+. - -private class Games.DatabaseUid : Object, Uid { - private const string HAS_UID_QUERY = """ - SELECT EXISTS (SELECT 1 FROM game_metadata WHERE uid=$UID LIMIT 1); - """; - - private const string ADD_UID_QUERY = """ - INSERT INTO game_metadata (uid) VALUES ($UID); - """; - - private Uid uid; - private Sqlite.Statement has_statement; - private Sqlite.Statement add_statement; - private bool has; - - internal DatabaseUid (Sqlite.Database database, Uid uid) { - this.uid = uid; - - try { - has_statement = Database.prepare (database, HAS_UID_QUERY); - add_statement = Database.prepare (database, ADD_UID_QUERY); - } - catch (Error e) { - warning (e.message); - } - } - - public string get_uid () throws Error { - try { - if (!has) - has_uid (); - if (!has) - add_uid (); - } - catch (Error e) { - warning (e.message); - } - - return uid.get_uid (); - } - - private void has_uid () throws Error { - if (has_statement == null) - return; - - Database.bind_text (has_statement, "$UID", uid.get_uid ()); - - if (has_statement.step () == Sqlite.ROW) - has = has_statement.column_text (0) == "1"; - else - warning ("Execution failed."); - } - - private void add_uid () throws Error { - if (add_statement == null) - return; - - has = true; - - Database.bind_text (add_statement, "$UID", uid.get_uid ()); - - if (add_statement.step () != Sqlite.DONE) - warning ("Execution failed."); - } -} diff --git a/src/database/database.vala b/src/database/database.vala index b513df88b73e018e2f28191646791f14f9cb0784..5ce1545a3f3daaa536bec119abfe09d4201580a2 100644 --- a/src/database/database.vala +++ b/src/database/database.vala @@ -21,7 +21,14 @@ private class Games.Database : Object { private const string CREATE_METADATA_TABLE_QUERY = """ CREATE TABLE IF NOT EXISTS game_metadata ( uid TEXT PRIMARY KEY NOT NULL, - developer TEXT + cooperative INTEGER, + description TEXT, + developer TEXT, + genre TEXT, + players TEXT, + publisher TEXT, + rating REAL, + release_date TEXT ) WITHOUT ROWID; """; @@ -63,12 +70,8 @@ private class Games.Database : Object { return new DatabaseUriSource (database); } - public DatabaseUid get_uid (Uid uid) { - return new DatabaseUid (database, uid); - } - - public DatabaseDeveloper get_developer (Developer developer, Uid uid) { - return new DatabaseDeveloper (database, developer, uid); + public DatabaseMetadata get_metadata (Game game) { + return new DatabaseMetadata (database, game); } private void create_tables () throws Error { @@ -91,6 +94,22 @@ private class Games.Database : Object { return statement; } + internal static void bind_double (Sqlite.Statement statement, string parameter, double val) throws Error { + var position = statement.bind_parameter_index (parameter); + if (position <= 0) + throw new DatabaseError.BINDING_FAILED ("Couldn't bind double to the parameter ā€œ%sā€, unexpected position: %d.", parameter, position); + + statement.bind_double (position, val); + } + + internal static void bind_int (Sqlite.Statement statement, string parameter, int val) throws Error { + var position = statement.bind_parameter_index (parameter); + if (position <= 0) + throw new DatabaseError.BINDING_FAILED ("Couldn't bind int to the parameter ā€œ%sā€, unexpected position: %d.", parameter, position); + + statement.bind_int (position, val); + } + internal static void bind_text (Sqlite.Statement statement, string parameter, string text) throws Error { var position = statement.bind_parameter_index (parameter); if (position <= 0) diff --git a/src/dummy/dummy-cooperative.vala b/src/dummy/dummy-cooperative.vala index a5aff939ba78ea784a22b9765e0706b0063bb8f5..b0e4b7d7923307b56700754b740a5bd4b5c0d875 100644 --- a/src/dummy/dummy-cooperative.vala +++ b/src/dummy/dummy-cooperative.vala @@ -1,6 +1,8 @@ // This file is part of GNOME Games. License: GPL-3.0+. public class Games.DummyCooperative : Object, Cooperative { + public bool has_loaded { get; protected set; } + public bool get_cooperative () { return false; } diff --git a/src/dummy/dummy-description.vala b/src/dummy/dummy-description.vala index 53a406502d8497f7957e8ef256d41f36449b642e..07571457d2f2fde4c51729ab8c404956a27ad28f 100644 --- a/src/dummy/dummy-description.vala +++ b/src/dummy/dummy-description.vala @@ -1,6 +1,8 @@ // This file is part of GNOME Games. License: GPL-3.0+. public class Games.DummyDescription : Object, Description { + public bool has_loaded { get; protected set; } + public string get_description () { return ""; } diff --git a/src/dummy/dummy-developer.vala b/src/dummy/dummy-developer.vala index e34628128f609f2a2a9dfb67e5f285cbf366bd71..84b5d759e7def0be95fd8508399969f13272a001 100644 --- a/src/dummy/dummy-developer.vala +++ b/src/dummy/dummy-developer.vala @@ -1,6 +1,8 @@ // This file is part of GNOME Games. License: GPL-3.0+. public class Games.DummyDeveloper : Object, Developer { + public bool has_loaded { get; protected set; } + public string get_developer () { return ""; } diff --git a/src/dummy/dummy-genre.vala b/src/dummy/dummy-genre.vala index b23b6c0f24cecbc49a8a47ea46f5f166e0b53141..97ba1bf4b7863abed1927a4ec128bc267ef3eb3c 100644 --- a/src/dummy/dummy-genre.vala +++ b/src/dummy/dummy-genre.vala @@ -4,6 +4,8 @@ public class Games.DummyGenre : Object, Genre { // This is needed because get_genre() can't transfer ownership of the list. private string[] genres; + public bool has_loaded { get; protected set; } + construct { genres = {}; } diff --git a/src/dummy/dummy-players.vala b/src/dummy/dummy-players.vala index 0f015d916bea56c7c30a39b35a19e00a58ac07ab..7acb1c7c4be9a6d4d36700cdda96d91565ce41da 100644 --- a/src/dummy/dummy-players.vala +++ b/src/dummy/dummy-players.vala @@ -1,6 +1,8 @@ // This file is part of GNOME Games. License: GPL-3.0+. public class Games.DummyPlayers : Object, Players { + public bool has_loaded { get; protected set; } + public string get_players () { return ""; } diff --git a/src/dummy/dummy-publisher.vala b/src/dummy/dummy-publisher.vala index 0ddb432a052103c165af1f5df893720b0413e57c..82e1dd1869c8b0e3c0d631b19502e9277f016cea 100644 --- a/src/dummy/dummy-publisher.vala +++ b/src/dummy/dummy-publisher.vala @@ -1,6 +1,8 @@ // This file is part of GNOME Games. License: GPL-3.0+. public class Games.DummyPublisher : Object, Publisher { + public bool has_loaded { get; protected set; } + public string get_publisher () { return ""; } diff --git a/src/dummy/dummy-rating.vala b/src/dummy/dummy-rating.vala index 216bd42c92a5489a1b6358edb9b20e598e63e895..9d53c77f33789e5d3e4ed9b59edb22d125c0a421 100644 --- a/src/dummy/dummy-rating.vala +++ b/src/dummy/dummy-rating.vala @@ -1,6 +1,8 @@ // This file is part of GNOME Games. License: GPL-3.0+. public class Games.DummyRating : Object, Rating { + public bool has_loaded { get; protected set; } + public float get_rating () { return 0; } diff --git a/src/dummy/dummy-release-date.vala b/src/dummy/dummy-release-date.vala index 2762e39b2d5fe9319e2c3658d46a28273bf2415e..7c9b742b46669bda4b2f0ff14b591e09588d75b1 100644 --- a/src/dummy/dummy-release-date.vala +++ b/src/dummy/dummy-release-date.vala @@ -1,6 +1,8 @@ // This file is part of GNOME Games. License: GPL-3.0+. public class Games.DummyReleaseDate : Object, ReleaseDate { + public bool has_loaded { get; protected set; } + public DateTime get_release_date () { return null; } diff --git a/src/generic/generic-cooperative.vala b/src/generic/generic-cooperative.vala index 8073a25e9067b834dec3091a9c1aa02706163924..a3e4a918eb224d6106595dfdd2056018576197ab 100644 --- a/src/generic/generic-cooperative.vala +++ b/src/generic/generic-cooperative.vala @@ -3,6 +3,12 @@ public class Games.GenericCooperative : Object, Cooperative { private bool cooperative; + public bool has_loaded { get; protected set; } + + construct { + has_loaded = true; + } + public GenericCooperative (bool cooperative) { this.cooperative = cooperative; } diff --git a/src/generic/generic-description.vala b/src/generic/generic-description.vala index fa08666f72138b990bb4ff49010ae87d720149c7..41ba950ceffdd64f27ac2b2ca8d8a0deee748d21 100644 --- a/src/generic/generic-description.vala +++ b/src/generic/generic-description.vala @@ -3,6 +3,12 @@ public class Games.GenericDescription : Object, Description { private string description; + public bool has_loaded { get; protected set; } + + construct { + has_loaded = true; + } + public GenericDescription (string description) { this.description = description; } diff --git a/src/generic/generic-developer.vala b/src/generic/generic-developer.vala index 3499c94035ca939a2b3e49f4860349aedb1b647d..cd791e3705f35379f5d3265be178510695635a8e 100644 --- a/src/generic/generic-developer.vala +++ b/src/generic/generic-developer.vala @@ -3,6 +3,12 @@ public class Games.GenericDeveloper : Object, Developer { private string developer; + public bool has_loaded { get; protected set; } + + construct { + has_loaded = true; + } + public GenericDeveloper (string developer) { this.developer = developer; } diff --git a/src/generic/generic-genre.vala b/src/generic/generic-genre.vala index 3ffd7b2c4adc911d58bb433057e1ea39f7f75fa0..d66fa0a6268b0273ac8f1722084ee6e533c69573 100644 --- a/src/generic/generic-genre.vala +++ b/src/generic/generic-genre.vala @@ -3,6 +3,12 @@ public class Games.GenericGenre : Object, Genre { private string[] genre; + public bool has_loaded { get; protected set; } + + construct { + has_loaded = true; + } + public GenericGenre (string[] genre) { this.genre = genre.copy (); } diff --git a/src/generic/generic-players.vala b/src/generic/generic-players.vala index 549a865d65f0803be9af9af1eda9d2eea40cb399..917db04cf451ed450b00f193395a4c02add7dbf9 100644 --- a/src/generic/generic-players.vala +++ b/src/generic/generic-players.vala @@ -3,6 +3,12 @@ public class Games.GenericPlayers : Object, Players { private string players; + public bool has_loaded { get; protected set; } + + construct { + has_loaded = true; + } + public GenericPlayers (string players) { this.players = players; } diff --git a/src/generic/generic-publisher.vala b/src/generic/generic-publisher.vala index bbebea9c8550e3b8684f9cc885f6fffd8c121872..0945d33ced98cdda79167d4fa5b30b418dd879ac 100644 --- a/src/generic/generic-publisher.vala +++ b/src/generic/generic-publisher.vala @@ -3,6 +3,12 @@ public class Games.GenericPublisher : Object, Publisher { private string publisher; + public bool has_loaded { get; protected set; } + + construct { + has_loaded = true; + } + public GenericPublisher (string publisher) { this.publisher = publisher; } diff --git a/src/generic/generic-rating.vala b/src/generic/generic-rating.vala index 315240c8fa507a3f43f871e87020edcae4e53b1d..62d8d0aa3d76544954e6e7cc61ad48ff07d57ce1 100644 --- a/src/generic/generic-rating.vala +++ b/src/generic/generic-rating.vala @@ -3,6 +3,12 @@ public class Games.GenericRating : Object, Rating { private float rating; + public bool has_loaded { get; protected set; } + + construct { + has_loaded = true; + } + public GenericRating (float rating) { this.rating = rating; } diff --git a/src/generic/generic-release-date.vala b/src/generic/generic-release-date.vala index ddf2e89c382009c9de9844efbb4cb5dcf8a07d54..81209198d346eb98122b853d4e3a75452802f36c 100644 --- a/src/generic/generic-release-date.vala +++ b/src/generic/generic-release-date.vala @@ -3,6 +3,12 @@ public class Games.GenericReleaseDate : Object, ReleaseDate { private DateTime release_date; + public bool has_loaded { get; protected set; } + + construct { + has_loaded = true; + } + public GenericReleaseDate (DateTime release_date) { this.release_date = release_date; } diff --git a/src/grilo/grilo-cooperative.vala b/src/grilo/grilo-cooperative.vala index 3cafcef0e3d7fc9ece3657de71225733a583f5cf..6439b1f3a89f18b198f31d38e24b76da8b5f04e0 100644 --- a/src/grilo/grilo-cooperative.vala +++ b/src/grilo/grilo-cooperative.vala @@ -4,7 +4,8 @@ public class Games.GriloCooperative : Object, Cooperative { private GriloMedia media; private bool cooperative; private bool resolving; - private bool resolved; + + public bool has_loaded { get; protected set; } public GriloCooperative (GriloMedia media) { this.media = media; @@ -13,11 +14,11 @@ public class Games.GriloCooperative : Object, Cooperative { } public bool get_cooperative () { - if (resolving || resolved) + if (resolving || has_loaded) return cooperative; resolving = true; - media.try_resolve_media (); + media.try_resolve_media_queued (); return cooperative; } @@ -36,8 +37,6 @@ public class Games.GriloCooperative : Object, Cooperative { cooperative = grl_media.get_boolean (metadata_key); - resolved = true; - - changed (); + has_loaded = true; } } diff --git a/src/grilo/grilo-cover.vala b/src/grilo/grilo-cover.vala index 5736237e1dddd04d8f4183ea8ccbeeaabcb4cea7..db53bc09a252ef274a283a7c7db240c877804894 100644 --- a/src/grilo/grilo-cover.vala +++ b/src/grilo/grilo-cover.vala @@ -35,7 +35,7 @@ public class Games.GriloCover : Object, Cover { resolving = true; - media.try_resolve_media (); + media.try_resolve_media_queued (); return icon; } diff --git a/src/grilo/grilo-description.vala b/src/grilo/grilo-description.vala index 7a9d824d9ad552ac371ce4364c361e3fc537639f..eb3bbf14a04fc54ab1c3163cd01460c9eed8f6a8 100644 --- a/src/grilo/grilo-description.vala +++ b/src/grilo/grilo-description.vala @@ -4,7 +4,8 @@ public class Games.GriloDescription : Object, Description { private GriloMedia media; private string description; private bool resolving; - private bool resolved; + + public bool has_loaded { get; protected set; } public GriloDescription (GriloMedia media) { this.media = media; @@ -13,11 +14,11 @@ public class Games.GriloDescription : Object, Description { } public string get_description () { - if (resolving || resolved) + if (resolving || has_loaded) return description; resolving = true; - media.try_resolve_media (); + media.try_resolve_media_queued (); return description; } @@ -33,8 +34,6 @@ public class Games.GriloDescription : Object, Description { description = grl_media.get_description (); - resolved = true; - - changed (); + has_loaded = true; } } diff --git a/src/grilo/grilo-developer.vala b/src/grilo/grilo-developer.vala index a679b99a17dfc52c7fec6d2e2b297e27bcb27d06..5e56fdab6e8c5709f1fbf8b6a9516b00376fb5c0 100644 --- a/src/grilo/grilo-developer.vala +++ b/src/grilo/grilo-developer.vala @@ -4,7 +4,8 @@ public class Games.GriloDeveloper : Object, Developer { private GriloMedia media; private string developer; private bool resolving; - private bool resolved; + + public bool has_loaded { get; protected set; } public GriloDeveloper (GriloMedia media) { this.media = media; @@ -13,11 +14,11 @@ public class Games.GriloDeveloper : Object, Developer { } public string get_developer () { - if (resolving || resolved) + if (resolving || has_loaded) return developer; resolving = true; - media.try_resolve_media (); + media.try_resolve_media_queued (); return developer; } @@ -36,8 +37,6 @@ public class Games.GriloDeveloper : Object, Developer { developer = grl_media.get_string (metadata_key); - resolved = true; - - changed (); + has_loaded = true; } } diff --git a/src/grilo/grilo-genre.vala b/src/grilo/grilo-genre.vala index b221dcb1af87f41320d506d4c100929a780a1ec9..28ecbb0bf221db3b05395ef8b2f1f33b2412007e 100644 --- a/src/grilo/grilo-genre.vala +++ b/src/grilo/grilo-genre.vala @@ -4,7 +4,8 @@ public class Games.GriloGenre : Object, Genre { private GriloMedia media; private string[] genre; private bool resolving; - private bool resolved; + + public bool has_loaded { get; protected set; } public GriloGenre (GriloMedia media) { this.media = media; @@ -13,11 +14,11 @@ public class Games.GriloGenre : Object, Genre { } public unowned string[] get_genre () { - if (resolving || resolved) + if (resolving || has_loaded) return genre; resolving = true; - media.try_resolve_media (); + media.try_resolve_media_queued (); return genre; } @@ -36,8 +37,6 @@ public class Games.GriloGenre : Object, Genre { for (uint index = 0; index < genre_count; index++) genre += grl_media.get_genre_nth (index); - resolved = true; - - changed (); + has_loaded = true; } } diff --git a/src/grilo/grilo-media-queue.vala b/src/grilo/grilo-media-queue.vala new file mode 100644 index 0000000000000000000000000000000000000000..5c9ec814c4f78b0e55ea89cef7127c3ce1795a30 --- /dev/null +++ b/src/grilo/grilo-media-queue.vala @@ -0,0 +1,36 @@ +// This file is part of GNOME Games. License: GPL-3.0+. + +public class Games.GriloMediaQueue : Object { + private Queue queue; + private GriloMedia current_media; + + private static Once instance; + + construct { + queue = new Queue (); + } + + private static GriloMediaQueue create_instance () { + return new GriloMediaQueue (); + } + + public static unowned GriloMediaQueue get_instance () { + return instance.once (create_instance); + } + + public void append (GriloMedia media) { + queue.push_tail (media); + + if (current_media == null) + load_next_media (); + } + + private void load_next_media () { + if (queue.is_empty ()) + return; + + current_media = queue.pop_head (); + current_media.resolved.connect (load_next_media); + current_media.try_resolve_media (); + } +} diff --git a/src/grilo/grilo-media.vala b/src/grilo/grilo-media.vala index 738cb710209621989747048c51c1d06e6f4118ae..9cec6da9b111bb0c9557d5cd0e387f8518b7652d 100644 --- a/src/grilo/grilo-media.vala +++ b/src/grilo/grilo-media.vala @@ -14,6 +14,8 @@ public class Games.GriloMedia : Object { private Grl.Media? media; + private bool queued; + public GriloMedia (Title title, string mime_type) { this.title = title; this.mime_type = mime_type; @@ -51,6 +53,14 @@ public class Games.GriloMedia : Object { } } + public void try_resolve_media_queued () { + if (queued) + return; + + GriloMediaQueue.get_instance ().append (this); + queued = true; + } + internal Grl.Media? get_media () { return media; } diff --git a/src/grilo/grilo-players.vala b/src/grilo/grilo-players.vala index 7ab4fddcc260c26a0c00d1f2e69f2628e8b4866f..94f3744d56b9a828ead6733372c15b1e2384206d 100644 --- a/src/grilo/grilo-players.vala +++ b/src/grilo/grilo-players.vala @@ -4,7 +4,8 @@ public class Games.GriloPlayers : Object, Players { private GriloMedia media; private string players; private bool resolving; - private bool resolved; + + public bool has_loaded { get; protected set; } public GriloPlayers (GriloMedia media) { this.media = media; @@ -13,11 +14,11 @@ public class Games.GriloPlayers : Object, Players { } public string get_players () { - if (resolving || resolved) + if (resolving || has_loaded) return players; resolving = true; - media.try_resolve_media (); + media.try_resolve_media_queued (); return players; } @@ -41,8 +42,6 @@ public class Games.GriloPlayers : Object, Players { else players = _("Multi-player"); - resolved = true; - - changed (); + has_loaded = true; } } diff --git a/src/grilo/grilo-publisher.vala b/src/grilo/grilo-publisher.vala index ee5c7efee2f55c519971f6f925cf441b403c3edd..3c842469a0a5ada61ea36d59fa920b46040e3c10 100644 --- a/src/grilo/grilo-publisher.vala +++ b/src/grilo/grilo-publisher.vala @@ -4,7 +4,8 @@ public class Games.GriloPublisher : Object, Publisher { private GriloMedia media; private string publisher; private bool resolving; - private bool resolved; + + public bool has_loaded { get; protected set; } public GriloPublisher (GriloMedia media) { this.media = media; @@ -13,11 +14,11 @@ public class Games.GriloPublisher : Object, Publisher { } public string get_publisher () { - if (resolving || resolved) + if (resolving || has_loaded) return publisher; resolving = true; - media.try_resolve_media (); + media.try_resolve_media_queued (); return publisher; } @@ -36,8 +37,6 @@ public class Games.GriloPublisher : Object, Publisher { publisher = grl_media.get_string (metadata_key); - resolved = true; - - changed (); + has_loaded = true; } } diff --git a/src/grilo/grilo-rating.vala b/src/grilo/grilo-rating.vala index 508d7dc12e3b304cf946a5708428eceed530f5bb..3d1adbfb84480f3730b32be74eb68e8c24b3b8b0 100644 --- a/src/grilo/grilo-rating.vala +++ b/src/grilo/grilo-rating.vala @@ -4,7 +4,8 @@ public class Games.GriloRating : Object, Rating { private GriloMedia media; private float rating; private bool resolving; - private bool resolved; + + public bool has_loaded { get; protected set; } public GriloRating (GriloMedia media) { this.media = media; @@ -13,11 +14,11 @@ public class Games.GriloRating : Object, Rating { } public float get_rating () { - if (resolving || resolved) + if (resolving || has_loaded) return rating; resolving = true; - media.try_resolve_media (); + media.try_resolve_media_queued (); return rating; } @@ -33,8 +34,6 @@ public class Games.GriloRating : Object, Rating { rating = grl_media.get_rating (); - resolved = true; - - changed (); + has_loaded = true; } } diff --git a/src/grilo/grilo-release-date.vala b/src/grilo/grilo-release-date.vala index d4febe9a2b996f15e5c789657a0f494286c7a93e..7e309b497c9b0d2694c3fb30885642ec6e9d4653 100644 --- a/src/grilo/grilo-release-date.vala +++ b/src/grilo/grilo-release-date.vala @@ -4,7 +4,8 @@ public class Games.GriloReleaseDate : Object, ReleaseDate { private GriloMedia media; private DateTime release_date; private bool resolving; - private bool resolved; + + public bool has_loaded { get; protected set; } public GriloReleaseDate (GriloMedia media) { this.media = media; @@ -13,11 +14,11 @@ public class Games.GriloReleaseDate : Object, ReleaseDate { } public DateTime get_release_date () { - if (resolving || resolved) + if (resolving || has_loaded) return release_date; resolving = true; - media.try_resolve_media (); + media.try_resolve_media_queued (); return release_date; } @@ -33,8 +34,6 @@ public class Games.GriloReleaseDate : Object, ReleaseDate { release_date = grl_media.get_publication_date (); - resolved = true; - - changed (); + has_loaded = true; } } diff --git a/src/meson.build b/src/meson.build index 9a8860519947fb5d4e3e72691424c179f2f2d99c..8e9882f0adff6a07f8fca0d4f4f877318799a7e0 100644 --- a/src/meson.build +++ b/src/meson.build @@ -46,10 +46,17 @@ vala_sources = [ 'core/uri-source.vala', 'database/database.vala', + 'database/database-cooperative.vala', + 'database/database-description.vala', 'database/database-developer.vala', 'database/database-error.vala', 'database/database-game.vala', - 'database/database-uid.vala', + 'database/database-genre.vala', + 'database/database-metadata.vala', + 'database/database-players.vala', + 'database/database-publisher.vala', + 'database/database-rating.vala', + 'database/database-release-date.vala', 'database/database-uri-iterator.vala', 'database/database-uri-source.vala', @@ -99,6 +106,7 @@ vala_sources = [ 'grilo/grilo-developer.vala', 'grilo/grilo-genre.vala', 'grilo/grilo-media.vala', + 'grilo/grilo-media-queue.vala', 'grilo/grilo-players.vala', 'grilo/grilo-publisher.vala', 'grilo/grilo-rating.vala', diff --git a/src/ui/collection-icon-view.vala b/src/ui/collection-icon-view.vala index 572a178477c1e87f817782722daba8410479e02a..098340c180e9b6036025c1f364be5452536ea321 100644 --- a/src/ui/collection-icon-view.vala +++ b/src/ui/collection-icon-view.vala @@ -10,7 +10,7 @@ private class Games.CollectionIconView : Gtk.Bin { if (value != null) filtering_terms = value.split (" "); - flow_box.invalidate_filter (); + invalidate_filter (); } } @@ -19,7 +19,7 @@ private class Games.CollectionIconView : Gtk.Bin { get { return _filtering_developer; } set { _filtering_developer = value; - flow_box.invalidate_filter (); + invalidate_filter (); } } @@ -28,7 +28,7 @@ private class Games.CollectionIconView : Gtk.Bin { get { return _filtering_platform; } set { _filtering_platform = value; - flow_box.invalidate_filter (); + invalidate_filter (); } } @@ -108,6 +108,10 @@ private class Games.CollectionIconView : Gtk.Bin { is_active = false; } + public void invalidate_filter () { + flow_box.invalidate_filter (); + } + public bool gamepad_button_press_event (Manette.Event event) { if (!get_mapped ()) return false; diff --git a/src/ui/developer-list-item.vala b/src/ui/developer-list-item.vala index 23871e8bd981726bb71c95a0e8eb24842782ba17..ebf066ad4eb59f4ec2967b8fd3ce239496473ae7 100644 --- a/src/ui/developer-list-item.vala +++ b/src/ui/developer-list-item.vala @@ -9,7 +9,6 @@ private class Games.DeveloperListItem: Gtk.ListBoxRow { set { _developer = value; update_label (); - value.changed.connect (update_label); } } diff --git a/src/ui/developers-view.vala b/src/ui/developers-view.vala index 0cce14779fb733e8eea2d9df21945daa67cd7640..8df6bb64e19b7eee35f2bd7e0a70c5b4f0ca193d 100644 --- a/src/ui/developers-view.vala +++ b/src/ui/developers-view.vala @@ -1,68 +1,66 @@ // This file is part of GNOME Games. License: GPL-3.0+. private class Games.DevelopersView : SidebarView { - // This is a List because Developer objects are mutable, - // and can't be stored in a GenericSet without breaking. - private List shown_developers; - private List all_developers; + private GenericSet shown_developers; + + private uint unknown_games; + private DeveloperListItem unknown_item; construct { - shown_developers = new List (); - all_developers = new List (); + shown_developers = new GenericSet (Developer.hash, Developer.equal); + unknown_games = 0; } protected override void game_added (Game game) { var developer = game.get_developer (); - all_developers.append (developer); - show_developer (developer); - developer.changed.connect (invalidate_developer); + if (developer.has_loaded && developer.get_developer () != "") + show_developer (developer); + else { + show_unknown (); + developer.notify["has-loaded"].connect (invalidate_developer); + } } - private bool show_developer (Developer developer) { - var not_shown = shown_developers.find_custom (developer, Developer.compare) == null; - if (not_shown) { - shown_developers.append (developer); + private void show_developer (Developer developer) { + var shown = shown_developers.contains (developer); + if (!shown) { + shown_developers.add (developer); list_box.add (new DeveloperListItem (developer)); var selected_row = list_box.get_selected_row (); if (selected_row != null) invalidate (selected_row); } - - return not_shown; } - private void hide_developer (Developer developer) { - Gtk.ListBoxRow? first_occurence = null; + private void show_unknown () { + unknown_games++; - foreach (var row in list_box.get_children ()) { - var list_item = row as DeveloperListItem; + if (unknown_item != null) + return; - if (Developer.equal (list_item.developer, developer)) { - if (first_occurence != null) { - if (row == list_box.get_selected_row ()) - list_box.select_row (first_occurence); + var developer = new DummyDeveloper (); + shown_developers.add (developer); - row.destroy (); + unknown_item = new DeveloperListItem (developer); - break; - } - else { - first_occurence = list_item; - first_occurence.changed (); - } - } - } + list_box.add (unknown_item); } - private void invalidate_developer (Developer developer) { - if (!show_developer (developer)) { - // If already shown, this developer's list item gets updated, - // hence try to show developers that are now not represented, - // and hide the developers that are now multiply represented. - all_developers.foreach ((item) => show_developer (item)); - hide_developer (developer); + private void invalidate_developer (Object object, ParamSpec param) { + var developer = object as Developer; + + if (developer.has_loaded) + show_developer (developer); + + unknown_games--; + collection_view.invalidate_filter (); + + if (unknown_games == 0) { + list_box.remove (unknown_item); + unknown_item = null; + select_default_row (); } }