[yelp] yelp-docbook-document: Make auto-reload work for DocBook



commit e3830746e2d03d52a3ac5ceba96198c74eda1ec7
Author: Shaun McCance <shaunm gnome org>
Date:   Mon Nov 18 21:08:43 2013 -0500

    yelp-docbook-document: Make auto-reload work for DocBook

 libyelp/yelp-docbook-document.c |   81 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 81 insertions(+), 0 deletions(-)
---
diff --git a/libyelp/yelp-docbook-document.c b/libyelp/yelp-docbook-document.c
index cdddce8..8516ae8 100644
--- a/libyelp/yelp-docbook-document.c
+++ b/libyelp/yelp-docbook-document.c
@@ -68,6 +68,12 @@ static gboolean       docbook_request_page      (YelpDocument         *document,
 
 static void           docbook_process           (YelpDocbookDocument  *docbook);
 static void           docbook_disconnect        (YelpDocbookDocument  *docbook);
+static gboolean       docbook_reload            (YelpDocbookDocument  *docbook);
+static void           docbook_monitor_changed   (GFileMonitor         *monitor,
+                                                 GFile                *file,
+                                                 GFile                *other_file,
+                                                 GFileMonitorEvent     event_type,
+                                                 YelpDocbookDocument  *docbook);
 
 static void           docbook_walk              (YelpDocbookDocument  *docbook);
 static gboolean       docbook_walk_chunkQ       (YelpDocbookDocument  *docbook,
@@ -119,6 +125,9 @@ struct _YelpDocbookDocumentPrivate {
     gchar        *cur_page_id;
     gchar        *cur_prev_id;
     gchar        *root_id;
+
+    GFileMonitor **monitors;
+    gint64         reload_time;
 };
 
 /******************************************************************************/
@@ -164,6 +173,7 @@ yelp_docbook_document_init (YelpDocbookDocument *docbook)
 static void
 yelp_docbook_document_dispose (GObject *object)
 {
+    gint i;
     YelpDocbookDocumentPrivate *priv = GET_PRIV (object);
 
     if (priv->uri) {
@@ -171,6 +181,14 @@ yelp_docbook_document_dispose (GObject *object)
         priv->uri = NULL;
     }
 
+    if (priv->monitors != NULL) {
+        for (i = 0; priv->monitors[i]; i++) {
+            g_object_unref (priv->monitors[i]);
+        }
+        g_free (priv->monitors);
+        priv->monitors = NULL;
+    }
+
     G_OBJECT_CLASS (yelp_docbook_document_parent_class)->dispose (object);
 }
 
@@ -199,6 +217,8 @@ yelp_docbook_document_new (YelpUri *uri)
     YelpDocbookDocument *docbook;
     YelpDocbookDocumentPrivate *priv;
     gchar *doc_uri;
+    gchar **path;
+    gint path_i;
 
     g_return_val_if_fail (uri != NULL, NULL);
 
@@ -211,6 +231,21 @@ yelp_docbook_document_new (YelpUri *uri)
 
     priv->uri = g_object_ref (uri);
 
+    path = yelp_uri_get_search_path (uri);
+    priv->monitors = g_new0 (GFileMonitor*, g_strv_length (path) + 1);
+    for (path_i = 0; path[path_i]; path_i++) {
+        GFile *file;
+        file = g_file_new_for_path (path[path_i]);
+        priv->monitors[path_i] = g_file_monitor (file,
+                                                 G_FILE_MONITOR_SEND_MOVED,
+                                                 NULL, NULL);
+        g_signal_connect (priv->monitors[path_i], "changed",
+                          G_CALLBACK (docbook_monitor_changed),
+                          docbook);
+        g_object_unref (file);
+    }
+    g_strfreev (path);
+
     return (YelpDocument *) docbook;
 }
 
@@ -453,6 +488,52 @@ docbook_disconnect (YelpDocbookDocument *docbook)
     priv->transform_running = FALSE;
 }
 
+static gboolean
+docbook_reload (YelpDocbookDocument *docbook)
+{
+    YelpDocbookDocumentPrivate *priv = GET_PRIV (docbook);
+
+    if (priv->index_running || priv->process_running || priv->transform_running)
+        return TRUE;
+
+    g_mutex_lock (&priv->mutex);
+
+    priv->reload_time = g_get_monotonic_time();
+
+    yelp_document_clear_contents (YELP_DOCUMENT (docbook));
+
+    priv->state = DOCBOOK_STATE_PARSING;
+    priv->process_running = TRUE;
+    g_object_ref (docbook);
+    priv->thread = g_thread_new ("docbook-reload",
+                                 (GThreadFunc) docbook_process,
+                                 docbook);
+
+    g_mutex_unlock (&priv->mutex);
+
+    return FALSE;
+}
+
+static void
+docbook_monitor_changed   (GFileMonitor         *monitor,
+                           GFile                *file,
+                           GFile                *other_file,
+                           GFileMonitorEvent     event_type,
+                           YelpDocbookDocument  *docbook)
+{
+    YelpDocbookDocumentPrivate *priv = GET_PRIV (docbook);
+
+    if (g_get_monotonic_time() - priv->reload_time < 1000)
+        return;
+
+    if (priv->index_running || priv->process_running || priv->transform_running) {
+        g_timeout_add_seconds (1, (GSourceFunc) docbook_reload, docbook);
+        return;
+    }
+
+    docbook_reload (docbook);
+}
+
 /******************************************************************************/
 
 static void


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