# HG changeset patch # User cin # Date 1383307388 -14400 # Node ID 7ea9363fef6ce03a1d177d55a29dec1d3f5a6c7a # Parent dfa21d507bc51624285dcb5724056b2f00f7fa30 inital progress handling diff -r dfa21d507bc5 -r 7ea9363fef6c Implab.suo Binary file Implab.suo has changed diff -r dfa21d507bc5 -r 7ea9363fef6c Implab/IPromise.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/IPromise.cs Fri Nov 01 16:03:08 2013 +0400 @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Implab +{ + public interface IPromise + { + /// + /// Check whereather the promise has no more than one dependent promise. + /// + bool IsExclusive + { + get; + } + + /// + /// The current state of the promise. + /// + PromiseState State + { + get; + } + + /// + /// Tries to cancel the promise or the complete chain. + /// + /// Try to cancel the parent promise is it has the only one child + /// + bool Cancel(bool dependencies); + } +} diff -r dfa21d507bc5 -r 7ea9363fef6c Implab/Implab.csproj --- a/Implab/Implab.csproj Mon Oct 21 02:34:31 2013 +0400 +++ b/Implab/Implab.csproj Fri Nov 01 16:03:08 2013 +0400 @@ -32,10 +32,14 @@ + + + + diff -r dfa21d507bc5 -r 7ea9363fef6c Implab/ProgressInitEventArgs.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/ProgressInitEventArgs.cs Fri Nov 01 16:03:08 2013 +0400 @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Implab +{ + + public class ProgressInitEventArgs: EventArgs + { + public float MaxProgress + { + get; + private set; + } + + public float CurrentProgress + { + get; + private set; + } + + public string Message + { + get; + private set; + } + + public ProgressInitEventArgs(float current, float max, string message) + { + this.MaxProgress = max; + this.CurrentProgress = current; + this.Message = message; + } + } +} diff -r dfa21d507bc5 -r 7ea9363fef6c Implab/Promise.cs --- a/Implab/Promise.cs Mon Oct 21 02:34:31 2013 +0400 +++ b/Implab/Promise.cs Fri Nov 01 16:03:08 2013 +0400 @@ -48,30 +48,32 @@ /// только инициатор обещания иначе могут возникнуть противоречия. /// /// - public class Promise { + public class Promise: IPromise { struct ResultHandlerInfo { public ResultHandler resultHandler; public ErrorHandler errorHandler; - } - - enum State { - Unresolved, - Resolving, - Resolved, - Cancelled + public Action cancelHandler; } LinkedList m_handlersChain = new LinkedList(); - State m_state; + PromiseState m_state; bool m_cancellable; T m_result; Exception m_error; + IPromise m_parent; + int m_childrenCount; public Promise() { m_cancellable = true; } + public Promise(IPromise parent, bool cancellable) + { + m_cancellable = cancellable; + m_parent = parent; + } + /// /// Событие, возникающее при отмене асинхронной операции. /// @@ -87,12 +89,12 @@ /// Данное обещание уже выполнено public void Resolve(T result) { lock (this) { - if (m_state == State.Cancelled) + if (m_state == PromiseState.Cancelled) return; - if (m_state != State.Unresolved) + if (m_state != PromiseState.Unresolved) throw new InvalidOperationException("The promise is already resolved"); m_result = result; - m_state = State.Resolving; + m_state = PromiseState.Resolved; } ResultHandlerInfo handler; @@ -107,12 +109,12 @@ /// Данное обещание уже выполнено public void Reject(Exception error) { lock (this) { - if (m_state == State.Cancelled) + if (m_state == PromiseState.Cancelled) return; - if (m_state != State.Unresolved) + if (m_state != PromiseState.Unresolved) throw new InvalidOperationException("The promise is already resolved"); m_error = error; - m_state = State.Resolving; + m_state = PromiseState.Rejected; } ResultHandlerInfo handler; @@ -126,8 +128,9 @@ /// true Операция была отменена, обработчики не будут вызваны.false отмена не возможна, поскольку обещание уже выполнено и обработчики отработали. public bool Cancel() { lock (this) { - if (m_state == State.Unresolved && m_cancellable) { - m_state = State.Cancelled; + if (m_state == PromiseState.Unresolved && m_cancellable) + { + m_state = PromiseState.Cancelled; EventHandler temp = Cancelled; if (temp != null) @@ -348,14 +351,13 @@ handler = default(ResultHandlerInfo); lock (this) { - Debug.Assert(m_state == State.Resolving); + Debug.Assert(m_state != PromiseState.Unresolved); if (m_handlersChain.Count > 0) { handler = m_handlersChain.First.Value; m_handlersChain.RemoveFirst(); return true; } else { - m_state = State.Resolved; return false; } } @@ -365,7 +367,7 @@ bool invokeRequired = false; lock (this) { - if (m_state != State.Resolved) + if (m_state == PromiseState.Unresolved) m_handlersChain.AddLast(handler); else invokeRequired = true; diff -r dfa21d507bc5 -r 7ea9363fef6c Implab/PromiseState.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/PromiseState.cs Fri Nov 01 16:03:08 2013 +0400 @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Implab +{ + public enum PromiseState + { + Unresolved, + Resolved, + Cancelled, + Rejected + } +} diff -r dfa21d507bc5 -r 7ea9363fef6c Implab/TaskController.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/TaskController.cs Fri Nov 01 16:03:08 2013 +0400 @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; + +namespace Implab +{ + /// + /// This class allows to interact with asyncronuos task. + /// + /// + /// Members of this object are thread safe. + /// + class TaskController + { + object m_lock; + string m_message; + bool m_cancelled; + + float m_current; + float m_max; + + public event EventHandler> MessageUpdated; + public event EventHandler> ProgressUpdated; + public event EventHandler ProgressInit; + + public TaskController() + { + m_lock = new Object(); + } + + public string Message + { + get + { + lock (m_lock) + return m_message; + } + set + { + lock (m_lock) + { + m_message = value; + OnMessageUpdated(); + } + } + } + + public float CurrentProgress + { + get + { + lock (m_lock) + return m_current; + } + set + { + lock (m_lock) + { + var prev = m_current; + m_current = value; + if (m_current >= m_max) + m_current = m_max; + if (m_current != prev) + OnProgressUpdated(); + } + } + } + + public void InitProgress(float current, float max, string message) + { + if (max < 0) + throw new ArgumentOutOfRangeException("max"); + if (current < 0 || current > max) + throw new ArgumentOutOfRangeException("current"); + + lock(m_lock) { + m_current = current; + m_max = max; + m_message = message; + OnProgressInit(); + } + } + + protected virtual void OnMessageUpdated() + { + var temp = MessageUpdated; + if (temp != null) + { + temp(this, new ValueEventArgs(m_message)); + } + } + + protected virtual void OnProgressUpdated() + { + var temp = ProgressUpdated; + if (temp != null) + { + temp(this,new ValueEventArgs(m_current)); + } + } + + protected virtual void OnProgressInit() + { + var temp = ProgressInit; + if (temp != null) + { + temp(this, new ProgressInitEventArgs(m_current,m_max, m_message)); + } + } + } +} diff -r dfa21d507bc5 -r 7ea9363fef6c Implab/ValueEventArgs.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/ValueEventArgs.cs Fri Nov 01 16:03:08 2013 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Implab +{ + public class ValueEventArgs: EventArgs + { + public ValueEventArgs(T value) + { + this.Value = value; + } + public T Value + { + get; + private set; + } + } +}