changeset 791:6d65167764ea

realtime file monitor
author nadvornik
date Fri, 06 Jun 2008 21:50:09 +0000
parents 436674261840
children 99ea3d973ad3
files src/filedata.c src/filedata.h src/layout.c src/typedefs.h src/view_file_icon.c src/view_file_list.c
diffstat 6 files changed, 125 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/filedata.c	Fri Jun 06 20:59:03 2008 +0000
+++ b/src/filedata.c	Fri Jun 06 21:50:09 2008 +0000
@@ -1443,17 +1443,28 @@
 struct _NotifyData {
 	FileDataNotifyFunc func;
 	gpointer data;
+	NotifyPriority priority;
 	};
 
 static GList *notify_func_list = NULL;
 
-gint file_data_register_notify_func(FileDataNotifyFunc func, gpointer data)
+static gint file_data_notify_sort(gconstpointer a, gconstpointer b)
+{
+	NotifyData *nda = (NotifyData *)a;
+	NotifyData *ndb = (NotifyData *)b;
+	if (nda->priority < ndb->priority) return -1;
+	if (nda->priority > ndb->priority) return 1;
+	return 0;
+}
+
+gint file_data_register_notify_func(FileDataNotifyFunc func, gpointer data, NotifyPriority priority)
 {
 	NotifyData *nd = g_new(NotifyData, 1);
 	nd->func = func;
 	nd->data = data;
-	notify_func_list = g_list_prepend(notify_func_list, nd);
-	DEBUG_1("Notify func registered: %p\n", nd);
+	nd->priority = priority;
+	notify_func_list = g_list_insert_sorted(notify_func_list, nd, file_data_notify_sort);
+	DEBUG_1("Notify func registered: %p", nd);
 	return TRUE;
 }
 
@@ -1468,7 +1479,7 @@
 			{
 			notify_func_list = g_list_delete_link(notify_func_list, work);
 			g_free(nd);
-			DEBUG_1("Notify func unregistered: %p\n", nd);
+			DEBUG_1("Notify func unregistered: %p", nd);
 			return TRUE;
 			}
 		work = work->next;
@@ -1483,7 +1494,7 @@
 	while(work)
 		{
 		NotifyData *nd = (NotifyData *)work->data;
-		DEBUG_1("Notify func calling: %p %s\n", nd, fd->path);
+		DEBUG_1("Notify func calling: %p %s", nd, fd->path);
 		nd->func(fd, nd->data);
 		work = work->next;
 		}
@@ -1494,6 +1505,78 @@
 }
 
 
+static GHashTable *file_data_monitor_pool = NULL;
+static gint realtime_monitor_id = -1;
+
+static void realtime_monitor_check_cb(gpointer key, gpointer value, gpointer data)
+{
+	FileData *fd = key;
+	struct stat st;
+
+	stat_utf8(fd->path, &st);
+	
+	file_data_check_changed_files(fd, &st);
+	
+	DEBUG_1("monitor %s", fd->path);
+}
+
+static gboolean realtime_monitor_cb(gpointer data)
+{
+	g_hash_table_foreach(file_data_monitor_pool, realtime_monitor_check_cb, NULL);
+	return TRUE;
+}
+
+gint file_data_register_real_time_monitor(FileData *fd)
+{
+	gint count = 0;
+	
+	file_data_ref(fd);
+	
+	if (!file_data_monitor_pool)
+		file_data_monitor_pool = g_hash_table_new(g_direct_hash, g_direct_equal);
+	
+	count = GPOINTER_TO_INT(g_hash_table_lookup(file_data_monitor_pool, fd));
+
+	DEBUG_1("Register realtime %d %s", count, fd->path);
+	
+	count++;
+	g_hash_table_insert(file_data_monitor_pool, fd, GINT_TO_POINTER(count));
+	
+	if (realtime_monitor_id == -1)
+		{
+		realtime_monitor_id = g_timeout_add(5000, realtime_monitor_cb, NULL);
+		}
+	return TRUE;
+}
+
+gint file_data_unregister_real_time_monitor(FileData *fd)
+{
+	gint count;
+	g_assert(file_data_monitor_pool);
+	
+	count = GPOINTER_TO_INT(g_hash_table_lookup(file_data_monitor_pool, fd));
+	
+	DEBUG_1("Unregister realtime %d %s", count, fd->path);
+	
+	g_assert(count > 0);
+	
+	count--;
+	
+	if (count == 0)
+		g_hash_table_remove(file_data_monitor_pool, fd);
+	else
+		g_hash_table_insert(file_data_monitor_pool, fd, GINT_TO_POINTER(count));
+
+	file_data_unref(fd);
+	
+	if (g_hash_table_size(file_data_monitor_pool) == 0)
+		{
+		g_source_remove(realtime_monitor_id);
+		realtime_monitor_id = -1;
+		return FALSE;
+		}
+	return TRUE;
+}
 
 
 
--- a/src/filedata.h	Fri Jun 06 20:59:03 2008 +0000
+++ b/src/filedata.h	Fri Jun 06 21:50:09 2008 +0000
@@ -78,7 +78,11 @@
 void file_data_sc_free_ci_list(GList *fd_list);
 
 typedef void (*FileDataNotifyFunc)(FileData *fd, gpointer data);
-gint file_data_register_notify_func(FileDataNotifyFunc func, gpointer data);
+gint file_data_register_notify_func(FileDataNotifyFunc func, gpointer data, NotifyPriority priority);
 gint file_data_unregister_notify_func(FileDataNotifyFunc func, gpointer data);
 void file_data_send_notification(FileData *fd);
+
+gint file_data_register_real_time_monitor(FileData *fd);
+gint file_data_unregister_real_time_monitor(FileData *fd);
+
 #endif
