[f-spot: 22/40] send the events on the Gtk mainloop



commit a7ac549ad97c83025e11e37456f07751f98b65e2
Author: Stephane Delcroix <stephane delcroix org>
Date:   Mon Jun 22 11:07:33 2009 +0200

    send the events on the Gtk mainloop
    
    Aggregate the AreaUpdate events as, e.g., the jpeg pixbuf loader sends an event for every line, and triggers the events (prepared, updated, completed) from the Gtk mainloop to avoid redrawing from another thread

 src/ImageLoader.cs |   62 ++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 41 insertions(+), 21 deletions(-)
---
diff --git a/src/ImageLoader.cs b/src/ImageLoader.cs
index 6af9d7b..21cf957 100644
--- a/src/ImageLoader.cs
+++ b/src/ImageLoader.cs
@@ -9,11 +9,10 @@
 // This is free software. See COPYING for details
 //
 
-using Gtk;
 using System;
-using System.IO;
-using System.Runtime.Remoting.Messaging;
-using FSpot.Platform;
+
+using Gdk;
+
 using FSpot.Utils;
 
 namespace FSpot {
@@ -73,6 +72,7 @@ namespace FSpot {
 			get { return loading; }
 		}
 
+		bool notify_prepared = false;
 		bool prepared = false;
 		public bool Prepared {
 			get { return prepared; }
@@ -105,11 +105,9 @@ namespace FSpot {
 			if (is_disposed)
 				return;
 
+			prepared = notify_prepared = true;
+			damage = Rectangle.Zero;
 			base.OnAreaPrepared ();
-			prepared = true;
-			EventHandler<AreaPreparedEventArgs> eh = AreaPrepared;
-			if (eh != null)
-				eh (this, new AreaPreparedEventArgs (false));
 		}
 
 		protected override void OnAreaUpdated (int x, int y, int width, int height)
@@ -117,10 +115,9 @@ namespace FSpot {
 			if (is_disposed)
 				return;
 
+			Rectangle area = new Rectangle (x, y, width, height);
+			damage = damage == Rectangle.Zero ? area : damage.Union (area);
 			base.OnAreaUpdated (x, y, width, height);
-			EventHandler<AreaUpdatedEventArgs> eh = AreaUpdated;
-			if (eh != null)
-				eh (this, new AreaUpdatedEventArgs (new Gdk.Rectangle (x, y, width, height)));
 		}
 
 		protected virtual void OnCompleted ()
@@ -128,7 +125,6 @@ namespace FSpot {
 			if (is_disposed)
 				return;
 
-			loading = false;
 			EventHandler eh = Completed;
 			if (eh != null)
 				eh (this, EventArgs.Empty);
@@ -138,9 +134,10 @@ namespace FSpot {
 
 #region private stuffs
 		System.IO.Stream image_stream;
-		const int count = 1 << 16; //64k
-
+		const int count = 1 << 20;
 		byte [] buffer = new byte [count];
+		bool notify_completed = false;
+		Rectangle damage;
 
 		void HandleReadDone (IAsyncResult ar)
 		{
@@ -150,16 +147,39 @@ namespace FSpot {
 			int byte_read = image_stream.EndRead (ar);
 			if (byte_read == 0) {
 				image_stream.Close ();
-				OnCompleted ();
-				return;
+				loading = false;
+				notify_completed = true;
 			}
 
 			Gtk.Application.Invoke (this, null, delegate (object sender, EventArgs e) {
-				try {
-					if (!is_disposed && Write (buffer, (ulong)byte_read))
-						image_stream.BeginRead (buffer, 0, count, HandleReadDone, null);
-				} catch (System.ObjectDisposedException od) {
-				} catch (GLib.GException ge) {
+				if (loading)
+					try {
+						if (!is_disposed && Write (buffer, (ulong)byte_read))
+							image_stream.BeginRead (buffer, 0, count, HandleReadDone, null);
+					} catch (System.ObjectDisposedException od) {
+					} catch (GLib.GException ge) {
+					}
+
+				//Send the AreaPrepared event
+				if (notify_prepared) {
+					notify_prepared = false;
+					EventHandler<AreaPreparedEventArgs> eh = AreaPrepared;
+					if (eh != null)
+						eh (this, new AreaPreparedEventArgs (false));
+				}
+
+				//Send the AreaUpdated events
+				if (damage != Rectangle.Zero) {
+					EventHandler<AreaUpdatedEventArgs> eh = AreaUpdated;
+					if (eh != null)
+						eh (this, new AreaUpdatedEventArgs (damage));
+					damage = Rectangle.Zero;
+				}
+
+				//Send the Completed event
+				if (notify_completed) {
+					notify_completed = false;
+					OnCompleted ();
 				}
 			});
 		}



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