Explorar o código

Move timers to the driver level. On X they are queued by the driver and checked on idle.

svn path=/trunk/mcs/; revision=32748
Jackson Harper %!s(int64=21) %!d(string=hai) anos
pai
achega
4ad54b53ce

+ 47 - 18
mcs/class/Managed.Windows.Forms/System.Windows.Forms/Timer.cs

@@ -24,19 +24,20 @@
 
 
 using System;
+using System.Threading;
 using System.ComponentModel;
 
 namespace System.Windows.Forms {
 
 	public class Timer : Component {
 
-		private System.Timers.Timer timer;
+		private bool enabled;
 		private IContainer container;
+		private int interval = 100;
+		private DateTime expires;
 
 		public Timer ()
 		{
-			timer = new System.Timers.Timer ();
-			timer.Elapsed += new System.Timers.ElapsedEventHandler (ElapsedEventHandler);
 		}
 
 		public Timer (IContainer container) : this ()
@@ -45,23 +46,45 @@ namespace System.Windows.Forms {
 		}
 
 		public bool Enabled {
-			get { return timer.Enabled; }
-			set { timer.Enabled = value; }
+			get {
+				return enabled;
+			}
+			set {
+				enabled = value;
+				if (value) {
+					Console.WriteLine ("Setting timer");
+					XplatUI.SetTimer (this);
+				} else {
+					XplatUI.KillTimer (this);
+				}
+			}
 		}
 
 		public int Interval {
-			get { return (int) timer.Interval; }
-			set { timer.Interval = (int) value; }
+			get {
+				return interval;
+			}
+			set {
+				interval = value;
+				// Use AddTicks so we get some rounding
+				expires = DateTime.Now.AddMilliseconds (interval);
+			}
 		}
 
 		public void Start ()
 		{
-			timer.Start ();
+			Enabled = true;
 		}
 
 		public void Stop ()
 		{
-			timer.Stop ();
+			Enabled = false;
+		}
+
+		internal DateTime Expires {
+			get {
+				return expires;
+			}
 		}
 
 		public event EventHandler Tick;
@@ -71,28 +94,34 @@ namespace System.Windows.Forms {
 			return base.ToString () + ", Interval: " + Interval;
 		}
 
+		internal void Update ()
+		{
+			expires = DateTime.Now.AddMilliseconds (interval);
+		}
+
+		internal void FireTick ()
+		{
+			OnTick (EventArgs.Empty);
+		}
+
+
 		protected virtual void OnTick (EventArgs e)
 		{
-			if (Tick != null)
-				Tick (this, e);
+			lock (this) {
+				if (Tick != null)
+					Tick (this, e);
+			}
 		}
 
 		protected override void Dispose (bool disposing)
 		{
 			Enabled = false;
-			timer.Dispose ();
 		}
 
 		private void TickHandler (object sender, EventArgs e)
 		{
 			OnTick (e);
 		}
-
-		private void ElapsedEventHandler (object sender, System.Timers.ElapsedEventArgs e)
-		{
-			Control.BeginInvokeInternal (new EventHandler (TickHandler), new object [] { this, e });
-		}
-		
 	}
 }
 

+ 14 - 1
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUI.cs

@@ -23,9 +23,12 @@
 //	Peter Bartok	[email protected]
 //
 //
-// $Revision: 1.19 $
+// $Revision: 1.20 $
 // $Modtime: $
 // $Log: XplatUI.cs,v $
+// Revision 1.20  2004/08/24 11:29:44  jackson
+// Move timers to the driver level. On X they are queued by the driver and checked on idle.
+//
 // Revision 1.19  2004/08/23 19:39:30  pbartok
 // - Added method to move mouse cursor
 //
@@ -326,6 +329,16 @@ namespace System.Windows.Forms {
 			driver.SendAsyncMethod (data);
 		}
 
