public void ScheduleEntity(T entity, TimeSpan period) { var entry = new SchedulerEntry(entity, (long)period.TotalMilliseconds, _timerCallback, Volatile.Read(ref _isStarted) == 1, _timerFactory); var added = _entries.TryAdd(entity, entry); Debug.Assert(added); }
/// <summary> /// Registers a delegate to be called in a given number of ticks. /// </summary> /// <param name="callback">The delegate to be called</param> /// <param name="dueInTicks">The delay in ticks before the delegate is called</param> /// <param name="owner">Optional owner of the delegate. Callback will not fire if the Thing is not spawned at call time.</param> /// <param name="repeat">If true, the callback will be rescheduled after each call until manually unscheduled</param> public void ScheduleCallback(Action callback, int dueInTicks, Thing owner = null, bool repeat = false) { if (lastProcessedTick < 0) { throw new Exception("Adding callback to not initialized TickDelayScheduler"); } if (callback == null) { throw new NullReferenceException("callback cannot be null"); } if (dueInTicks < 0) { throw new Exception("invalid dueInTicks value: " + dueInTicks); } if (dueInTicks == 0 && repeat) { throw new Exception("Cannot schedule repeating callback with 0 delay"); } var entry = new SchedulerEntry(callback, dueInTicks, owner, lastProcessedTick + dueInTicks, repeat); if (dueInTicks == 0) { DoCallback(entry); } else { ScheduleEntry(entry); } }
public void Update() { if (Count != 0) { int count = Count; int i = 0; using (new KProfiler.Region("Scheduler.Update", null)) { float time = clock.GetTime(); if (previousTime != time) { previousTime = time; for (; i < count; i++) { if (!(time >= entries.Peek().Key)) { break; } SchedulerEntry value = entries.Dequeue().Value; if (value.callback != null) { value.callback(value.callbackData); } } } } } }
private void CancelCurrentUpdate() { lock (this) { if (_cancalTokenSource != null) { _cancalTokenSource.Cancel(); _cancalTokenSource = null; } _nextScheduledRuntime = default(DateTime); _nextEntry = null; } }
public SchedulerEntry GetNextEvent() { SchedulerEntry nextEvent = null; try { foreach (var entry in SchedulerEvents) { DayOfWeek day = DayOfWeek.Sunday; var alldays = entry.Day.ToLower() == "all"; if (!alldays) { day = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), entry.Day, true); } bool isNegative = entry.Offset.StartsWith("-"); string format = isNegative ? "\\-hh\\:mm" : "\\+hh\\:mm"; TimeSpanStyles tss = isNegative ? TimeSpanStyles.AssumeNegative : TimeSpanStyles.None; var offset = TimeSpan.ParseExact(entry.Offset, format, CultureInfo.InvariantCulture, tss); var time = DateTime.ParseExact(entry.Time, "HH:mm:ss", CultureInfo.InvariantCulture); entry.EventTime = new DateTimeOffset(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, time.Hour, time.Minute, time.Second, offset); entry.EventTime = entry.EventTime.AddDays(-2); while (DateTimeOffset.UtcNow > entry.EventTime.UtcDateTime || (!alldays && entry.EventTime.DayOfWeek != day)) { entry.EventTime = entry.EventTime.AddDays(1); } } nextEvent = SchedulerEvents.OrderBy(x => x.EventTime - DateTimeOffset.Now).FirstOrDefault(); } catch (Exception ex) { if (ScheduledNotificationsTaskCTS != null) { ScheduledNotificationsTaskCTS.Cancel(); } NextEvent = null; SchedulerEvents = null; Model.ScheduledNotificationsFile = string.Empty; MessageBox.Show("Invalid scheduled events file."); Log.Message(ex.ToString()); } return(nextEvent); }
private bool DoCallback(SchedulerEntry entry) { if (entry.owner == null || entry.owner.Spawned) { try { entry.callback(); return(true); } catch (Exception e) { HugsLibController.Logger.Error("TickDelayScheduler caught an exception while calling {0} registered by {1}: {2}", HugsLibUtility.DescribeDelegate(entry.callback), entry.owner == null ? "[null]" : entry.owner.ToString(), e); } } return(false); }
// inserts the new entry, maintaining the list sorted in ascending order private void ScheduleEntry(SchedulerEntry newEntry) { // iterate tail-first for best performance when reinserting var lastEntry = entries.Last; while (lastEntry != null) { if (lastEntry.Value.dueAtTick <= newEntry.dueAtTick) { entries.AddAfter(lastEntry, newEntry); return; } lastEntry = lastEntry.Previous; } // on empty list entries.AddFirst(newEntry); }
private void LoadSchedulerEvents() { try { var file = Model.ScheduledNotificationsFile; if (!Path.IsPathRooted(file)) { var folder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); file = Path.Combine(folder, file); } if (!File.Exists(file)) { return; } SchedulerEvents = File.ReadAllLines(file) .Skip(1) .Select(csvLine => { var vals = csvLine.Split(','); var entry = new SchedulerEntry(); entry.Day = vals[0]; entry.Time = vals[1]; entry.Offset = vals[2]; entry.Message = vals[3]; entry.ColorId = Int32.Parse(vals[4]); return(entry); }) .ToList(); } catch (Exception ex) { if (ScheduledNotificationsTaskCTS != null) { ScheduledNotificationsTaskCTS.Cancel(); } NextEvent = null; SchedulerEvents = null; Model.ScheduledNotificationsFile = string.Empty; MessageBox.Show("Invalid scheduled events file."); Log.Message(ex.ToString()); } }
public void ExecuteNextEvent() { if (SchedulerEvents == null) { return; } ScheduledNotificationsTaskCTS = new CancellationTokenSource(); ScheduledNotificationsTask = Task.Factory.StartNew(async() => { NextEvent = GetNextEvent(); if (NextEvent == null) { return; } var delay = NextEvent.EventTime - DateTimeOffset.Now; await Task.Delay(delay, ScheduledNotificationsTaskCTS.Token); ProcessNewMessage(string.Empty, NextEvent.Message, NextEvent.ColorId); await Task.Delay(1000, ScheduledNotificationsTaskCTS.Token); ExecuteNextEvent(); }, ScheduledNotificationsTaskCTS.Token); }
// It's recommended to pass member function rather than anonymous functions, since it's easier to find the culprit when an exception occurs. public void ScheduleCallback(Action callback, int dueInTicks, bool repeat = false) { if (lastProcessedTick < 0) { throw new Exception("Adding callback to not initialized CallbackScheduler"); } if (callback == null) { throw new NullReferenceException("callback cannot be null"); } if (dueInTicks < 0) { throw new Exception("invalid dueInTicks value: " + dueInTicks); } if (dueInTicks == 0) { DoCallback(callback); } else { var entry = new SchedulerEntry(callback, dueInTicks, lastProcessedTick + dueInTicks, repeat); ScheduleEntry(entry); } }
public void Update() { string newText = FriendlyDateStrings.GetString(this.Date); this.NextUpdate = FriendlyDateStrings.GetNextUpdateTime(this.Date); _text = newText; if (_textBlock != null) { if (newText != _textBlock.Text) { _textBlock.Text = newText; InvalidateMeasure(); InvalidateArrange(); } } _currentEntry = _sched.Add(this.NextUpdate, new Action(() => { IAsyncAction i = this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, Update); })); }
private SchedulerHandle Schedule(string name, float time, float time_interval, Action <object> callback, object callback_data, GameObject profiler_obj) { SchedulerEntry entry = new SchedulerEntry(name, time + clock.GetTime(), time_interval, callback, callback_data, profiler_obj); return(Schedule(entry)); }
private SchedulerHandle Schedule(SchedulerEntry entry) { entries.Enqueue(entry.time, entry); return(new SchedulerHandle(this, entry)); }
public SchedulerHandle(Scheduler scheduler, SchedulerEntry entry) { this.entry = entry; this.scheduler = scheduler; }
private void Scheduler_ActionException(Scheduler scheduler, SchedulerEntry schedulerEntry, Exception e) { HandleSynchronousException((ScriptComponent)schedulerEntry.Token, e); }
public void ModelChanged(object sender, PropertyChangedEventArgs e) { if (!IsInitialized) { return; } lock (m_ConfigurationLock) SaveConfiguration(SelectedProfile.Name, Model, Commands); if (e.PropertyName == nameof(Model)) { foreach (var cmd in CommandIdToTaskCancellation) { cmd.Value.Cancel(); } CommandIdToTaskCancellation.Clear(); } if (e.PropertyName == nameof(Model.AutoDelete) || e.PropertyName == nameof(Model)) { lock (m_OSDLock) { if (AutoDeleteCTS != null) { AutoDeleteCTS.Cancel(); } m_OSDMessages.Clear(); RefreshOSD(); AutoDeleteCTS = new CancellationTokenSource(); } } if (e.PropertyName == nameof(Model.MaxMessages)) { lock (m_OSDLock) { while ((Model.MaxMessages > 0 && m_OSDMessages.Count > Model.MaxMessages) || m_OSDMessages.Count > 100) { m_OSDMessages.RemoveAt(0); } RefreshOSD(); } } if (e.PropertyName == nameof(Model.ScheduledNotificationsFile) || e.PropertyName == nameof(Model.IsScheduledNotificationsEnabled) || e.PropertyName == nameof(Model)) { if (ScheduledNotificationsTaskCTS != null) { ScheduledNotificationsTaskCTS.Cancel(); } NextEvent = null; SchedulerEvents = null; if (Model.IsScheduledNotificationsEnabled && !string.IsNullOrEmpty(Model.ScheduledNotificationsFile)) { LoadSchedulerEvents(); ExecuteNextEvent(); } } if (e.PropertyName == nameof(Model.User) || e.PropertyName == nameof(Model.Room) || e.PropertyName == nameof(Model)) { lock (m_ConnectionLock) m_Client.Disconnect(); } }
private void InternalRegister(ApproximateDateBlock dateBlock) { lock (this) { CancelCurrentUpdate(); SchedulerEntry schedulerEntry = new SchedulerEntry(dateBlock); schedulerEntry.DateUpdated += OnDateUpdated; _set.Add(schedulerEntry.CachedNextUpdate, schedulerEntry); _lookupDict.Add(dateBlock, schedulerEntry); ScheduleNextUpdate(); } }