/// <summary>Finds the index of the <see cref="IRingEntry" /> which should be played at the specified <paramref name="time" />.</summary> /// <param name="ring">The target <see cref="IRing" /></param> /// <param name="ringItems">The sorted array of the ring items.</param> /// <param name="time"> /// The time where you want to gather the playing <see cref="IRingEntry" />. If <paramref name="time" /> equals null /// <see cref="DateTime.Now" /> will be used. /// </param> public static RingEntrySpecification <TItem> Find_Item_At_Time <TItem>(this IRing <TItem> ring, TItem[] ringItems, DateTime?time = null) where TItem : IRingEntry { if (ring == null) { throw RingEngineException_InvalidArgument.NullOrEmpty(nameof(ring)); } RingEngineException_InvalidRing.ThrowIfInvalid(ring); if (time == null) { time = DateTime.Now; } var ringStart = ring.Find_LastRingStart(time); // The current position in the ring in ticks var searchedTickInRing = (time.Value - ringStart).Ticks; for (var i = 0; i < ringItems.Length; i++) { var item = ringItems[i]; if (item.RingEntryStartTime.Ticks < searchedTickInRing) { continue; } int itemIndex; if (i == 0) { itemIndex = ringItems.Length - 1; } else { itemIndex = i - 1; } return(new RingEntrySpecification <TItem>(ringStart, ringItems[itemIndex], itemIndex)); } return(new RingEntrySpecification <TItem>(ringStart, ringItems[0], 0)); }
/// <summary> /// Finds the time when the <see cref="IRingEntry" /> with the specified <paramref name="index" /> will be played next time after /// the speciefied <paramref name="time" />. /// </summary> /// <param name="ring">The ring</param> /// <param name="ringItems">The sorted array of the ring items.</param> /// <param name="index">The index of the <see cref="IRingEntry" /> inside the <paramref name="ring" />.</param> /// <param name="time">The time after which the time is searched.</param> public static DateTime Find_Time_At_NextPlay <TItem>(this IRing <TItem> ring, TItem[] ringItems, int index, DateTime?time = null) where TItem : IRingEntry { if (ring == null) { throw RingEngineException_InvalidArgument.NullOrEmpty(nameof(ring)); } if (index < 0) { throw RingEngineException_InvalidArgument.SmallerThenZero(nameof(index), index); } if (index >= ringItems.Length) { throw RingEngineException_InvalidArgument.OutOfRange(nameof(index), index, ringItems.Length - 1); } RingEngineException_InvalidRing.ThrowIfInvalid(ring); if (time == null) { time = DateTime.Now; } var ringStart = ring.Find_LastRingStart(time); var item = ringItems[index]; var result = ringStart.Add(item.RingEntryStartTime); if (result >= time) // if the resulting value is in the future return { return(result); } //Otherwise take next ring start and then add start time. return(ringStart.Add(ring.RingPeriod).Add(item.RingEntryStartTime)); }