public Watch(long milliseconds, bool repeat, IAction onDone, bool run = true, Needle needle = null) { _time = CurrentTime = milliseconds; Repeat = repeat; OnDone = onDone; _updater = new ActionAct(Update); _running = run; // was the needle specified? if (needle == null) { // no, derive the correct needle _needle = _time % 1000 == 0 ? ManagerUpdate.Iterant : ManagerUpdate.Polling; } else { // yes, persist the needle _needleSpecified = true; _needle = needle; } if (_running && _time > 0) { _needle.AddUpdate(_updater); } }
/// <summary> /// Add an action to be called on update using this needle. /// </summary> public override ActionAct AddUpdate(IAction action) { var task = new ActionAct(action, false); _lockB.Take(); _tasks.B.Enqueue(task); _lockB.Release(); return(task); }
//-------------------------------------------// /// <summary> /// Initialize with the timeout time in milliseconds, onComplete(false is timeout) /// getComplete get whether the task is complete. /// </summary> public Timeout(long time, Action <bool> onComplete, Func <bool> getComplete) { OnComplete = onComplete; GetComplete = getComplete; Timer = new Timer(time, OnTimeout); _locker = new Lock(); _updater = new ActionAct(Update); ManagerUpdate.Polling.AddUpdate(_updater); }
/// <summary> /// Return a task if there is one. /// </summary> public override bool Next(out ActionAct task) { // is the current task still running, has the needle been // paused or is the lock already taken? if (_paused || !_current.Ready || !_lock.TryTake) { // yes, return no task task = null; return(false); } // get the next task while (--_taskCount >= 0 && _tasks.Dequeue()) { if (!_tasks.Current.Remove) { _tasks.Enqueue(_tasks.Current); } // should the task be run? if (_tasks.Current.ToRun && _tasks.Current.Ready) { // set the current item task = _current = _tasks.Current; _current.Ready = false; _lock.Release(); return(true); } } // get the number of ticks since the last update _deltaTicks = Time.Timestamp - _lastDeltaTicks; _lastDeltaTicks += _deltaTicks; // no task _lock.Release(); // get the number of tasks to execute next iteration _taskCount = _tasks.Count; task = null; return(false); }
public Timer(long time, Act onDone, bool run = true, Needle needle = null) { Time = time; OnDone = onDone; _updater = new ActionAct(Update); _updater.ToRun = false; // has the needle been specified? if (needle == null) { // no, derive the needle to use _needle = Time % 1000 == 0 ? ManagerUpdate.Iterant : ManagerUpdate.Polling; } else { // yes, persist the needle _needle = needle; } Run = run; }
/// <summary> /// Add an Task to be called in order on this needle. /// </summary> public override void AddUpdate(ActionAct task) { _lockB.Take(); _tasks.B.Enqueue(task); _lockB.Release(); }
/// <summary> /// Return a task if there is one. /// </summary> public override bool Next(out ActionAct task) { // has the needle been paused or is the lock already taken? if (_paused) { // yes, return no task task = null; return(false); } // if currently running if (_running) { // try get the A side lock if (_lockA.TryTake) { var tasks = _tasks.A; // get the next task while (tasks.Next() && !tasks.Loop) { if (tasks.Current.Remove) { tasks.RemoveCurrent(); tasks.Current.Remove = false; } task = tasks.Current; // should the task be run? if (task.ToRun && task.Ready) { _current = task; // set the current item task.Ready = false; _lockA.Release(); return(true); } } if (_flip) { _flip = false; _lockB.Take(); _tasks.Flip(); _lockB.Release(); tasks = _tasks.A; // get the next task while (tasks.Next() && !tasks.Loop) { if (tasks.Current.Remove) { tasks.RemoveCurrent(); tasks.Current.Remove = false; } task = tasks.Current; // should the task be run? if (task.ToRun && task.Ready) { _current = task; // set the current item task.Ready = false; _lockA.Release(); return(true); } } } // return to wait for delta time _running = false; // release the a lock _lockA.Release(); } else { task = null; return(false); } } if (!_lockA.TryTake) { task = null; return(false); } // if delta is greater than target it's time for another loop of tasks if (Time.Timestamp >= _nextTimestamp) { // add the target number of ticks _nextTimestamp = _nextTimestamp + _targetTicks; // this is running _running = true; _flip = true; // log of target ticks vs actual // if(Delta == 1000) { // Log.D(System.Threading.Thread.CurrentThread.Name + " Offset " + (_nextTimestamp - _targetTicks - Time.Timestamp)); // } var tasks = _tasks.A; // get the next task while (tasks.Next() && !tasks.Loop) { if (tasks.Current.Remove) { tasks.RemoveCurrent(); tasks.Current.Remove = false; } task = tasks.Current; // should the task be run? if (task.ToRun && task.Ready) { _current = task; // set the current item task.Ready = false; _lockA.Release(); return(true); } } if (_flip) { _flip = false; _lockB.Take(); _tasks.Flip(); _lockB.Release(); tasks = _tasks.A; // get the next task while (tasks.Next() && !tasks.Loop) { if (tasks.Current.Remove) { tasks.RemoveCurrent(); tasks.Current.Remove = false; } task = tasks.Current; // should the task be run? if (task.ToRun && task.Ready) { _current = task; // set the current item task.Ready = false; _lockA.Release(); return(true); } } } _running = false; } // release the a lock _lockA.Release(); // no task return task = null; return(false); }
//-------------------------------------------// /// <summary> /// Needles manage queues of tasks to be repeatedly executed after a length /// of time. /// </summary> public NeedleElastic(string name, byte priority = 0) : base(name, priority) { _tasks = new SafeQueue <ActionAct>(); _lock = new Lock(); _current = new ActionAct((IRun)null); }
/// <summary> /// Return a task if there is one. /// </summary> public override bool Next(out ActionAct task) { // has the needle been paused? if (_paused) { // yes, return no task task = null; return(false); } // update the delta time if (_lock.TryTake) { Delta = (Time.Timestamp - _lastUpdate) / Time.Frequency; _lastUpdate = Time.Timestamp; _updateCount = 0; // get the next task while (_tasks.Dequeue(out task)) { // updating tasks is much less likely with dynamic needles if (!task.Remove) { // re-enqueue the task _tasks.Enqueue(task); // should the task be run? if (task.ToRun && task.Ready) { // set the current item _lock.Release(); _current = task; task.Ready = false; return(true); } // does the number of update tasks equal the number of remaining // tasks? if (++_updateCount == _tasks.Count) { // yes, return _lock.Release(); return(false); } } // should the task be run? if (task.ToRun && task.Ready) { // set the current item _lock.Release(); _current = task; task.Ready = false; return(true); } } _lock.Release(); } task = null; return(false); }
/// <summary> /// Return a task if there is one. /// </summary> public abstract bool Next(out ActionAct task);
/// <summary> /// Add an Task to be called in order on this needle. /// </summary> public abstract void AddUpdate(ActionAct task);
public Timer(Act onDone) { OnDone = onDone; _updater = new ActionAct(Update); _updater.ToRun = false; }