[gnome-games/wip/theawless/async-cover: 19/20] ui: Make cover fetching/loading async



commit 24ccba12f0a1475eda69080fd506ba30a64fc32f
Author: theawless <theawless gmail com>
Date:   Sat Oct 6 02:15:09 2018 +0530

    ui: Make cover fetching/loading async

 plugins/steam/src/steam-cover.vala | 19 ++++++---------
 src/core/cover.vala                |  4 +--
 src/dummy/dummy-cover.vala         |  2 +-
 src/grilo/grilo-cover.vala         | 50 +++++++++++++++-----------------------
 src/ui/game-thumbnail.vala         | 37 ++++++++++++++--------------
 src/utils/composite-cover.vala     | 10 ++------
 src/utils/local-cover.vala         | 50 +++++++++++++++++---------------------
 7 files changed, 72 insertions(+), 100 deletions(-)
---
diff --git a/plugins/steam/src/steam-cover.vala b/plugins/steam/src/steam-cover.vala
index 517db2a8..8ded03e9 100644
--- a/plugins/steam/src/steam-cover.vala
+++ b/plugins/steam/src/steam-cover.vala
@@ -3,17 +3,12 @@
 public class Games.SteamCover : Object, Cover {
        private string game_id;
        private GLib.Icon icon;
-       private bool resolving;
 
        public SteamCover (string game_id) {
                this.game_id = game_id;
-               resolving = false;
        }
 
-       public GLib.Icon? get_cover () {
-               if (resolving)
-                       return icon;
-
+       public async GLib.Icon? get_cover () {
                if (icon != null)
                        return icon;
 
@@ -21,12 +16,11 @@ public class Games.SteamCover : Object, Cover {
                if (icon != null)
                        return icon;
 
-               resolving = true;
-
                var uri = @"http://cdn.akamai.steamstatic.com/steam/apps/$game_id/header.jpg";;
-               fetch_cover.begin (uri);
+               yield fetch_cover (uri);
+               load_cover ();
 
-               return null;
+               return icon;
        }
 
        private string get_cover_path () {
@@ -57,7 +51,10 @@ public class Games.SteamCover : Object, Cover {
                        } catch (Error e) {
                                warning (e.message);
                        }
+                       Idle.add (fetch_cover.callback);
                });
+
+               yield;
        }
 
        private void load_cover () {
@@ -68,7 +65,5 @@ public class Games.SteamCover : Object, Cover {
 
                var file = File.new_for_path (cover_path);
                icon = new FileIcon (file);
-
-               changed ();
        }
 }
diff --git a/src/core/cover.vala b/src/core/cover.vala
index b2434b05..8a9f76ee 100644
--- a/src/core/cover.vala
+++ b/src/core/cover.vala
@@ -1,7 +1,5 @@
 // This file is part of GNOME Games. License: GPL-3.0+.
 
 public interface Games.Cover : Object {
-       public signal void changed ();
-
-       public abstract GLib.Icon? get_cover ();
+       public abstract async GLib.Icon? get_cover ();
 }
diff --git a/src/dummy/dummy-cover.vala b/src/dummy/dummy-cover.vala
index f8252b7f..563a70cb 100644
--- a/src/dummy/dummy-cover.vala
+++ b/src/dummy/dummy-cover.vala
@@ -1,7 +1,7 @@
 // This file is part of GNOME Games. License: GPL-3.0+.
 
 public class Games.DummyCover : Object, Cover {
-       public GLib.Icon? get_cover () {
+       public async GLib.Icon? get_cover () {
                return null;
        }
 }
diff --git a/src/grilo/grilo-cover.vala b/src/grilo/grilo-cover.vala
index 5736237e..668c1fa4 100644
--- a/src/grilo/grilo-cover.vala
+++ b/src/grilo/grilo-cover.vala
@@ -4,20 +4,14 @@ public class Games.GriloCover : Object, Cover {
        private GriloMedia media;
        private Uid uid;
        private GLib.Icon icon;
-       private bool resolving;
        private string cover_path;
 
        public GriloCover (GriloMedia media, Uid uid) {
                this.media = media;
                this.uid = uid;
-               media.resolved.connect (on_media_resolved);
-               resolving = false;
        }
 
-       public GLib.Icon? get_cover () {
-               if (resolving)
-                       return icon;
-
+       public async GLib.Icon? get_cover () {
                if (icon != null)
                        return icon;
 
@@ -26,31 +20,37 @@ public class Games.GriloCover : Object, Cover {
                }
                catch (Error e) {
                        warning (e.message);
-
-                       return icon;
                }
 
                if (icon != null)
                        return icon;
 
-               resolving = true;
+               yield media.resolve_media_async ();
+               var uri = get_cover_uri ();
+               if (uri == null)
+                       return icon;
 
-               media.try_resolve_media ();
+               try {
+                       yield fetch_cover (uri);
+                       load_cover ();
+               }
+               catch (Error e) {
+                       warning (e.message);
+               }
 
                return icon;
        }
 
-       private void on_media_resolved () {
+       private string? get_cover_uri () {
                var grl_media = media.get_media ();
 
                if (grl_media == null)
-                       return;
+                       return null;
 
                if (grl_media.length (Grl.MetadataKey.THUMBNAIL) == 0)
-                       return;
+                       return null;
 
-               var uri = grl_media.get_thumbnail_nth (0);
-               try_fetch_cover.begin (uri);
+               return grl_media.get_thumbnail_nth (0);
        }
 
        private string get_cover_path () throws Error {
@@ -64,18 +64,7 @@ public class Games.GriloCover : Object, Cover {
                return cover_path;
        }
 
-       private async void try_fetch_cover (string uri) {
-               try {
-                       yield fetch_cover (uri);
-               }
-               catch (Error e) {
-                       warning (e.message);
-
-                       return;
-               }
-       }
-
-       private async void fetch_cover (string uri) throws Error{
+       private async void fetch_cover (string uri) throws Error {
                var dir = Application.get_covers_dir ();
                Application.try_make_dir (dir);
 
@@ -97,7 +86,10 @@ public class Games.GriloCover : Object, Cover {
                        } catch (Error e) {
                                warning (e.message);
                        }
+                       Idle.add (fetch_cover.callback);
                });
+
+               yield;
        }
 
        private void load_cover () throws Error {
@@ -108,7 +100,5 @@ public class Games.GriloCover : Object, Cover {
 
                var file = File.new_for_path (cover_path);
                icon = new FileIcon (file);
-
-               changed ();
        }
 }
diff --git a/src/ui/game-thumbnail.vala b/src/ui/game-thumbnail.vala
index 9f384354..77ae4b3e 100644
--- a/src/ui/game-thumbnail.vala
+++ b/src/ui/game-thumbnail.vala
@@ -32,7 +32,6 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                }
        }
 
-       private ulong cover_changed_id;
        private Cover _cover;
        public Cover cover {
                get { return _cover; }
@@ -40,14 +39,8 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                        if (_cover == value)
                                return;
 
-                       if (_cover != null)
-                               _cover.disconnect (cover_changed_id);
-
                        _cover = value;
 
-                       if (_cover != null)
-                               cover_changed_id = _cover.changed.connect (invalidate_cover);
-
                        invalidate_cover ();
                }
        }
@@ -98,7 +91,7 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                        tried_loading_cover = false;
                }
 
-               load_cache (context.width, context.height);
+               load_cache.begin (context.width, context.height);
 
                draw_border (context);
                if (cover_cache != null)
@@ -113,11 +106,19 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                return true;
        }
 
