view Implab/TaskController.cs @ 14:e943453e5039 promises

Implemented interllocked queue fixed promise syncronization
author cin
date Wed, 06 Nov 2013 17:49:12 +0400
parents eb418ba8275b
children 9bf5b23650c9
line wrap: on
line source

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Implab
{
    /// <summary>
    /// This class allows to interact with asyncronuos task.
    /// </summary>
    /// <remarks>
    /// Members of this object are thread safe.
    /// </remarks>
    class TaskController: IProgressNotifier, ITaskController, ICancellable
    {
        readonly object m_lock;
        string m_message;

        float m_current;
        float m_max;

        bool m_cancelled;

        public event EventHandler<ValueEventArgs<string>> MessageUpdated;
        public event EventHandler<ValueEventArgs<float>> ProgressUpdated;
        public event EventHandler<ProgressInitEventArgs> 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();
            }
        }

        public bool Cancelled {
            get {
                lock (m_lock)
                    return m_cancelled;
            }
        }

        public bool Cancel() {
            lock (m_lock) {
                if (!m_cancelled) {
                    m_cancelled = true;
                    return true;
                } else {
                    return false;
                }
            }
        }

        protected virtual void OnMessageUpdated()
        {
            var temp = MessageUpdated;
            if (temp != null)
            {
                temp(this, new ValueEventArgs<string>(m_message));
            }
        }

        protected virtual void OnProgressUpdated()
        {
            var temp = ProgressUpdated;
            if (temp != null)
            {
                temp(this,new ValueEventArgs<float>(m_current));
            }
        }

        protected virtual void OnProgressInit()
        {
            var temp = ProgressInit;
            if (temp != null)
            {
                temp(this, new ProgressInitEventArgs(m_current,m_max, m_message));
            }
        }
    }
}