/// <summary> /// Prüft, ob ein weiterer Zeitpunkt vorliegt. /// </summary> public void MoveNext() { // As long as necessary for (; ;) { // Ask base if (m_Scan != null) { if (!m_Scan.MoveNext()) { m_Scan = null; } } // Report if (m_Scan == null) { break; } // Load what base gives us m_Current = m_Scan.Current; // Load to check - normally we will not change it var planned = m_Current.Planned; // Find exception to apply PlanException exception; if (m_Exceptions.TryGetValue(planned.Start.ToLocalTime().Date, out exception)) { #if !SILVERLIGHT // Report if (RecordingScheduler.SchedulerTrace.TraceVerbose) { Trace.TraceInformation(Properties.SchedulerResources.Trace_Exception, planned.Start, planned.Duration, exception.StartDelta, exception.DurationDelta); } #endif // Change planned = new PlannedTime { Duration = planned.Duration + exception.DurationDelta, Start = planned.Start + exception.StartDelta, }; // Write back m_Current.Planned = planned; } // Found it if (planned.End > m_MinTime) { if (planned.Duration.TotalSeconds > 0) { break; } } } }
/// <summary> /// Erzeugt eine neue Beschreibung. /// </summary> /// <param name="recording">Die zugehörige Aufzeichnung.</param> /// <param name="time">Die vorgesehene Ausführungszeit.</param> /// <param name="startsLate">Gesetzt, wenn die Aufzeichnung verspätet beginnt.</param> public _RecordingItem(IRecordingDefinition recording, PlannedTime time, bool startsLate) { // Remember StartsLate = startsLate; Recording = recording; Time = time; }
/// <summary> /// Erzeugt eine neue Beschreibung. /// </summary> /// <param name="context">Vom Anwender der Schnittstelle zusätzlich bereitgestellte Daten.</param> /// <param name="name">Eine Name zur Identifikation der Aufzeichnung.</param> /// <param name="uniqueIdentifier">Die eindeutige Kennung der Aufzeichnung.</param> /// <param name="resources">Die Liste aller Geräte, die verwendet werden dürfen.</param> /// <param name="source">Die gewünschte Quelle.</param> /// <param name="start">Der Beginn der Aufzeichnung.</param> /// <param name="duration">Die Dauer der Aufzeichnung.</param> public _OneOffItem(UserDataType context, string name, Guid uniqueIdentifier, IScheduleResource[] resources, IScheduleSource source, DateTime start, TimeSpan duration) { // Validate if (source == null) { throw new ArgumentNullException("source"); } if (start.Year < 2000) { throw new ArgumentOutOfRangeException("start", string.Format(Properties.InterfaceResources.Exception_StartYear, start)); } if (duration.TotalSeconds <= 0) { throw new ArgumentOutOfRangeException("duration", string.Format(Properties.InterfaceResources.Exception_Duration, duration)); } if (resources != null) { if (resources.Any(r => r == null)) { throw new ArgumentNullException("resources"); } } // Create compound information m_Plan = new PlannedTime { Start = start, Duration = duration }; // Remember simple information Resources = resources ?? new IScheduleResource[0]; UniqueIdentifier = uniqueIdentifier; Context = context; Source = source; Name = name; }
/// <summary> /// Meldet alle Ausführungszeiten. /// </summary> /// <param name="minTime">Der früheste Ausführungszeitpunkt.</param> /// <returns>Alle möglichen Zeiten.</returns> public IEnumerable <SuggestedPlannedTime> GetTimes(DateTime minTime) { // Process if (Duration.TotalSeconds > 0) { for (var lastRun = LastRun; ; minTime = lastRun.Value) { // Load next var next = GetNextSchedule(lastRun, minTime); if (!next.HasValue) { yield break; } // Create plan SuggestedPlannedTime plan = new PlannedTime { Start = next.Value, Duration = Duration }; // Can always report - will never be smaller than the minimum time yield return(plan); // Advance - please not that we use the eventually modified real schedule time not the one we begged for lastRun = plan.Planned.End; } } }
/// <summary> /// Erzeugt eine neue Beschreibung. /// </summary> /// <param name="definition">Die ursprüngliche Beschreibung der Aufzeichnung.</param> /// <param name="resource">Das zu verwendende Gerät.</param> /// <param name="time">Die tatsächliche Ausführungszeit.</param> /// <param name="late">Gesetzt, wenn die Ausführung verspätet beginnt.</param> internal ScheduleInfo(IScheduleDefinition definition, IScheduleResource resource, PlannedTime time, bool late) { // Remember Definition = definition; Resource = resource; StartsLate = late; Time = time; }
/// <summary> /// Erzeugt eine neue Beschreibung. /// </summary> /// <param name="definition">Die ursprüngliche Beschreibung der Aufzeichnung.</param> /// <param name="resource">Das zu verwendende Gerät.</param> /// <param name="time">Die tatsächliche Ausführungszeit.</param> /// <param name="late">Gesetzt, wenn die Ausführung verspätet beginnt.</param> internal ScheduleInfo( IScheduleDefinition definition, IScheduleResource resource, PlannedTime time, bool late ) { // Remember Definition = definition; Resource = resource; StartsLate = late; Time = time; }
/// <summary> /// Erzeugt eine neue Beschreibung. /// </summary> /// <param name="resource">Das zugehörige Gerät.</param> /// <param name="source">Optional die zu verwendende Quelle.</param> /// <param name="identifier">Die eindeutige Kennung der zugehörigen Aufzeichnung oder Aufgabe.</param> /// <param name="name">Der Name der Aufzeichnung.</param> /// <param name="start">Der Startzeitpunkt.</param> /// <param name="duration">Die Dauer der Aufzeichnung.</param> /// <exception cref="ArgumentOutOfRangeException">Die Dauer der Aufzeichnung ist negativ.</exception> public ResourceAllocationInformation( IScheduleResource resource, IScheduleSource source, Guid identifier, string name, DateTime start, TimeSpan duration ) { // Validate if (duration.TotalSeconds <= 0) throw new ArgumentOutOfRangeException( "duration" ); // Remember all Time = new PlannedTime { Start = start, Duration = duration }; Resources = new[] { resource }; UniqueIdentifier = identifier; Source = source; Name = name; }
/// <summary> /// Meldet alle geplanten Aufzeichnungszeiten. /// </summary> /// <param name="minTime">Aufzeichnunge, die vor diesem Zeitpunkt enden, brauchen nicht in /// der Auflistung zu erscheinen. Es handelt sich um eine optionale Optimierung.</param> /// <returns>Eine Liste aller geplanten Zeiten.</returns> public override IEnumerable <SuggestedPlannedTime> GetTimes(DateTime minTime) { // Get the recording time var next = Plan.Start; // Adjust a bit to avoid race conditions if (next < minTime) { next = minTime.ToLocalTime().Date.AddDays(-2) + next.ToLocalTime().TimeOfDay; } else { next = next.ToLocalTime(); } // Process for (; ; next = next.AddDays(1)) { // Adjust until day is valid while (!m_Pattern.Contains(next.DayOfWeek)) { next = next.AddDays(1); } // Done if end is reached if (next.Date > m_End) { yield break; } // Create plan var planned = new PlannedTime { Start = next.ToUniversalTime(), Duration = Plan.Duration }; // Report if limit reached if (planned.End > minTime) { yield return(planned); } } }
/// <summary> /// Korrigiert einen Abruf einer Entschlüsselung. /// </summary> /// <param name="allocationIndex">Die laufende Nummer des zu belegenden Eintrags.</param> /// <param name="source">Die zu verwendende Quelle.</param> /// <param name="time">Der Zeitraum, in dem eine Entschlüsselung aktiv ist.</param> private void Allocate(int allocationIndex, IScheduleSource source, ref PlannedTime time) { // Reset all caches - just in case... m_cachedResourceStartTimes = null; m_sourceUsage = null; // We are now using the source if (!m_Sources.Any(s => s.IsSameAs(source))) { m_Sources.Add(source); } // Localize time - can not use ref parameters inside a delegate var timeCopy = time; // Find the one the prepare analysis gave us - no further tests will be made! var allocation = m_Allocations[allocationIndex]; // See if we have to clip if (time.Start < allocation.Start) { // Do the clip time.Duration = time.End - allocation.Start; time.Start = allocation.Start; } // Correct it all for (; ;) { // On change we must create a clone var allocationIsPrivate = false; // Create a new starter if (time.Start > allocation.Start) { // Create a new allocation entry var split = allocation.Clone(allocation.Start, time.Start); // Add it just in front of the current one m_Allocations.Insert(allocationIndex++, split); // Must create a brand new one allocation = allocation.Clone(time.Start, allocation.End); // Update in our private list m_Allocations[allocationIndex] = allocation; // We can now safely overwrite it allocationIsPrivate = true; } // Create a new trailer if (time.End < allocation.End) { // Create a new allocation entry var split = allocation.Clone(time.End, allocation.End); // Add it just behind the current one m_Allocations.Insert(allocationIndex + 1, split); // Update the allocation if (allocationIsPrivate) { // We are allowed to change it allocation.End = time.End; } else { // Must create a brand new one allocation = allocation.Clone(allocation.Start, time.End); // Update in our private list m_Allocations[allocationIndex] = allocation; // We are now allowed to write to it allocationIsPrivate = true; } } // Update the allocation if (allocationIsPrivate) { // Just count down allocation.Allocate(source); } else { // Must create a brand new one allocation = allocation.Clone(allocation.Start, allocation.End); // Correct allocation.Allocate(source); // Update in our private list m_Allocations[allocationIndex] = allocation; } // See if we are done if (time.End <= allocation.End) { break; } // Load the next allocation area allocation = m_Allocations[++allocationIndex]; } }
/// <summary> /// Prüft, ob dieser Zeitbereich mit einer geplanten Aufzeichnung überlappt. /// </summary> /// <param name="time">Der Zeitraum der Aufzeichnung.</param> /// <returns>Gesetzt, wenn eine Überlappung vorliegt.</returns> public bool Overlaps(PlannedTime time) { // Just rest return((time.Start < End) && (time.End > Start)); }
/// <summary> /// Prüft, ob ein weiterer Zeitpunkt vorliegt. /// </summary> public void MoveNext() { // As long as necessary for (; ; ) { // Ask base if (m_Scan != null) if (!m_Scan.MoveNext()) m_Scan = null; // Report if (m_Scan == null) break; // Load what base gives us m_Current = m_Scan.Current; // Load to check - normally we will not change it var planned = m_Current.Planned; // Find exception to apply PlanException exception; if (m_Exceptions.TryGetValue( planned.Start.ToLocalTime().Date, out exception )) { #if !SILVERLIGHT // Report if (RecordingScheduler.SchedulerTrace.TraceVerbose) Trace.TraceInformation( Properties.SchedulerResources.Trace_Exception, planned.Start, planned.Duration, exception.StartDelta, exception.DurationDelta ); #endif // Change planned = new PlannedTime { Duration = planned.Duration + exception.DurationDelta, Start = planned.Start + exception.StartDelta, }; // Write back m_Current.Planned = planned; } // Found it if (planned.End > m_MinTime) if (planned.Duration.TotalSeconds > 0) break; } }
/// <summary> /// Meldet alle Ausführungszeiten. /// </summary> /// <param name="minTime">Der früheste Ausführungszeitpunkt.</param> /// <returns>Alle möglichen Zeiten.</returns> public IEnumerable<SuggestedPlannedTime> GetTimes( DateTime minTime ) { // Process if (Duration.TotalSeconds > 0) for (var lastRun = LastRun; ; minTime = lastRun.Value) { // Load next var next = GetNextSchedule( lastRun, minTime ); if (!next.HasValue) yield break; // Create plan SuggestedPlannedTime plan = new PlannedTime { Start = next.Value, Duration = Duration }; // Can always report - will never be smaller than the minimum time yield return plan; // Advance - please not that we use the eventually modified real schedule time not the one we begged for lastRun = plan.Planned.End; } }