[nautilus/wip/ernestask/attributes: 28/29] attr



commit 327def41e24fba3821a4b7665126c6dfa2503268
Author: Ernestas Kulik <ernestask gnome org>
Date:   Tue Aug 22 16:21:22 2017 +0300

    attr

 src-ng/nautilus-attribute.c |  170 +++++++++++++++++++++++++++++++------------
 src-ng/nautilus-attribute.h |   21 ++---
 src-ng/nautilus-directory.c |    4 +-
 src-ng/nautilus-file.c      |   48 ++++--------
 4 files changed, 149 insertions(+), 94 deletions(-)
---
diff --git a/src-ng/nautilus-attribute.c b/src-ng/nautilus-attribute.c
index 9f84f4c..70b7c6d 100644
--- a/src-ng/nautilus-attribute.c
+++ b/src-ng/nautilus-attribute.c
@@ -18,34 +18,41 @@
 
 #include "nautilus-attribute.h"
 
-typedef struct
+struct _NautilusAttribute
 {
+    GRecMutex mutex;
+
     gpointer value;
     NautilusAttributeState state;
 
+    NautilusTaskFunc update_func;
+    NautilusTask *update_task;
+
     NautilusCopyFunc copy_func;
     GDestroyNotify destroy_func;
 
-    GMutex mutex;
-} NautilusAttributePrivate;
+    GCancellable *cancellable;
+};
 
-G_DEFINE_TYPE_WITH_PRIVATE (NautilusAttribute, nautilus_attribute, G_TYPE_OBJECT)
+G_DEFINE_TYPE (NautilusAttribute, nautilus_attribute, G_TYPE_OBJECT)
 
 static void
 finalize (GObject *object)
 {
     NautilusAttribute *self;
-    NautilusAttributePrivate *priv;
 
     self = NAUTILUS_ATTRIBUTE (object);
-    priv = nautilus_attribute_get_instance_private (self);
 
-    if (priv->destroy_func != NULL && priv->value != NULL)
+    g_rec_mutex_clear (&self->mutex);
+
+    if (self->value != NULL)
     {
-        g_clear_pointer (&priv->value, priv->destroy_func);
+        g_clear_pointer (&self->value, self->destroy_func);
     }
 
-    g_mutex_clear (&priv->mutex);
+    g_cancellable_cancel (self->cancellable);
+
+    g_object_unref (self->cancellable);
 
     G_OBJECT_CLASS (nautilus_attribute_parent_class)->finalize (object);
 }
