Mercurial > pub > ImplabNet
view Implab.Fx/Animation.cs @ 138:f75cfa58e3d4 v2
added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
author | cin |
---|---|
date | Tue, 17 Feb 2015 18:16:26 +0300 |
parents | dfa21d507bc5 |
children |
line wrap: on
line source
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Timers; using System.ComponentModel; using System.Diagnostics; namespace Implab.Fx { public delegate void AnimationStep<T>(T target, int elapsed, int duration); public class Animation<TArg> where TArg: class { int m_duration; int m_delay; int m_elapsed; int m_prevTicks; TArg m_arg; ISynchronizeInvoke m_syncronizationObject; public event AnimationStep<TArg> Step; Promise<TArg> m_promise; public Animation(TArg target, int duration, int delay) { if (duration <= 0) throw new ArgumentOutOfRangeException("duration"); if (delay <= 0) throw new ArgumentOutOfRangeException("delay"); m_arg = target; m_syncronizationObject = target as ISynchronizeInvoke; m_duration = duration; m_delay = delay; m_promise = new Promise<TArg>(); } public Animation(TArg target) : this(target, 500, 30) { } public TArg Traget { get { return m_arg; } } public Promise<TArg> Play() { var timer = new Timer(m_delay); timer.AutoReset = false; timer.SynchronizingObject = m_syncronizationObject; timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); m_prevTicks = Environment.TickCount; timer.Start(); return m_promise; } void timer_Elapsed(object sender, ElapsedEventArgs args) { var timer = sender as Timer; var dt = Environment.TickCount - m_prevTicks; m_prevTicks = Environment.TickCount; m_elapsed += dt; if (m_elapsed > m_duration) m_elapsed = m_duration; try { var handler = Step; if (handler != null) handler(m_arg, m_elapsed, m_duration); } catch (Exception e) { Trace.TraceError(e.ToString()); } if (m_elapsed < m_duration) timer.Start(); else { timer.Dispose(); m_promise.Resolve(m_arg); } } } }