[gnome-games/wip/exalm/covers: 4/5] game-thumbnail: Load covers in a separate thread
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games/wip/exalm/covers: 4/5] game-thumbnail: Load covers in a separate thread
- Date: Sun, 17 Nov 2019 11:59:56 +0000 (UTC)
commit 9721a98d7f521406186b59b3990fcfd31c473de7
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Sun Nov 17 16:39:49 2019 +0500
game-thumbnail: Load covers in a separate thread
Use CoverLoader to fetch covers. Throw away the result if the thumbnail
has been resized while it loaded.
src/ui/application.vala | 6 +++
src/ui/game-thumbnail.vala | 131 ++++++++++++---------------------------------
2 files changed, 39 insertions(+), 98 deletions(-)
---
diff --git a/src/ui/application.vala b/src/ui/application.vala
index e9106291..802d26b1 100644
--- a/src/ui/application.vala
+++ b/src/ui/application.vala
@@ -12,6 +12,7 @@ public class Games.Application : Gtk.Application {
private bool game_list_loaded;
private GameCollection game_collection;
+ private CoverLoader cover_loader;
private Manette.Monitor manette_monitor;
@@ -208,6 +209,7 @@ public class Games.Application : Gtk.Application {
init_game_sources ();
load_game_list.begin ();
+ cover_loader = new CoverLoader ();
ListStore list_store = new ListStore (typeof (Game));
game_collection.game_added.connect (game => list_store.append (game));
@@ -456,6 +458,10 @@ public class Games.Application : Gtk.Application {
return game_collection;
}
+ internal CoverLoader get_cover_loader () {
+ return cover_loader;
+ }
+
internal new static Application get_default () {
return GLib.Application.get_default () as Application;
}
diff --git a/src/ui/game-thumbnail.vala b/src/ui/game-thumbnail.vala
index 7df97cc8..04fab0ff 100644
--- a/src/ui/game-thumbnail.vala
+++ b/src/ui/game-thumbnail.vala
@@ -25,16 +25,19 @@ private class Games.GameThumbnail : Gtk.DrawingArea {
cover = game.get_cover ();
if (cover != null)
- cover_changed_id = cover.changed.connect (invalidate_cover);
+ cover_changed_id = cover.changed.connect (() => {
+ try_load_cover = true;
+ queue_draw ();
+ });
- invalidate_cover ();
+ queue_draw ();
}
}
- private bool tried_loading_cover;
- private Gdk.Pixbuf? cover_cache;
- private int previous_cover_width;
- private int previous_cover_height;
+ private Gdk.Pixbuf? cover_pixbuf;
+ private bool loading_cover;
+ private bool try_load_cover;
+ private int last_size;
public struct DrawingContext {
Cairo.Context cr;
@@ -44,6 +47,10 @@ private class Games.GameThumbnail : Gtk.DrawingArea {
int height;
}
+ construct {
+ try_load_cover = true;
+ }
+
static construct {
set_css_name ("gamesgamethumbnail");
}
@@ -177,107 +184,35 @@ private class Games.GameThumbnail : Gtk.DrawingArea {
}
private Gdk.Pixbuf? get_scaled_cover (DrawingContext context) {
- if (previous_cover_width != context.width * scale_factor) {
- previous_cover_width = context.width * scale_factor;
- cover_cache = null;
- tried_loading_cover = false;
- }
-
- if (previous_cover_height != context.height * scale_factor) {
- previous_cover_height = context.height * scale_factor;
- cover_cache = null;
- tried_loading_cover = false;
- }
-
- if (cover_cache != null)
- return cover_cache;
-
var size = int.min (context.width, context.height) * scale_factor;
- load_cover_cache_from_disk (context, size);
- if (cover_cache != null)
- return cover_cache;
-
- var g_icon = cover.get_cover ();
- if (g_icon == null)
- return null;
-
- var theme = Gtk.IconTheme.get_default ();
- var lookup_flags = Gtk.IconLookupFlags.FORCE_SIZE | Gtk.IconLookupFlags.FORCE_REGULAR;
- var icon_info = theme.lookup_by_gicon (g_icon, (int) size, lookup_flags);
-
- try {
- cover_cache = icon_info.load_icon ();
- save_cover_cache_to_disk (size);
- }
- catch (Error e) {
- warning (@"Couldn’t load the icon: $(e.message)\n");
+ if (size != last_size) {
+ cover_pixbuf = null;
+ try_load_cover = true;
}
- return cover_cache;
- }
+ if (!try_load_cover)
+ return cover_pixbuf;
- private void load_cover_cache_from_disk (DrawingContext context, int size) {
- if (tried_loading_cover)
- return;
+ var loader = Application.get_default ().get_cover_loader ();
- tried_loading_cover = true;
+ last_size = size;
- string cover_cache_path;
- try {
- cover_cache_path = get_cover_cache_path (size);
- }
- catch (Error e) {
- critical (e.message);
+ try_load_cover = false;
+ loading_cover = true;
+ loader.fetch_cover (game, size, (s, pixbuf) => {
+ if (s != last_size) {
+ cover_pixbuf = null;
+ try_load_cover = true;
+ } else
+ if (pixbuf != null)
+ cover_pixbuf = pixbuf;
- return;
- }
-
- try {
- cover_cache = new Gdk.Pixbuf.from_file_at_scale (cover_cache_path,
- context.width * scale_factor,
- context.height * scale_factor,
- true);
- }
- catch (Error e) {
- debug (e.message);
- }
- }
-
- private void save_cover_cache_to_disk (int size) {
- if (cover_cache == null)
- return;
-
- Application.try_make_dir (Application.get_covers_cache_dir (size));
- var now = new GLib.DateTime.now_local ();
- var creation_time = now.to_string ();
-
- try {
- var cover_cache_path = get_cover_cache_path (size);
- cover_cache.save (cover_cache_path, "png",
- "tEXt::Software", "GNOME Games",
- "tEXt::Creation Time", creation_time.to_string (),
- null);
- }
- catch (Error e) {
- critical (e.message);
- }
- }
-
- private string get_cover_cache_path (int size) throws Error {
- var dir = Application.get_covers_cache_dir (size);
-
- assert (uid != null);
-
- var uid = uid.get_uid ();
-
- return @"$dir/$uid.png";
- }
+ loading_cover = false;
+ queue_draw ();
+ });
- private void invalidate_cover () {
- cover_cache = null;
- tried_loading_cover = false;
- queue_draw ();
+ return cover_pixbuf;
}
private void draw_pixbuf (DrawingContext context, Gdk.Pixbuf pixbuf) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]