+		internal static void SetTimer (Timer timer)
+		{
+			driver.SetTimer (timer);
+		}
+
+		internal static void KillTimer (Timer timer)
+		{
+			driver.KillTimer (timer);
+		}
+
 		// Santa's little helper
 		internal static void Where() {
 			Console.WriteLine("Here: {0}", new StackTrace().ToString());

+ 8 - 1
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIDriver.cs

@@ -23,9 +23,12 @@
 //	Peter Bartok	[email protected]
 //
 //
-// $Revision: 1.19 $
+// $Revision: 1.20 $
 // $Modtime: $
 // $Log: XplatUIDriver.cs,v $
+// Revision 1.20  2004/08/24 11:29:44  jackson
+// Move timers to the driver level. On X they are queued by the driver and checked on idle.
+//
 // Revision 1.19  2004/08/23 19:39:30  pbartok
 // - Added method to move mouse cursor
 //
@@ -193,6 +196,10 @@ namespace System.Windows.Forms {
 		internal abstract void ReleaseWindow(IntPtr hWnd);
 
 		internal abstract void SendAsyncMethod (AsyncMethodData method);
+		internal abstract void SetTimer (Timer timer);
+		internal abstract void KillTimer (Timer timer);
+
+
 #endregion	// XplatUI Driver Methods
 	}
 }

+ 14 - 1
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs

@@ -23,9 +23,12 @@
 //	Peter Bartok	[email protected]
 //
 //
-// $Revision: 1.29 $
+// $Revision: 1.30 $
 // $Modtime: $
 // $Log: XplatUIWin32.cs,v $
+// Revision 1.30  2004/08/24 11:29:44  jackson
+// Move timers to the driver level. On X they are queued by the driver and checked on idle.
+//
 // Revision 1.29  2004/08/24 00:19:36  ravindra
 // Removed the unwanted destructor.
 //
@@ -1020,6 +1023,16 @@ namespace System.Windows.Forms {
 			Win32PostMessage(FosterParent, Msg.WM_ASYNC_MESSAGE, IntPtr.Zero, (IntPtr)GCHandle.Alloc (method));
 		}
 
+		internal override void SetTimer (Timer timer)
+		{
+			throw new NotImplementedException ();
+		}
+
+		internal override void KillTimer (Timer timer)
+		{
+			throw new NotImplementedException ();
+		}
+
 		// Santa's little helper
 		static void Where() {
 			Console.WriteLine("Here: {0}", new StackTrace().ToString());

+ 25 - 6
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs

@@ -59,6 +59,7 @@ namespace System.Windows.Forms {
 
 		private static Hashtable	handle_data;
 		private Queue message_queue;
+		private ArrayList timer_list;
 
 		private static readonly EventMask  SelectInputMask = EventMask.ButtonPressMask | 
 				EventMask.ButtonReleaseMask | 
@@ -111,6 +112,7 @@ namespace System.Windows.Forms {
 			ref_count=0;
 
 			message_queue = new Queue ();
+			timer_list = new ArrayList ();
 
 			// Now regular initialization
 			SetDisplay(XOpenDisplay(IntPtr.Zero));
@@ -554,16 +556,24 @@ namespace System.Windows.Forms {
 			XEvent	xevent = new XEvent();
 			bool queued_message = false;
 
-		begin:
 			lock (message_queue) {
 				if (message_queue.Count > 0) {
 					xevent = (XEvent) message_queue.Dequeue ();
 					queued_message = true;
 				}
 			}
+
 			if (!queued_message) {
 				lock (this) {
 					if (!XCheckMaskEvent (DisplayHandle, SelectInputMask, ref xevent)) {
+						for (int i = 0; i < timer_list.Count; i++) {
+							Timer timer = (Timer) timer_list [i];
+							DateTime now = DateTime.Now;
+							if (timer.Enabled && timer.Expires <= now) {
+								timer.FireTick ();
+								timer.Update ();
+							}
+						}
 						msg.message = Msg.WM_ENTERIDLE;
 						return true;
 					}
@@ -703,11 +713,6 @@ namespace System.Windows.Forms {
 					data.AddToInvalidArea (xevent.ExposeEvent.x, xevent.ExposeEvent.y,
 							xevent.ExposeEvent.width, xevent.ExposeEvent.height);
 
-					// Only paint on the last of a series of expose events
-					if (xevent.ExposeEvent.count > 0) {
-						goto begin;
-					}
-
 					lock (this) {
 						// Try combining expose events to reduce drawing	
 						while (XCheckWindowEvent (DisplayHandle, xevent.AnyEvent.window,
@@ -930,6 +935,20 @@ namespace System.Windows.Forms {
 			}
 		}
 
+		internal override void SetTimer (Timer timer)
+		{
+			lock (timer_list) {
+				timer_list.Add (timer);
+			}
+		}
+
+		internal override void KillTimer (Timer timer)
+		{
+			lock (timer_list) {
+				timer_list.Add (timer);
+			}
+		}
+
 		// Santa's little helper
 		static void Where() 
 		{