--- a/src/layout.c	Fri Jun 06 20:59:03 2008 +0000
+++ b/src/layout.c	Fri Jun 06 21:50:09 2008 +0000
@@ -937,8 +937,13 @@
 
 	if (isdir(fd->path))
 		{
-		file_data_unref(lw->dir_fd);
+		if (lw->dir_fd)
+			{
+			file_data_unregister_real_time_monitor(lw->dir_fd);
+			file_data_unref(lw->dir_fd);
+			}
 		lw->dir_fd = file_data_ref(fd);
+		file_data_register_real_time_monitor(fd);
 		}
 	else
 		{
@@ -951,8 +956,13 @@
 			}
 		else if (isdir(base))
 			{
-			file_data_unref(lw->dir_fd);
+			if (lw->dir_fd)
+				{
+				file_data_unregister_real_time_monitor(lw->dir_fd);
+				file_data_unref(lw->dir_fd);
+				}
 			lw->dir_fd = file_data_new_simple(base);
+			file_data_register_real_time_monitor(lw->dir_fd);
 			g_free(base);
 			}
 		else
@@ -1608,6 +1618,7 @@
 	layout_image_full_screen_stop(lw);
 
 	dir_fd = lw->dir_fd;
+	file_data_unregister_real_time_monitor(lw->dir_fd);
 	lw->dir_fd = NULL;
 	lw->image = NULL;
 	lw->utility_box = NULL;
@@ -1826,16 +1837,16 @@
 
 	layout_window_list = g_list_remove(layout_window_list, lw);
 
-	if (lw->last_time_id != -1)
-		{
-		g_source_remove(lw->last_time_id);
-		}
-
+	
 	layout_bars_close(lw);
 
 	gtk_widget_destroy(lw->window);
 
-	file_data_unref(lw->dir_fd);
+	if (lw->dir_fd) 
+		{
+		file_data_unregister_real_time_monitor(lw->dir_fd);
+		file_data_unref(lw->dir_fd);
+		}
 
 	g_free(lw);
 }
@@ -1979,7 +1990,7 @@
 
 	/* set up the time stat timeout */
 	lw->last_version = 0;
-	lw->last_time_id = g_timeout_add(5000, layout_check_for_update_cb, lw);
+//	lw->last_time_id = g_timeout_add(5000, layout_check_for_update_cb, lw);
 
 	if (geometry)
 		{
--- a/src/typedefs.h	Fri Jun 06 20:59:03 2008 +0000
+++ b/src/typedefs.h	Fri Jun 06 21:50:09 2008 +0000
@@ -131,6 +131,13 @@
 	SS_ERR_OTHER,
 } SecureSaveErrno;
 
+typedef enum {
+	NOTIFY_PRIORITY_HIGH = 0,
+	NOTIFY_PRIORITY_MEDIUM,
+	NOTIFY_PRIORITY_LOW
+} NotifyPriority;
+	
+
 
 #define MAX_SPLIT_IMAGES 4
 
@@ -539,7 +546,6 @@
 
 	/* directory update check */
 
-	gint last_time_id;
 	gint last_version;
 
 	/* misc */
--- a/src/view_file_icon.c	Fri Jun 06 20:59:03 2008 +0000
+++ b/src/view_file_icon.c	Fri Jun 06 21:50:09 2008 +0000
@@ -2301,7 +2301,7 @@
 	/* force VFICON_INFO(vf, columns) to be at least 1 (sane) - this will be corrected in the size_cb */
 	vficon_populate_at_new_size(vf, 1, 1, FALSE);
 
-	file_data_register_notify_func(vficon_notify_cb, vf);
+	file_data_register_notify_func(vficon_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM);
 
 	return vf;
 }
--- a/src/view_file_list.c	Fri Jun 06 20:59:03 2008 +0000
+++ b/src/view_file_list.c	Fri Jun 06 21:50:09 2008 +0000
@@ -1463,7 +1463,7 @@
 		
 		file_data_unregister_notify_func(vflist_notify_cb, vf); /* we don't need the notification */
 		file_data_increment_version(fd);
-		file_data_register_notify_func(vflist_notify_cb, vf);
+		file_data_register_notify_func(vflist_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM);
 
 		gtk_tree_store_set(GTK_TREE_STORE(store), &iter, FILE_COLUMN_MARKS + n, fd->marks[n], -1);
 
@@ -1570,7 +1570,7 @@
 
 		ret = filelist_read(vf->dir_fd, &vf->list, NULL);
 
-		file_data_register_notify_func(vflist_notify_cb, vf);
+		file_data_register_notify_func(vflist_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM);
 
 		DEBUG_1("%s vflist_refresh: sort", get_exec_time());
 		vf->list = filelist_sort(vf->list, vf->sort_method, vf->sort_ascend);
@@ -1711,7 +1711,7 @@
 	fd->marks[col_idx - FILE_COLUMN_MARKS] = mark;
 	file_data_unregister_notify_func(vflist_notify_cb, vf); /* we don't need the notification */
 	file_data_increment_version(fd);
-	file_data_register_notify_func(vflist_notify_cb, vf);
+	file_data_register_notify_func(vflist_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM);
 
 	gtk_tree_store_set(store, &iter, col_idx, mark, -1);
 	gtk_tree_path_free(path);
@@ -1832,7 +1832,7 @@
 	vflist_listview_add_column(vf, FILE_COLUMN_SIZE, _("Size"), FALSE, TRUE, FALSE);
 	vflist_listview_add_column(vf, FILE_COLUMN_DATE, _("Date"), FALSE, TRUE, FALSE);
 
-	file_data_register_notify_func(vflist_notify_cb, vf);
+	file_data_register_notify_func(vflist_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM);
 	return vf;
 }