-       private void load_cache (int width, int height) {
-               if (cover_cache == null && icon_cache == null)
-                       cover_cache = get_cover_cache (width, height);
-               if (cover_cache == null && icon_cache == null)
-                       icon_cache = get_icon_cache (width, height);
+       private async void load_cache (int width, int height) {
+               if (cover_cache == null && icon_cache == null) {
+                       var cache = yield get_cover_cache (width, height);
+                       if (width == cache_width && height == cache_height)
+                               cover_cache = cache;
+               }
+               if (cover_cache == null && icon_cache == null) {
+                       var cache = yield get_icon_cache (width, height);
+                       if (width == cache_width && height == cache_height)
+                               icon_cache = cache;
+               }
+
+               queue_draw ();
        }
 
        private Gdk.Pixbuf? get_emblem (DrawingContext context) {
@@ -139,7 +140,7 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                }
        }
 
-       private Gdk.Pixbuf? get_icon_cache (int width, int height) {
+       private async Gdk.Pixbuf? get_icon_cache (int width, int height) {
                if (icon == null)
                        return null;
 
@@ -157,7 +158,7 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                        return null;
                }
                try {
-                       return icon_info.load_icon ();
+                       return yield icon_info.load_icon_async ();
                }
                catch (Error e) {
                        warning (@"Couldn’t load the icon: $(e.message)");
@@ -165,7 +166,7 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                }
        }
 
