~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Ide/MonoDevelop.Ide/DispatchService.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
using System;
31
31
using System.Threading;
32
32
using System.Collections;
 
33
using System.Diagnostics;
33
34
 
34
35
using MonoDevelop.Core;
35
36
using MonoDevelop.Ide.Gui;
36
37
using System.Collections.Generic;
 
38
using System.Linq;
37
39
 
38
40
namespace MonoDevelop.Ide
39
41
{
131
133
                        // This means we pump the main loop dozens of times a second resulting in many screen
132
134
                        // redraws and significantly slow down the running task.
133
135
 
134
 
                        int n = 1000;
 
136
                        int maxLength = 20;
135
137
                        Gdk.Threads.Enter();
 
138
                        Stopwatch sw = new Stopwatch ();
 
139
                        sw.Start ();
136
140
 
137
141
                        // Check for less than zero in case there's a system time change
138
142
                        var diff = DateTime.UtcNow - lastPendingEvents;
139
143
                        if (diff > TimeSpan.FromMilliseconds (500) || diff < TimeSpan.Zero) {
140
144
                                lastPendingEvents = DateTime.UtcNow;
141
 
                                while (Gtk.Application.EventsPending () && --n > 0) {
 
145
                                while (Gtk.Application.EventsPending () && sw.ElapsedMilliseconds < maxLength) {
142
146
                                        Gtk.Application.RunIteration (false);
143
147
                                }
144
148
                        }
145
149
 
 
150
                        sw.Stop ();
 
151
 
146
152
                        Gdk.Threads.Leave();
147
153
                        guiDispatcher ();
148
154
                }
320
326
                        else
321
327
                                LoggingService.LogError ("{0} {1}\nCaller stack not available. Define the environment variable MONODEVELOP_DISPATCH_DEBUG to enable caller stack capture.", errormsg, msg.Exception.ToString ());
322
328
                }
 
329
 
 
330
                #region Animations
 
331
 
 
332
                /// <summary>
 
333
                /// Runs a delegate at regular intervals 
 
334
                /// </summary>
 
335
                /// <returns>
 
336
                /// An animation object. It can be disposed to stop the animation.
 
337
                /// </returns>
 
338
                /// <param name='animation'>
 
339
                /// The delegate to run. The return value if the number of milliseconds to wait until the delegate is run again.
 
340
                /// The execution will stop if the deletgate returns 0
 
341
                /// </param>
 
342
                public static IDisposable RunAnimation (Func<int> animation)
 
343
                {
 
344
                        var ainfo = new AnimationInfo () {
 
345
                                AnimationFunc = animation,
 
346
                                NextDueTime = DateTime.Now
 
347
                        };
 
348
 
 
349
                        activeAnimations.Add (ainfo);
 
350
                        
 
351
                        // Don't immediately run the animation if we are going to do it in less than 20ms
 
352
                        if (animationHandle == 0 || currentAnimationSpan > 20)
 
353
                                ProcessAnimations ();
 
354
                        return ainfo;
 
355
                }
 
356
                
 
357
                static List<AnimationInfo> activeAnimations = new List<AnimationInfo> ();
 
358
                static uint animationHandle;
 
359
                static DateTime nextDueTime;
 
360
                static int currentAnimationSpan;
 
361
 
 
362
                class AnimationInfo: IDisposable {
 
363
                        public Func<int> AnimationFunc;
 
364
                        public DateTime NextDueTime;
 
365
 
 
366
                        public void Dispose ()
 
367
                        {
 
368
                                DispatchService.StopAnimation (this);
 
369
                        }
 
370
                }
 
371
 
 
372
                static bool ProcessAnimations ()
 
373
                {
 
374
                        List<AnimationInfo> toDelete = null;
 
375
 
 
376
                        DateTime now = DateTime.Now;
 
377
                        nextDueTime = DateTime.MaxValue;
 
378
 
 
379
                        foreach (var a in activeAnimations) {
 
380
                                if (a.NextDueTime <= now) {
 
381
                                        int ms = a.AnimationFunc ();
 
382
                                        if (ms <= 0) {
 
383
                                                if (toDelete == null)
 
384
                                                        toDelete = new List<AnimationInfo> ();
 
385
                                                toDelete.Add (a);
 
386
                                                a.NextDueTime = DateTime.MaxValue;
 
387
                                        } else
 
388
                                                a.NextDueTime = DateTime.Now + TimeSpan.FromMilliseconds (ms);
 
389
                                }
 
390
                                if (a.NextDueTime < nextDueTime)
 
391
                                        nextDueTime = a.NextDueTime;
 
392
                        }
 
393
 
 
394
                        if (toDelete != null) {
 
395
                                foreach (var a in toDelete)
 
396
                                        activeAnimations.Remove (a);
 
397
                        }
 
398
 
 
399
                        if (nextDueTime == DateTime.MaxValue) {
 
400
                                // No more animations
 
401
                                animationHandle = 0;
 
402
                                return false;
 
403
                        }
 
404
 
 
405
                        int nms = (int) (nextDueTime - DateTime.Now).TotalMilliseconds;
 
406
                        if (nms < 20)
 
407
                                nms = 20;
 
408
 
 
409
                        // Don't re-schedule if the current time span is more or less the same as the previous one
 
410
                        if (animationHandle != 0 && Math.Abs (nms - currentAnimationSpan) <= 3)
 
411
                                return true;
 
412
 
 
413
                        currentAnimationSpan = nms;
 
414
                        animationHandle = GLib.Timeout.Add ((uint)currentAnimationSpan, ProcessAnimations);
 
415
                        return false;
 
416
                }
 
417
 
 
418
                static void StopAnimation (AnimationInfo a)
 
419
                {
 
420
                        activeAnimations.Remove (a);
 
421
                        if (activeAnimations.Count == 0 && animationHandle != 0) {
 
422
                                GLib.Source.Remove (animationHandle);
 
423
                                animationHandle = 0;
 
424
                        }
 
425
                }
 
426
 
 
427
                #endregion
323
428
        }
324
429
 
325
430
        public delegate void MessageHandler ();