@@ -63,90 +70,159 @@ nautilus_attribute_class_init (NautilusAttributeClass *klass)
 static void
 nautilus_attribute_init (NautilusAttribute *self)
 {
-    NautilusAttributePrivate *priv;
+    g_rec_mutex_init (&self->mutex);
+
+    self->update_task = NULL;
+    self->cancellable = g_cancellable_new ();
+}
+
+typedef struct
+{
+    NautilusAttribute *attribute;
+
+    NautilusAttributeUpdateValueCallback callback;
+    gpointer user_data;
+} GetValueCallbackDetails;
+
+static void
+update_task_callback (NautilusTask *task,
+                      gpointer      user_data)
+{
+    GetValueCallbackDetails *details;
 
-    priv = nautilus_attribute_get_instance_private (self);
+    details = user_data;
 
-    g_mutex_init (&priv->mutex);
+    g_rec_mutex_lock (&attribute->mutex);
+
+    if (attribute->update_task == task)
+    {
+        if (attribute->state == NAUTILUS_ATTRIBUTE_STATE_PENDING)
+        {
+            attribute->state = NAUTILUS_ATTRIBUTE_STATE_VALID;
+        }
+
+        
+
+        details->callback (details->attribute, nautilus_task_get_result (task),
+                           details->user_data);
+    }
+
+    g_rec_mutex_lock (&attribute->mutex);
+
+    g_object_unref (details->attribute);
+    g_free (details);
 }
 
 void
 nautilus_attribute_get_value (NautilusAttribute                    *attribute,
-                              gboolean                              update,
                               NautilusAttributeUpdateValueCallback  callback,
                               gpointer                              user_data)
 {
-    NautilusAttributePrivate *priv;
     gpointer value;
 
     g_return_if_fail (NAUTILUS_IS_ATTRIBUTE (attribute));
 
-    if (callback == NULL)
-    {
-        return;
-    }
-
-    priv = nautilus_attribute_get_instance_private (attribute);
+    g_rec_mutex_lock (&attribute->mutex);
 
-    if (!update)
+    switch (attribute->state)
     {
-        if (priv->copy_func != NULL && priv->value != NULL)
+        case NAUTILUS_ATTRIBUTE_STATE_PENDING:
         {
-            value = priv->copy_func (priv->value);
+            GetValueCallbackDetails *details;
+
+            details = g_new0 (GetValueCallbackDetails, 1);
+
+            details->attribute = g_object_ref (attribute);
+            details->callback = callback;
+            details->user_data = user_data;
+
+            nautilus_task_add_callback (attribute->update_task, update_task_callback, details);
         }
-        else
+        break;
+
+        case NAUTILUS_ATTRIBUTE_STATE_VALID:
         {
-            value = priv->value;
+            callback (attribute, attribute->copy_func (attribute->value), user_data);
+        };
+        break;
+
+        case NAUTILUS_ATTRIBUTE_STATE_INVALID:
+        {
+            if (attribute->update_task != NULL)
+            {
+                g_object_unref (attribute->update_task);
+            }
+
+            attribute->update_task = nautilus_task_new_with_func (attribute->update_func,
+                                                                  g_object_ref (attribute),
+                                                                  g_object_unref,
+                                                                  attribute->cancellable);
+
+            nautilus_task_add_callback (
         }
+        break;
     }
+
+    g_rec_mutex_unlock (&attribute->mutex);
 }
 
 void
 nautilus_attribute_set_value (NautilusAttribute *attribute,
                               gpointer           value)
 {
-    NautilusAttributePrivate *priv;
-
     g_return_if_fail (NAUTILUS_IS_ATTRIBUTE (attribute));
 
-    priv = nautilus_attribute_get_instance_private (attribute);
-
-    g_mutex_lock (&priv->mutex);
+    g_rec_mutex_lock (&attribute->mutex);
 
-    if (priv->destroy_func != NULL && priv->value != NULL)
+    if (attribute->value != NULL)
     {
-        priv->destroy_func (priv->value);
+        attribute->destroy_func (attribute->value);
     }
 
-    if (priv->copy_func != NULL)
-    {
-        priv->value = priv->copy_func (value);
-    }
-    else
-    {
-        priv->value = value;
-    }
+    attribute->value = attribute->copy_func (value);
 
     /* If an update is pending,
      * the new value divined shall be discarded after the state check.
      */
-    priv->state = NAUTILUS_ATTRIBUTE_STATE_VALID;
+    attribute->state = NAUTILUS_ATTRIBUTE_STATE_VALID;
+
+    g_rec_mutex_unlock (&attribute->mutex);
+}
 
-    g_mutex_unlock (&priv->mutex);
+static gpointer
+dummy_copy_func (gpointer data)
+{
+    return data;
+}
+
+static void
+dummy_destroy_func (gpointer data)
+{
+    (void) data;
 }
 
 NautilusAttribute *
-nautilus_attribute_new (NautilusCopyFunc copy_func,
+nautilus_attribute_new (NautilusTaskFunc update_func,
+                        NautilusCopyFunc copy_func,
                         GDestroyNotify   destroy_func)
 {
     NautilusAttribute *instance;
-    NautilusAttributePrivate *priv;
+
+    g_return_val_if_fail (update_func != NULL, NULL);
 
     instance = g_object_new (NAUTILUS_TYPE_ATTRIBUTE, NULL);
-    priv = nautilus_attribute_get_instance_private (instance);
 
-    priv->copy_func = copy_func;
-    priv->destroy_func = destroy_func;
+    instance->update_func = update_func;
+    if (copy_func == NULL)
+    {
+        copy_func = dummy_copy_func;
+    }
+    instance->copy_func = copy_func;
+    if (destroy_func == NULL)
+    {
+        destroy_func = dummy_destroy_func;
+    }
+    instance->destroy_func = destroy_func;
 
     return instance;
 }
diff --git a/src-ng/nautilus-attribute.h b/src-ng/nautilus-attribute.h
index 49a6677..56c4687 100644
--- a/src-ng/nautilus-attribute.h
+++ b/src-ng/nautilus-attribute.h
@@ -19,11 +19,13 @@
 #ifndef NAUTILUS_ATTRIBUTE_H_INCLUDED
 #define NAUTILUS_ATTRIBUTE_H_INCLUDED
 
+#include "nautilus-task.h"
+
 #include <glib-object.h>
 
 #define NAUTILUS_TYPE_ATTRIBUTE (nautilus_attribute_get_type ())
 
-G_DECLARE_DERIVABLE_TYPE (NautilusAttribute, nautilus_attribute, NAUTILUS, ATTRIBUTE, GObject)
+G_DECLARE_FINAL_TYPE (NautilusAttribute, nautilus_attribute, NAUTILUS, ATTRIBUTE, GObject)
 
 /* GCopyFunc has too many parameters for our taste. */
 typedef gpointer (*NautilusCopyFunc) (gpointer data);
@@ -40,13 +42,6 @@ typedef enum
     NAUTILUS_ATTRIBUTE_STATE_VALID
 } NautilusAttributeState;
 
-struct _NautilusAttributeClass
-{
-    GObjectClass parent_class;
-
-    void (*update) (NautilusAttribute *attribute);
-};
-
 /**
  * nautilus_attribute_get_state:
  * @attribute: an initialized #NautilusAttribute
@@ -65,12 +60,10 @@ void                   nautilus_attribute_invalidate (NautilusAttribute *attribu
 /**
  * nautilus_attribute_get_value:
  * @attribute: an initialized #NautilusAttribute
- * @update: whether the value should be updated if invalid
- * @callback: the function to call with the value of @attribute
- * @user_data: additional data to pass to @callback
+ * @callback: (nullable): the function to call with the value of @attribute
+ * @user_data: (nullable): additional data to pass to @callback
  */
 void nautilus_attribute_get_value (NautilusAttribute                    *attribute,
-                                   gboolean                              update,
                                    NautilusAttributeUpdateValueCallback  callback,
                                    gpointer                              user_data);
 /**
@@ -83,12 +76,14 @@ void nautilus_attribute_set_value (NautilusAttribute *attribute,
 
 /**
  * nautilus_attribute_new:
+ * @update_func: the function to call to update invalid values
  * @copy_func: (nullable): the function to call when copying the value
  * @destroy_func: (nullable): the function to call when destroying the value
  *
  * Returns: a new #NautilusAttribute
  */
-NautilusAttribute *nautilus_attribute_new (NautilusCopyFunc copy_func,
+NautilusAttribute *nautilus_attribute_new (NautilusTaskFunc update_func,
+                                           NautilusCopyFunc copy_func,
                                            GDestroyNotify   destroy_func);
 
 #endif
diff --git a/src-ng/nautilus-directory.c b/src-ng/nautilus-directory.c
index a4c8c13..a02b67d 100644
--- a/src-ng/nautilus-directory.c
+++ b/src-ng/nautilus-directory.c
@@ -157,7 +157,7 @@ nautilus_directory_enumerate_children (NautilusDirectory                 *direct
 {
     NautilusDirectoryPrivate *priv;
     NautilusCacheState cache_state;
-    g_autoptr (GFile) location = NULL;
+    GFile *location;
     g_autoptr (NautilusTask) task = NULL;
 
     g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
@@ -183,7 +183,7 @@ nautilus_directory_enumerate_children (NautilusDirectory                 *direct
 
     location = nautilus_file_get_location (NAUTILUS_FILE (directory));
     task = nautilus_task_new_with_func (nautilus_enumerate_children_task_func, location,
-                                        cancellable);
+                                        g_object_unref, cancellable);
 
     nautilus_task_run (task);
 }
diff --git a/src-ng/nautilus-file.c b/src-ng/nautilus-file.c
index b543880..d9f3e37 100644
--- a/src-ng/nautilus-file.c
+++ b/src-ng/nautilus-file.c
@@ -18,24 +18,17 @@
 
 #include "nautilus-file.h"
 
-#include "nautilus-cache.h"
+#include "nautilus-attribute.h"
 #include "nautilus-directory.h"
 #include "nautilus-file-table.h"
 #include "nautilus-task.h"
 #include "nautilus-tasks.h"
 
-enum
-{
-    INFO,
-    N_ITEMS
-};
-
 typedef struct
 {
     GFile *location;
 
-    NautilusCache *cache;
-    gssize cache_items[N_ITEMS];
+    NautilusAttribute *attribute_info;
 } NautilusFilePrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (NautilusFile, nautilus_file, G_TYPE_OBJECT)
@@ -147,8 +140,7 @@ renamed (NautilusFile *file,
 
     g_assert (nautilus_file_table_insert (new_location, file));
 
-    nautilus_cache_item_invalidate (priv->cache, priv->cache_items[INFO],
-                                    FALSE);
+    nautilus_attribute_item_invalidate (priv->attribute_info);
 }
 
 static void
@@ -189,9 +181,9 @@ nautilus_file_init (NautilusFile *self)
 
     priv = nautilus_file_get_instance_private (self);
 
-    priv->cache = nautilus_cache_new ();
-    priv->cache_items[INFO] = nautilus_cache_install_item (priv->cache,
-                                                           g_object_unref);
+    priv->attribute_info = nautilus_attribute_new (nautilus_query_info_func,
+                                                   NAUTILUS_COPY_FUNC (g_file_info_dup),
+                                                   g_object_unref);
 }
 
 typedef struct
@@ -202,12 +194,9 @@ typedef struct
     gpointer callback_data;
 } QueryInfoDetails;
 
-/*static void
-on_query_info_finished (NautilusAttributeTask *task,
-                        GFile                 *file,
-                        GFileInfo             *info,
-                        GError                *error,
-                        gpointer               data)
+static void
+query_info_task_callback (NautilusTask *task,
+                          gpointer      user_data)
 {
     QueryInfoDetails *details;
     NautilusFilePrivate *priv;
@@ -218,20 +207,11 @@ on_query_info_finished (NautilusAttributeTask *task,
     cache_state = nautilus_cache_item_get_state (priv->cache,
                                                  priv->cache_items[INFO]);
 
-    if (cache_state == NAUTILUS_CACHE_INVALID)
-    {*/
-        /* TODO: restart */
-        /*return;
-    }
-
-    nautilus_cache_item_set_value (priv->cache, priv->cache_items[INFO],
-                                   info);
-
     details->callback (details->file, g_file_info_dup (info), error,
                        details->callback_data);
 
     g_free (details);
-}*/
+}
 
 void
 nautilus_file_query_info (NautilusFile             *file,
@@ -277,7 +257,8 @@ nautilus_file_query_info (NautilusFile             *file,
     nautilus_cache_item_set_pending (priv->cache, priv->cache_items[INFO]);
 
     location = nautilus_file_get_location (file);
-    task = nautilus_task_new_with_func (nautilus_query_info_func, location, cancellable);
+    task = nautilus_task_new_with_func (nautilus_query_info_func, location, g_object_unref,
+                                        cancellable);
 
     details = g_new0 (QueryInfoDetails, 1);
 
@@ -285,6 +266,8 @@ nautilus_file_query_info (NautilusFile             *file,
     details->callback = callback;
     details->callback_data = user_data;
 
+    nautilus_task_add_callback (task, query_info_task_callback, details);
+
     nautilus_task_run (task);
 }
 
@@ -301,7 +284,8 @@ nautilus_file_get_thumbnail (NautilusFile              *file,
 
     location = nautilus_file_get_location (file);
     task = nautilus_task_new_with_func (nautilus_thumbnail_task_func,
-                                        g_object_ref (location), cancellable);
+                                        g_object_ref (location), g_object_unref,
+                                        cancellable);
 
     nautilus_task_run (task);
 }


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