-       private Gdk.Pixbuf? get_cover_cache (int width, int height) {
+       private async Gdk.Pixbuf? get_cover_cache (int width, int height) {
                var cover_cache = load_cover_cache_from_disk (width, height);
                if (cover_cache != null)
                        return cover_cache;
@@ -173,7 +174,7 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                if (cover == null)
                        return null;
 
-               var g_icon = cover.get_cover ();
+               var g_icon = yield cover.get_cover ();
                if (g_icon == null)
                        return null;
 
@@ -187,7 +188,7 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                        return null;
                }
                try {
-                       cover_cache = icon_info.load_icon ();
+                       cover_cache = yield icon_info.load_icon_async ();
                        save_cover_cache_to_disk (cover_cache, size);
                }
                catch (Error e) {
diff --git a/src/utils/composite-cover.vala b/src/utils/composite-cover.vala
index 3cca1c8a..07fba50f 100644
--- a/src/utils/composite-cover.vala
+++ b/src/utils/composite-cover.vala
@@ -5,21 +5,15 @@ public class Games.CompositeCover : Object, Cover {
 
        public CompositeCover (Cover[] covers) {
                this.covers = covers;
-               foreach (var cover in covers)
-                       cover.changed.connect (on_cover_changed);
        }
 
-       public GLib.Icon? get_cover () {
+       public async GLib.Icon? get_cover () {
                foreach (var cover in covers) {
-                       var result_cover = cover.get_cover ();
+                       var result_cover = yield cover.get_cover ();
                        if (result_cover != null)
                                return result_cover;
                }
 
                return null;
        }
-
-       private void on_cover_changed () {
-               changed ();
-       }
 }
diff --git a/src/utils/local-cover.vala b/src/utils/local-cover.vala
index 1190be58..f2ac42a4 100644
--- a/src/utils/local-cover.vala
+++ b/src/utils/local-cover.vala
@@ -2,51 +2,37 @@
 
 public class Games.LocalCover : Object, Cover {
        private Uri uri;
-       private bool resolved;
        private GLib.Icon? icon;
 
        public LocalCover (Uri uri) {
                this.uri = uri;
        }
 
-       public GLib.Icon? get_cover () {
-               if (resolved)
+       public async GLib.Icon? get_cover () {
+               if (icon != null)
                        return icon;
 
-               resolved = true;
-
-               string? cover_path;
                try {
-                       cover_path = get_cover_path ();
+                       var cover_path = yield get_cover_path ();
+                       if (cover_path != null)
+                               load_cover (cover_path);
                }
                catch (Error e) {
                        warning (e.message);
-
-                       return null;
                }
 
-               if (cover_path == null)
-                       return null;
-
-               var file = File.new_for_path (cover_path);
-               icon = new FileIcon (file);
-
                return icon;
        }
 
-       private string? get_cover_path () throws Error {
-               var cover_path = get_sibbling_cover_path ();
-               if (cover_path != null && FileUtils.test (cover_path, FileTest.EXISTS))
-                       return cover_path;
-
-               cover_path = get_directory_cover_path ();
-               if (cover_path != null && FileUtils.test (cover_path, FileTest.EXISTS))
-                       return cover_path;
+       private async string? get_cover_path () throws Error {
+               var cover_path = yield get_sibbling_cover_path ();
+               if (cover_path == null)
+                       cover_path = yield get_directory_cover_path ();
 
-               return null;
+               return cover_path;
        }
 
-       private string? get_sibbling_cover_path () throws Error {
+       private async string? get_sibbling_cover_path () throws Error {
                var file = uri.to_file ();
                var parent = file.get_parent ();
                if (parent == null)
@@ -59,7 +45,7 @@ public class Games.LocalCover : Object, Cover {
                string cover_path = null;
                var directory = new Directory (parent);
                var attributes = string.join (",", FileAttribute.STANDARD_NAME, 
FileAttribute.STANDARD_FAST_CONTENT_TYPE);
-               directory.foreach (attributes, (sibbling) => {
+               yield directory.foreach_async (attributes, (sibbling) => {
                        var sibbling_basename = sibbling.get_name ();
                        if (sibbling_basename == basename)
                                return false;
@@ -80,7 +66,7 @@ public class Games.LocalCover : Object, Cover {
                return cover_path;
        }
 
-       private string? get_directory_cover_path () throws Error {
+       private async string? get_directory_cover_path () throws Error {
                var file = uri.to_file ();
                var parent = file.get_parent ();
                if (parent == null)
@@ -89,7 +75,7 @@ public class Games.LocalCover : Object, Cover {
                string cover_path = null;
                var directory = new Directory (parent);
                var attributes = string.join (",", FileAttribute.STANDARD_NAME, 
FileAttribute.STANDARD_FAST_CONTENT_TYPE);
-               directory.foreach (attributes, (sibbling) => {
+               yield directory.foreach_async (attributes, (sibbling) => {
                        var sibbling_basename = sibbling.get_name ();
                        if (!sibbling_basename.has_prefix ("cover.") &&
                            !sibbling_basename.has_prefix ("folder."))
@@ -107,4 +93,12 @@ public class Games.LocalCover : Object, Cover {
 
                return cover_path;
        }
+
+       private void load_cover (string cover_path) {
+               if (!FileUtils.test (cover_path, FileTest.EXISTS))
+                       return;
+
+               var file = File.new_for_path (cover_path);
+               icon = new FileIcon (file);
+       }
 }


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