diff Implab.Fx/PromiseHelpers.cs @ 4:381095ad0a69

Implab.Fx: implemented animation object Implab.Fx: implemented transparency animation helper
author cin
date Tue, 17 Sep 2013 04:27:30 +0400
parents
children d67b95eddaf4 0fdaf280c797
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab.Fx/PromiseHelpers.cs	Tue Sep 17 04:27:30 2013 +0400
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using System.Threading;
+
+namespace Implab.Fx
+{
+    public static class PromiseHelpers
+    {
+        /// <summary>
+        /// Перенаправляет обработку обещания в поток указанного элемента управления.
+        /// </summary>
+        /// <typeparam name="T">Тип результата обещания</typeparam>
+        /// <param name="that">Исходное обещание</param>
+        /// <param name="ctl">Элемент управления</param>
+        /// <returns>Новое обещание, обработчики которого будут выполнены в потоке элемента управления.</returns>
+        /// <exception cref="ArgumentNullException">Параметр не может быть <c>null</c>.</exception>
+        /// <example>
+        /// client
+        ///     .Get("description.txt") // returns a promise
+        ///     .DirectToControl(m_ctl) // handle the promise in the thread of the control
+        ///     .Then(
+        ///         description => m_ctl.Text = description // now it's safe
+        ///     )
+        /// </example>
+        public static Promise<T> DispatchToControl<T>(this Promise<T> that, Control ctl)
+        {
+            if (that == null)
+                throw new ArgumentNullException("that");
+            if (ctl == null)
+                throw new ArgumentNullException("ctl");
+
+            var directed = new Promise<T>();
+
+            that.Then(
+                res =>
+                {
+                    if (ctl.InvokeRequired)
+                        ctl.Invoke(new Action<T>(directed.Resolve), res);
+                    else
+                        directed.Resolve(res);
+                },
+                err =>
+                {
+                    if (ctl.InvokeRequired)
+                        ctl.Invoke(new Action<Exception>(directed.Reject), err);
+                    else
+                        directed.Reject(err);
+                }
+            );
+
+            return directed;
+        }
+
+        /// <summary>
+        /// Направляет обработку обещания в текущий поток, если у него существует контекст синхронизации.
+        /// </summary>
+        /// <typeparam name="T">Тип результата обещания.</typeparam>
+        /// <param name="that">Обещание которое нужно обработать в текущем потоке.</param>
+        /// <returns>Перенаправленное обещание.</returns>
+        public static Promise<T> DispatchToCurrentThread<T>(this Promise<T> that)
+        {
+            var sync = SynchronizationContext.Current;
+            if (sync == null)
+                throw new InvalidOperationException("The current thread doesn't have a syncronization context");
+            return DispatchToSyncContext(that, sync);
+        }
+
+        /// <summary>
+        /// Направляет обработку обещания в указанный контекст синхронизации.
+        /// </summary>
+        /// <typeparam name="T">Тип результата обещания.</typeparam>
+        /// <param name="that">Обещание, которое требуется обработать в указанном контексте синхронизации.</param>
+        /// <param name="sync">Контекст синхронизации в который будет направлено обещание.</param>
+        /// <returns>Новое обещание, которое будет обрабатываться в указанном контексте.</returns>
+        public static Promise<T> DispatchToSyncContext<T>(this Promise<T> that, SynchronizationContext sync)
+        {
+            if (that == null)
+                throw new ArgumentNullException("that");
+            if (sync == null)
+                throw new ArgumentNullException("sync");
+
+            var d = new Promise<T>();
+
+            that.Then(
+                res => sync.Post(state => d.Resolve(res), null),
+                err => sync.Post(state => d.Reject(err), null)
+            );
+
+            return d;
+        }
+    }
+}