[grits] Add thread safe grits_viewer_queue_draw function



commit ecb7a9abd329d604506ea1734d2db72760fcb4f4
Author: Andy Spencer <andy753421 gmail com>
Date:   Thu Dec 27 09:26:28 2012 +0000

    Add thread safe grits_viewer_queue_draw function
    
    This should be used by threads when they finish loading something. Any
    additional loading which must be done by the main thread will ideally be
    done during the next draw.

 src/grits-opengl.c         |    8 ++++----
 src/grits-viewer.c         |   33 ++++++++++++++++++++++++++++++++-
 src/grits-viewer.h         |    5 +++++
 src/objects/grits-object.c |    2 +-
 4 files changed, 42 insertions(+), 6 deletions(-)
---
diff --git a/src/grits-opengl.c b/src/grits-opengl.c
index 90e830b..0e803ba 100644
--- a/src/grits-opengl.c
+++ b/src/grits-opengl.c
@@ -290,7 +290,7 @@ static gboolean run_mouse_move(GritsOpenGL *opengl, GdkEventMotion *event)
 static gboolean on_motion_notify(GritsOpenGL *opengl, GdkEventMotion *event, gpointer _)
 {
 	opengl->mouse_queue = *event;
-	gtk_widget_queue_draw(GTK_WIDGET(opengl));
+	grits_viewer_queue_draw(GRITS_VIEWER(opengl));
 	return FALSE;
 }
 
@@ -402,18 +402,18 @@ static gboolean on_key_press(GritsOpenGL *opengl, GdkEventKey *event, gpointer _
 	/* Testing */
 	if (kv == GDK_w) {
 		opengl->wireframe = !opengl->wireframe;
-		gtk_widget_queue_draw(GTK_WIDGET(opengl));
+		grits_viewer_queue_draw(GRITS_VIEWER(opengl));
 	}
 	if (kv == GDK_p) {
 		opengl->pickmode = !opengl->pickmode;
-		gtk_widget_queue_draw(GTK_WIDGET(opengl));
+		grits_viewer_queue_draw(GRITS_VIEWER(opengl));
 	}
 #ifdef ROAM_DEBUG
 	else if (kv == GDK_n) roam_sphere_split_one(opengl->sphere);
 	else if (kv == GDK_p) roam_sphere_merge_one(opengl->sphere);
 	else if (kv == GDK_r) roam_sphere_split_merge(opengl->sphere);
 	else if (kv == GDK_u) roam_sphere_update_errors(opengl->sphere);
-	gtk_widget_queue_draw(GTK_WIDGET(opengl));
+	grits_viewer_queue_draw(GRITS_VIEWER(opengl));
 #endif
 	return FALSE;
 }
diff --git a/src/grits-viewer.c b/src/grits-viewer.c
index aa5c3a5..67d25fb 100644
--- a/src/grits-viewer.c
+++ b/src/grits-viewer.c
@@ -71,6 +71,14 @@ static void _grits_viewer_fix_rotation(GritsViewer *viewer)
 	while (viewer->rotation[2] >  180) viewer->rotation[2] -= 360;
 }
 
+static gboolean _grits_viewer_queue_draw_cb(gpointer _viewer)
+{
+	GritsViewer *viewer = _viewer;
+	gtk_widget_queue_draw(GTK_WIDGET(viewer));
+	viewer->draw_source = 0;
+	return FALSE;
+}
+
 /* Signal helpers */
 static void _grits_viewer_emit_location_changed(GritsViewer *viewer)
 {
@@ -187,7 +195,7 @@ static gboolean on_motion_notify(GritsViewer *viewer, GdkEventMotion *event, gpo
 static void on_view_changed(GritsViewer *viewer,
 		gdouble _1, gdouble _2, gdouble _3)
 {
-	gtk_widget_queue_draw(GTK_WIDGET(viewer));
+	grits_viewer_queue_draw(viewer);
 }
 
 /***********
@@ -424,6 +432,20 @@ gboolean grits_viewer_get_offline(GritsViewer *viewer)
 	return viewer->offline;
 }
 
+/**
+ * grits_viewer_queue_draw:
+ * @viewer: the viewer
+ *
+ * Causes the viewer to redraw the screen. This has the safe effect as
+ * gtk_widget_queue_draw, but is thread safe, and probably faster.
+ */
+void grits_viewer_queue_draw(GritsViewer *viewer)
+{
+	if (!viewer->draw_source)
+		viewer->draw_source = g_idle_add_full(G_PRIORITY_HIGH,
+				_grits_viewer_queue_draw_cb, viewer, NULL);
+}
+
 /***********************************
  * To be implemented by subclasses *
  ***********************************/
@@ -610,6 +632,14 @@ static void grits_viewer_init(GritsViewer *viewer)
 	g_signal_connect(viewer, "location-changed",     G_CALLBACK(on_view_changed),   NULL);
 	g_signal_connect(viewer, "rotation-changed",     G_CALLBACK(on_view_changed),   NULL);
 }
+static void grits_viewer_dispose(GObject *gobject)
+{
+	g_debug("GritsViewer: dispose");
+	GritsViewer *viewer = GRITS_VIEWER(gobject);
+	if (viewer->draw_source)
+		g_source_remove(viewer->draw_source);
+	G_OBJECT_CLASS(grits_viewer_parent_class)->dispose(gobject);
+}
 static void grits_viewer_finalize(GObject *gobject)
 {
 	g_debug("GritsViewer: finalize");
@@ -620,6 +650,7 @@ static void grits_viewer_class_init(GritsViewerClass *klass)
 {
 	g_debug("GritsViewer: class_init");
 	GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+	gobject_class->dispose      = grits_viewer_dispose;
 	gobject_class->finalize     = grits_viewer_finalize;
 
 	/**
diff --git a/src/grits-viewer.h b/src/grits-viewer.h
index 4b04e3f..fa9fc07 100644
--- a/src/grits-viewer.h
+++ b/src/grits-viewer.h
@@ -119,6 +119,9 @@ struct _GritsViewer {
 	/* For dragging */
 	gint    drag_mode;
 	gdouble drag_x, drag_y;
+
+	/* For queue_draw */
+	guint   draw_source;
 };
 
 struct _GritsViewerClass {
@@ -187,4 +190,6 @@ void grits_viewer_add(GritsViewer *viewer, GritsObject *object,
 		gint level, gboolean sort);
 void grits_viewer_remove(GritsViewer *viewer, GritsObject *object);
 
+void grits_viewer_queue_draw(GritsViewer *viewer);
+
 #endif
diff --git a/src/objects/grits-object.c b/src/objects/grits-object.c
index 4674e8a..2eb6b5c 100644
--- a/src/objects/grits-object.c
+++ b/src/objects/grits-object.c
@@ -163,7 +163,7 @@ void grits_object_hide(GritsObject *object, gboolean hidden)
 void grits_object_queue_draw(GritsObject *object)
 {
 	if (object->viewer)
-		gtk_widget_queue_draw(GTK_WIDGET(object->viewer));
+		grits_viewer_queue_draw(object->viewer);
 }
 
 void grits_object_set_cursor(GritsObject *object, GdkCursorType cursor)



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