[geary/mjog/composer-context-loading-fixes: 9/19] Application.AccountInterface: New interface for accessing account objects




commit 86082933678e15cf19f03ba797cb93b34db6d585
Author: Michael Gratton <mike vee net>
Date:   Mon Aug 10 18:10:32 2020 +1000

    Application.AccountInterface: New interface for accessing account objects
    
    By defining an interface for account object access, classes that use it
    are decoupled from Application.Controller, allowing them to be more
    easily unit tested.

 .../application/application-account-interface.vala | 63 ++++++++++++++++++++++
 src/client/application/application-controller.vala | 34 +++---------
 src/client/meson.build                             |  1 +
 3 files changed, 70 insertions(+), 28 deletions(-)
---
diff --git a/src/client/application/application-account-interface.vala 
b/src/client/application/application-account-interface.vala
new file mode 100644
index 000000000..6a7fb7046
--- /dev/null
+++ b/src/client/application/application-account-interface.vala
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2020 Michael Gratton <mike vee net>
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+
+/**
+ * Application interface for objects that manage accounts.
+ *
+ * This interface allows non-core application components to access the
+ * application's account context objects. Typically this is
+ * implemented by {@link Controller}.
+ *
+ * It also supports unit testing these components without having to
+ * load the complete application by providing mock instances of this
+ * interface instead of a fully initialised controller.
+ */
+internal interface Application.AccountInterface : GLib.Object {
+
+    /**
+     * Emitted when an account is added or is enabled.
+     *
+     * This will be emitted after an account is opened and added to
+     * the controller.
+     *
+     * The `is_startup` argument will be true if the application is in
+     * the middle of starting up, otherwise if the account was newly
+     * added when the application was already running then it will be
+     * false.
+     */
+    public signal void account_available(
+        AccountContext context,
+        bool is_startup
+    );
+
+    /**
+     * Emitted when an account is removed or is disabled.
+     *
+     * This will be emitted after the account is removed from the
+     * controller's collection of accounts, but before the {@link
+     * AccountContext.cancellable} is cancelled and before the account
+     * itself is closed.
+     *
+     * The `is_shutdown` argument will be true if the application is
+     * in the middle of quitting, otherwise if the account was simply
+     * removed but the application will keep running, then it will be
+     * false.
+     */
+    public signal void account_unavailable(
+        AccountContext context,
+        bool is_shutdown
+    );
+
+    /** Returns a context for an account, if any. */
+    internal abstract AccountContext? get_context_for_account(Geary.AccountInformation account);
+
+    /** Returns a read-only collection of contexts each active account. */
+    internal abstract Gee.Collection<AccountContext> get_account_contexts();
+
+
+}
diff --git a/src/client/application/application-controller.vala 
b/src/client/application/application-controller.vala
index 6ba759602..9d040b50d 100644
--- a/src/client/application/application-controller.vala
+++ b/src/client/application/application-controller.vala
@@ -13,7 +13,8 @@
  * A single instance of this class is constructed by {@link Client}
  * when the primary application instance is started.
  */
-internal class Application.Controller : Geary.BaseObject {
+internal class Application.Controller :
+    Geary.BaseObject, AccountInterface {
 
 
     private const uint MAX_AUTH_ATTEMPTS = 3;
@@ -78,6 +79,7 @@ internal class Application.Controller : Geary.BaseObject {
     // Primary collection of the application's open accounts
     private Gee.Map<Geary.AccountInformation,AccountContext> accounts =
         new Gee.HashMap<Geary.AccountInformation,AccountContext>();
+    private bool is_loading_accounts = true;
 
     // Cancelled if the controller is closed
     private GLib.Cancellable controller_open;
@@ -98,31 +100,6 @@ internal class Application.Controller : Geary.BaseObject {
     private GLib.Cancellable? storage_cleanup_cancellable;
 
 
-    /**
-     * Emitted when an account is added or is enabled.
-     *
-     * This will be emitted after an account is opened and added to
-     * the controller.
-     */
-    public signal void account_available(AccountContext context);
-
-    /**
-     * Emitted when an account is removed or is disabled.
-     *
-     * This will be emitted after the account is removed from the
-     * controller's collection of accounts, but before the {@link
-     * AccountContext.cancellable} is cancelled and before the account
-     * itself is closed.
-     *
-     * The `is_shutdown` argument will be true if the application is
-     * in the middle of quitting, otherwise if the account was simply
-     * removed but the application will keep running, then it will be
-     * false.
-     */
-    public signal void account_unavailable(AccountContext context,
-                                           bool is_shutdown);
-
-
     /**
      * Constructs a new instance of the controller.
      */
@@ -213,8 +190,9 @@ internal class Application.Controller : Geary.BaseObject {
 
         yield this.account_manager.connect_goa(cancellable);
 
-        // Start loading accounts
+        // Load accounts
         yield this.account_manager.load_accounts(cancellable);
+        this.is_loading_accounts = false;
 
         // Expunge any deleted accounts in the background, so we're
         // not blocking the app continuing to open.
@@ -1003,7 +981,7 @@ internal class Application.Controller : Geary.BaseObject {
         // Notify before opening so that listeners have a chance to
         // hook into it before signals start getting fired by folders
         // becoming available, etc.
-        account_available(context);
+        account_available(context, this.is_loading_accounts);
 
         bool retry = false;
         do {
diff --git a/src/client/meson.build b/src/client/meson.build
index 1c630d16f..033aaf14c 100644
--- a/src/client/meson.build
+++ b/src/client/meson.build
@@ -12,6 +12,7 @@ client_package = '@0@-@1@'.format(
 
 client_vala_sources = files(
   'application/application-account-context.vala',
+  'application/application-account-interface.vala',
   'application/application-attachment-manager.vala',
   'application/application-avatar-store.vala',
   'application/application-certificate-manager.vala',


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