##// END OF EJS Templates
Implab.Fx: implemented animation object...
cin -
r4:381095ad0a69 default
parent child
Show More
@@ -0,0 +1,41
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Windows.Forms;
6 using System.Diagnostics;
7
8 namespace Implab.Fx
9 {
10 public static class AnimationHelpers
11 {
12 public static Animation<TTarget> AnimateProperty<TTarget,TVal>(this Animation<TTarget> animation, Action<TTarget,TVal> setter, Func<TTarget,TVal> getter, TVal newValue, Func<TVal,TVal,int,int,TVal> fx) where TTarget: class
13 {
14 if (animation == null)
15 throw new ArgumentNullException("animation");
16
17 TVal oldValue = getter(animation.Traget);
18
19 animation.Step += (target, elaped, duration) =>
20 {
21 var value = fx(oldValue, newValue, elaped, duration);
22 setter(target, value);
23 };
24
25 return animation;
26 }
27
28 public static Animation<Form> AnimateTransparency(this Form ctl, float newValue)
29 {
30 var anim = new Animation<Form>(ctl);
31
32 anim.AnimateProperty(
33 (target, value) => target.Opacity = value,
34 target => target.Opacity,
35 newValue,
36 (ov, nv, el, du) => ov + ((float)el / du) * (nv - ov)
37 );
38 return anim;
39 }
40 }
41 }
@@ -0,0 +1,95
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Windows.Forms;
6 using System.Threading;
7
8 namespace Implab.Fx
9 {
10 public static class PromiseHelpers
11 {
12 /// <summary>
13 /// Перенаправляет обработку обещания в поток указанного элемента управления.
14 /// </summary>
15 /// <typeparam name="T">Тип результата обещания</typeparam>
16 /// <param name="that">Исходное обещание</param>
17 /// <param name="ctl">Элемент управления</param>
18 /// <returns>Новое обещание, обработчики которого будут выполнены в потоке элемента управления.</returns>
19 /// <exception cref="ArgumentNullException">Параметр не может быть <c>null</c>.</exception>
20 /// <example>
21 /// client
22 /// .Get("description.txt") // returns a promise
23 /// .DirectToControl(m_ctl) // handle the promise in the thread of the control
24 /// .Then(
25 /// description => m_ctl.Text = description // now it's safe
26 /// )
27 /// </example>
28 public static Promise<T> DispatchToControl<T>(this Promise<T> that, Control ctl)
29 {
30 if (that == null)
31 throw new ArgumentNullException("that");
32 if (ctl == null)
33 throw new ArgumentNullException("ctl");
34
35 var directed = new Promise<T>();
36
37 that.Then(
38 res =>
39 {
40 if (ctl.InvokeRequired)
41 ctl.Invoke(new Action<T>(directed.Resolve), res);
42 else
43 directed.Resolve(res);
44 },
45 err =>
46 {
47 if (ctl.InvokeRequired)
48 ctl.Invoke(new Action<Exception>(directed.Reject), err);
49 else
50 directed.Reject(err);
51 }
52 );
53
54 return directed;
55 }
56
57 /// <summary>
58 /// Направляет обработку обещания в текущий поток, если у него существует контекст синхронизации.
59 /// </summary>
60 /// <typeparam name="T">Тип результата обещания.</typeparam>
61 /// <param name="that">Обещание которое нужно обработать в текущем потоке.</param>
62 /// <returns>Перенаправленное обещание.</returns>
63 public static Promise<T> DispatchToCurrentThread<T>(this Promise<T> that)
64 {
65 var sync = SynchronizationContext.Current;
66 if (sync == null)
67 throw new InvalidOperationException("The current thread doesn't have a syncronization context");
68 return DispatchToSyncContext(that, sync);
69 }
70
71 /// <summary>
72 /// Направляет обработку обещания в указанный контекст синхронизации.
73 /// </summary>
74 /// <typeparam name="T">Тип результата обещания.</typeparam>
75 /// <param name="that">Обещание, которое требуется обработать в указанном контексте синхронизации.</param>
76 /// <param name="sync">Контекст синхронизации в который будет направлено обещание.</param>
77 /// <returns>Новое обещание, которое будет обрабатываться в указанном контексте.</returns>
78 public static Promise<T> DispatchToSyncContext<T>(this Promise<T> that, SynchronizationContext sync)
79 {
80 if (that == null)
81 throw new ArgumentNullException("that");
82 if (sync == null)
83 throw new ArgumentNullException("sync");
84
85 var d = new Promise<T>();
86
87 that.Then(
88 res => sync.Post(state => d.Resolve(res), null),
89 err => sync.Post(state => d.Reject(err), null)
90 );
91
92 return d;
93 }
94 }
95 }
@@ -7,3 +7,4 Implab/bin/
7 Implab/obj/
7 Implab/obj/
8 TestResults/
8 TestResults/
9 Implab.Fx/obj/
9 Implab.Fx/obj/
10 Implab.Fx/bin/
@@ -2,14 +2,96
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Linq;
3 using System.Linq;
4 using System.Text;
4 using System.Text;
5 using System.Timers;
6 using System.ComponentModel;
7 using System.Diagnostics;
5
8
6 namespace Implab.Fx
9 namespace Implab.Fx
7 {
10 {
8 public class Animation
11 public delegate void AnimationStep<T>(T target, int elapsed, int duration);
12
13 public class Animation<TArg> where TArg: class
9 {
14 {
10 int m_duration;
15 int m_duration;
11 int m_fps;
16 int m_delay;
17 int m_elapsed;
18 int m_prevTicks;
19 TArg m_arg;
20 ISynchronizeInvoke m_syncronizationObject;
21
22 public event AnimationStep<TArg> Step;
23
24 Promise<TArg> m_promise;
25
26 public Animation(TArg target, int duration, int delay)
27 {
28 if (duration <= 0)
29 throw new ArgumentOutOfRangeException("duration");
30 if (delay <= 0)
31 throw new ArgumentOutOfRangeException("delay");
32
33 m_arg = target;
34 m_syncronizationObject = target as ISynchronizeInvoke;
35 m_duration = duration;
36 m_delay = delay;
37 m_promise = new Promise<TArg>();
38 }
39
40 public Animation(TArg target)
41 : this(target, 500, 30)
42 {
43 }
44
45 public TArg Traget
46 {
47 get { return m_arg; }
48 }
12
49
50 public Promise<TArg> Play()
51 {
52 var timer = new Timer(m_delay);
53
54 timer.AutoReset = true;
55 timer.SynchronizingObject = m_syncronizationObject;
56 timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
13
57
58 m_prevTicks = Environment.TickCount;
59
60 timer.Start();
61
62 return m_promise;
63 }
64
65 void timer_Elapsed(object sender, ElapsedEventArgs args)
66 {
67 var timer = sender as Timer;
68
69 var dt = Environment.TickCount - m_prevTicks;
70 m_prevTicks = Environment.TickCount;
71
72 m_elapsed += dt;
73
74 if (m_elapsed > m_duration)
75 m_elapsed = m_duration;
76
77 try
78 {
79 var handler = Step;
80 if (handler != null)
81 handler(m_arg, m_elapsed, m_duration);
82 }
83 catch (Exception e)
84 {
85 Trace.TraceError(e.ToString());
86 }
87
88 if (m_elapsed < m_duration)
89 timer.Start();
90 else
91 {
92 timer.Dispose();
93 m_promise.Resolve(m_arg);
94 }
95 }
14 }
96 }
15 }
97 }
@@ -41,7 +41,9
41 <Reference Include="System.Xml" />
41 <Reference Include="System.Xml" />
42 </ItemGroup>
42 </ItemGroup>
43 <ItemGroup>
43 <ItemGroup>
44 <Compile Include="ControlHelpers.cs" />
44 <Compile Include="Animation.cs" />
45 <Compile Include="AnimationHelpers.cs" />
46 <Compile Include="PromiseHelpers.cs" />
45 <Compile Include="Properties\AssemblyInfo.cs" />
47 <Compile Include="Properties\AssemblyInfo.cs" />
46 </ItemGroup>
48 </ItemGroup>
47 <ItemGroup>
49 <ItemGroup>
@@ -1,101 +1,101
1 using System;
1 using System;
2 using Microsoft.VisualStudio.TestTools.UnitTesting;
2 using Microsoft.VisualStudio.TestTools.UnitTesting;
3 using Implab;
3 using Implab;
4 using System.Reflection;
4 using System.Reflection;
5 using System.Threading;
5 using System.Threading;
6
6
7 namespace Implab.Tests
7 namespace Implab.Tests
8 {
8 {
9 [TestClass]
9 [TestClass]
10 public class AsyncTests
10 public class AsyncTests
11 {
11 {
12 [TestMethod]
12 [TestMethod]
13 public void ResolveTest ()
13 public void ResolveTest ()
14 {
14 {
15 int res = -1;
15 int res = -1;
16 var p = new Promise<int> ();
16 var p = new Promise<int> ();
17 p.Then (x => res = x);
17 p.Then (x => res = x);
18 p.Resolve (100);
18 p.Resolve (100);
19
19
20 Assert.AreEqual (res, 100);
20 Assert.AreEqual (res, 100);
21 }
21 }
22
22
23 [TestMethod]
23 [TestMethod]
24 public void RejectTest ()
24 public void RejectTest ()
25 {
25 {
26 int res = -1;
26 int res = -1;
27 Exception err = null;
27 Exception err = null;
28
28
29 var p = new Promise<int> ();
29 var p = new Promise<int> ();
30 p.Then (x => res = x, e => err = e);
30 p.Then (x => res = x, e => err = e);
31 p.Reject (new ApplicationException ("error"));
31 p.Reject (new ApplicationException ("error"));
32
32
33 Assert.AreEqual (res, -1);
33 Assert.AreEqual (res, -1);
34 Assert.AreEqual (err.Message, "error");
34 Assert.AreEqual (err.Message, "error");
35
35
36 }
36 }
37
37
38 [TestMethod]
38 [TestMethod]
39 public void JoinSuccessTest ()
39 public void JoinSuccessTest ()
40 {
40 {
41 var p = new Promise<int> ();
41 var p = new Promise<int> ();
42 p.Resolve (100);
42 p.Resolve (100);
43 Assert.AreEqual (p.Join (), 100);
43 Assert.AreEqual (p.Join (), 100);
44 }
44 }
45
45
46 [TestMethod]
46 [TestMethod]
47 public void JoinFailTest ()
47 public void JoinFailTest ()
48 {
48 {
49 var p = new Promise<int> ();
49 var p = new Promise<int> ();
50 p.Reject (new ApplicationException ("failed"));
50 p.Reject (new ApplicationException ("failed"));
51
51
52 try {
52 try {
53 p.Join ();
53 p.Join ();
54 throw new ApplicationException ("WRONG!");
54 throw new ApplicationException ("WRONG!");
55 } catch (TargetInvocationException err) {
55 } catch (TargetInvocationException err) {
56 Assert.AreEqual (err.InnerException.Message, "failed");
56 Assert.AreEqual (err.InnerException.Message, "failed");
57 } catch {
57 } catch {
58 Assert.Fail ("Got wrong excaption");
58 Assert.Fail ("Got wrong excaption");
59 }
59 }
60 }
60 }
61
61
62 [TestMethod]
62 [TestMethod]
63 public void MapTest ()
63 public void MapTest ()
64 {
64 {
65 var p = new Promise<int> ();
65 var p = new Promise<int> ();
66
66
67 var p2 = p.Map (x => x.ToString ());
67 var p2 = p.Map (x => x.ToString ());
68 p.Resolve (100);
68 p.Resolve (100);
69
69
70 Assert.AreEqual (p2.Join (), "100");
70 Assert.AreEqual (p2.Join (), "100");
71 }
71 }
72
72
73 [TestMethod]
73 [TestMethod]
74 public void ChainTest ()
74 public void ChainTest ()
75 {
75 {
76 var p1 = new Promise<int> ();
76 var p1 = new Promise<int> ();
77
77
78 var p3 = p1.Chain (x => {
78 var p3 = p1.Chain (x => {
79 var p2 = new Promise<string> ();
79 var p2 = new Promise<string> ();
80 p2.Resolve (x.ToString ());
80 p2.Resolve (x.ToString ());
81 return p2;
81 return p2;
82 });
82 });
83
83
84 p1.Resolve (100);
84 p1.Resolve (100);
85
85
86 Assert.AreEqual (p3.Join (), "100");
86 Assert.AreEqual (p3.Join (), "100");
87 }
87 }
88
88
89 [TestMethod]
89 [TestMethod]
90 public void PoolTest ()
90 public void PoolTest ()
91 {
91 {
92 var pid = Thread.CurrentThread.ManagedThreadId;
92 var pid = Thread.CurrentThread.ManagedThreadId;
93 var p = AsyncPool.Invoke (() => {
93 var p = AsyncPool.Invoke (() => {
94 return Thread.CurrentThread.ManagedThreadId;
94 return Thread.CurrentThread.ManagedThreadId;
95 });
95 });
96
96
97 Assert.AreNotEqual (pid, p.Join ());
97 Assert.AreNotEqual (pid, p.Join ());
98 }
98 }
99 }
99 }
100 }
100 }
101
101
@@ -1,7 +1,7
1 
1 
2 Microsoft Visual Studio Solution File, Format Version 11.00
2 Microsoft Visual Studio Solution File, Format Version 11.00
3 # Visual Studio 2010
3 # Visual Studio 2010
4 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab", "Implab\Implab.csproj", "{99B95D0D-9CF9-4F70-8ADF-F4D0AA5CB0D9}"
4 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab", "Implab\Implab.csproj", "{F550F1F8-8746-4AD0-9614-855F4C4B7F05}"
5 EndProject
5 EndProject
6 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CE8D8D18-437A-445C-B662-4C2CE79A76F6}"
6 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CE8D8D18-437A-445C-B662-4C2CE79A76F6}"
7 ProjectSection(SolutionItems) = preProject
7 ProjectSection(SolutionItems) = preProject
@@ -23,10 +23,10 Global
23 Release|Any CPU = Release|Any CPU
23 Release|Any CPU = Release|Any CPU
24 EndGlobalSection
24 EndGlobalSection
25 GlobalSection(ProjectConfigurationPlatforms) = postSolution
25 GlobalSection(ProjectConfigurationPlatforms) = postSolution
26 {99B95D0D-9CF9-4F70-8ADF-F4D0AA5CB0D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 {99B95D0D-9CF9-4F70-8ADF-F4D0AA5CB0D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 {99B95D0D-9CF9-4F70-8ADF-F4D0AA5CB0D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 {99B95D0D-9CF9-4F70-8ADF-F4D0AA5CB0D9}.Release|Any CPU.Build.0 = Release|Any CPU
29 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.Build.0 = Release|Any CPU
30 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
32 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -5,7 +5,7
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProductVersion>10.0.0</ProductVersion>
6 <ProductVersion>10.0.0</ProductVersion>
7 <SchemaVersion>2.0</SchemaVersion>
7 <SchemaVersion>2.0</SchemaVersion>
8 <ProjectGuid>{99B95D0D-9CF9-4F70-8ADF-F4D0AA5CB0D9}</ProjectGuid>
8 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
9 <OutputType>Library</OutputType>
9 <OutputType>Library</OutputType>
10 <RootNamespace>Implab</RootNamespace>
10 <RootNamespace>Implab</RootNamespace>
11 <AssemblyName>Implab</AssemblyName>
11 <AssemblyName>Implab</AssemblyName>
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now