[gnome-games/wip/theawless/async-cover] ui: Use async calls for fetching and showing cover



commit 2a55bddb31347af212adf2f9b2ba79dd5ad38a04
Author: theawless <theawless gmail com>
Date:   Wed Oct 3 00:18:12 2018 +0530

    ui: Use async calls for fetching and showing cover

 plugins/steam/src/steam-cover.vala | 28 ++++++++++----------
 src/core/cover.vala                |  4 +--
 src/dummy/dummy-cover.vala         |  2 +-
 src/grilo/grilo-cover.vala         | 52 ++++++++++++++------------------------
 src/grilo/grilo-media.vala         | 13 ++++++++++
 src/ui/game-thumbnail.vala         | 40 +++++++++++++----------------
 src/utils/composite-cover.vala     | 10 ++------
 src/utils/local-cover.vala         | 51 ++++++++++++++++---------------------
 8 files changed, 89 insertions(+), 111 deletions(-)
---
diff --git a/plugins/steam/src/steam-cover.vala b/plugins/steam/src/steam-cover.vala
index 517db2a8..33dca246 100644
--- a/plugins/steam/src/steam-cover.vala
+++ b/plugins/steam/src/steam-cover.vala
@@ -3,30 +3,28 @@
 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;
-
                load_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);
-
-               return null;
+               try {
+                       yield fetch_cover (uri);
+                       load_cover ();
+               }
+               catch (Error e) {
+                       warning (e.message);
+               }
+
+               return icon;
        }
 
        private string get_cover_path () {
@@ -57,7 +55,9 @@ public class Games.SteamCover : Object, Cover {
                        } catch (Error e) {
                                warning (e.message);
                        }
+                       GLib.Idle.add (fetch_cover.callback);
                });
+               yield;
        }
 
        private void load_cover () {
@@ -68,7 +68,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..f8f196cb 100644
--- a/src/grilo/grilo-cover.vala
+++ b/src/grilo/grilo-cover.vala
@@ -4,53 +4,50 @@ 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;
-
                try {
                        load_cover ();
                }
                catch (Error e) {
                        warning (e.message);
-
-                       return icon;
                }
 
                if (icon != null)
                        return icon;
-
-               resolving = true;
-
-               media.try_resolve_media ();
+               yield media.resolve_media_async ();
+               var uri = get_cover_uri ();
+               if (uri == null)
+                       return icon;
+               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 +61,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 +83,9 @@ public class Games.GriloCover : Object, Cover {
                        } catch (Error e) {
                                warning (e.message);
                        }
+                       GLib.Idle.add (fetch_cover.callback);
                });
+               yield;
        }
 
        private void load_cover () throws Error {
@@ -108,7 +96,5 @@ public class Games.GriloCover : Object, Cover {
 
                var file = File.new_for_path (cover_path);
                icon = new FileIcon (file);
-
-               changed ();
        }
 }
diff --git a/src/grilo/grilo-media.vala b/src/grilo/grilo-media.vala
index 738cb710..1382163d 100644
--- a/src/grilo/grilo-media.vala
+++ b/src/grilo/grilo-media.vala
@@ -11,6 +11,7 @@ public class Games.GriloMedia : Object {
        private Title title;
        private string mime_type;
        private bool resolving;
+       SourceFunc? resolve_callback;
 
        private Grl.Media? media;
 
@@ -51,6 +52,16 @@ public class Games.GriloMedia : Object {
                }
        }
 
+       public async void resolve_media_async () {
+               if (media != null || resolve_callback != null)
+                       return;
+
+               try_resolve_media ();
+               resolve_callback = resolve_media_async.callback;
+
+               yield;
+       }
+
        internal Grl.Media? get_media () {
                return media;
        }
@@ -87,5 +98,7 @@ public class Games.GriloMedia : Object {
        private void on_media_resolved (Grl.Source source, uint operation_id, owned Grl.Media media, 
GLib.Error? error) {
                this.media = media;
                resolved ();
+               if (resolve_callback != null)
+                       GLib.Idle.add (resolve_callback);
        }
 }
diff --git a/src/ui/game-thumbnail.vala b/src/ui/game-thumbnail.vala
index c5b32862..c815fd0e 100644
--- a/src/ui/game-thumbnail.vala
+++ b/src/ui/game-thumbnail.vala
@@ -46,11 +46,10 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
 
                        _cover = value;
 
-                       if (_cover != null)
-                               cover_changed_id = _cover.changed.connect (invalidate_cover);
-
-                       invalidate_cover ();
-               }
+                       cover_cache = null;
+                       tried_loading_cover = false;
+                       queue_draw ();
+                       }
        }
 
        private bool tried_loading_cover;
@@ -100,7 +99,7 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                        cover_cache = null;
                }
 
-               load_cache (context);
+               load_cache.begin (context);
 
                draw_border (context);
                if (cover_cache != null)
@@ -115,15 +114,18 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                return true;
        }
 
-       private void load_cache (DrawingContext context) {
+       private async void load_cache (DrawingContext context) {
+               if (emblem_cache == null) {
+                       load_emblem_cache (context);
+               }
                if (cover_cache == null && icon_cache == null) {
-                       load_cover_cache (context);
+                       yield load_cover_cache (context);
+                       queue_draw ();
                }
                if (cover_cache == null && icon_cache == null) {
-                       load_icon_cache (context);
+                       yield load_icon_cache (context);
+                       queue_draw ();
                }
-               if (emblem_cache == null)
-                       load_emblem_cache (context);
        }
 
        private void load_emblem_cache (DrawingContext context) {
@@ -144,7 +146,7 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                }
        }
 
-       private void load_icon_cache (DrawingContext context) {
+       private async void load_icon_cache (DrawingContext context) {
                if (icon == null)
                        return;
                var g_icon = icon.get_icon ();
@@ -161,14 +163,14 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                        return;
                }
                try {
-                       icon_cache = icon_info.load_icon ();
+                       icon_cache = yield icon_info.load_icon_async ();
                }
                catch (Error e) {
                        warning (@"Couldn’t load the icon: $(e.message)");
                }
        }
 
-       private void load_cover_cache (DrawingContext context) {
+       private async void load_cover_cache (DrawingContext context) {
                var size = int.min (context.width, context.height);
 
                load_cover_cache_from_disk (context, size);
@@ -177,7 +179,7 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
 
                if (cover == null)
                        return;
-               var g_icon = cover.get_cover ();
+               var g_icon = yield cover.get_cover ();
                if (g_icon == null)
                        return;
 
@@ -190,7 +192,7 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                        return;
                }
                try {
-                       cover_cache = icon_info.load_icon ();
+                       cover_cache = yield icon_info.load_icon_async ();
                        save_cover_cache_to_disk (size);
                }
                catch (Error e) {
@@ -249,12 +251,6 @@ private class Games.GameThumbnail: Gtk.DrawingArea {
                return @"$dir/$uid.png";
        }
 
-       private void invalidate_cover () {
-               cover_cache = null;
-               tried_loading_cover = false;
-               queue_draw ();
-       }
-
        private void draw_pixbuf (DrawingContext context, Gdk.Pixbuf pixbuf) {
                var surface = Gdk.cairo_surface_create_from_pixbuf (pixbuf, 1, context.window);
 
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..59a51c0a 100644
--- a/src/utils/local-cover.vala
+++ b/src/utils/local-cover.vala
@@ -2,51 +2,36 @@
 
 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 +44,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 +65,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 +74,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 +92,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]