Exemplo n.º 1
0
        /// <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));
        }
Exemplo n.º 2
0
        /// <summary>Calculates the last time the <see cref="IRing" /> was restarted.</summary>
        /// <param name="ring">The target <see cref="IRing" />.</param>
        /// <param name="time">The reference time. Could be datetime now.</param>
        public static DateTime Find_LastRingStart <TItem>(this IRing <TItem> ring, 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;
            }


            //Contains the ticks which are past since the last ring start.
            var ticksSinceLastStart = (time.Value - ring.RingStartTime).Ticks % ring.RingPeriod.Ticks;
            var ringStart           = new DateTime(time.Value.Ticks - ticksSinceLastStart);

            return(ringStart);
        }
Exemplo n.º 3
0
        /// <summary>Increases the specified <paramref name="index" /> by the <paramref name="value" /> keeping <see cref="IRing" /> metrics.</summary>
        internal static int IncreaseIndexBy <TItem>(this IRing <TItem> ring, TItem[] ringItems, int index, int value) where TItem : IRingEntry
        {
            if (value < 0)
            {
                throw RingEngineException_InvalidArgument.SmallerThenZero(nameof(value), value);
            }
            if (index < 0)
            {
                throw RingEngineException_InvalidArgument.SmallerThenZero(nameof(index), index);
            }
            if (ring == null)
            {
                throw RingEngineException_InvalidArgument.NullOrEmpty(nameof(ring));
            }
            if (index >= ringItems.Length)
            {
                throw RingEngineException_InvalidArgument.OutOfRange(nameof(index), index, ringItems.Length - 1);
            }

            RingEngineException_InvalidRing.ThrowIfInvalid(ring);

            if (value == 0)
            {
                return(index);
            }

            value = value % ringItems.Length;             // if the number is greater then the ring itself.

            var result = index + value;

            if (result < ringItems.Length)
            {
                return(result);
            }

            //result is greather then the ring length
            result = result - ringItems.Length;             // if it is exactly the length take the first element and so on.
            return(result);
        }
Exemplo n.º 4
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));
        }