/// <summary>
        /// Return meetings loaded from the internet. We will continue sending them if the meeting
        /// is currently running (e.g. doing constant updates).
        /// </summary>
        /// <param name="meeting"></param>
        /// <returns>Stream of meetings</returns>
        /// <remarks>
        /// The algorithm for this:
        /// 1. Always fetch the meeting at least one time.
        /// 2. If we are in the outer buffer region, check once an hour
        /// 3. If we are in the inner buffer region, then check every 5 minutes.
        ///
        /// Inner buffer region: meeting start and end times, with 30 minutes before the meeting, and 2 hours after the meeting.
        /// Outer buffer region: 1 day before the meeting to 1 day after the meeting.
        /// </remarks>
        private IObservable <IMeeting> MeetingLoader(IMeetingRef meeting)
        {
            // Grab a copy of the meeting online.
            var firstMeeting = Observable.FromAsync(() => meeting.GetMeeting())
                               .Catch(Observable.Empty <IMeeting>())
                               .Publish();

            // Determine the two buffer times for this meeting, and create a "pulse" that will
            // fire at the required intervals during those buffered times.
            var laterUpdates = firstMeeting
                               .SelectMany(m =>
            {
                var bufInner  = new TimePeriod(m.StartTime - TimeSpan.FromMinutes(30), m.EndTime + TimeSpan.FromHours(2));
                var bufOutter = new TimePeriod(m.StartTime - TimeSpan.FromDays(1), m.EndTime + TimeSpan.FromDays(1));

                IObservable <Unit> reloadPulse;
                if (!bufOutter.Contains(DateTime.Now))
                {
                    // This meeting is way late or way early.
                    // Don't waste any time doing the loading.
                    reloadPulse = Observable.Empty <Unit>();
                    Debug.WriteLine("Not triggering re-fetches for the meeting");
                }
                else
                {
                    // We do both inner and outer so that if someone leaves this up for a long
                    // time it will work will.
                    var outter = Observable.Timer(TimeSpan.FromMinutes(30))
                                 .Where(_ => bufOutter.Contains(DateTime.Now))
                                 .WriteLine("Getting meeting in outer buffer")
                                 .Select(_ => default(Unit));
                    var inner = Observable.Timer(TimeSpan.FromMinutes(5))
                                .Where(_ => bufInner.Contains(DateTime.Now))
                                .WriteLine("Getting meeting in inner buffer")
                                .Select(_ => default(Unit));
                    reloadPulse = Observable.Merge(outter, inner);
                }

                // Now, use it to trigger the meetings.
                return(reloadPulse
                       .SelectMany(_ => Observable.FromAsync(() => meeting.GetMeeting()).Catch(Observable.Empty <IMeeting>())));
            });

            var meetingSequence = Observable.Merge(firstMeeting, laterUpdates);

            // TODO: why do we need this firstMeeting a published observable?
            firstMeeting.Connect();
            return(meetingSequence);
        }
        /// <summary>
        /// Setup the VM for the file.
        /// </summary>
        /// <param name="downloader">The download controller. This assumes this is for a PDF file, and it is Valid.</param>
        /// <param name="talkTime">The time that this guy is relevant</param>
        public FileSlideListViewModel(PDFFile pdfFile, TimePeriod talkTime)
        {
            // Get the object consistent.
            SlideThumbnails = new ReactiveList <SlideThumbViewModel>();

            // We will want to refresh the view of this file depending on how close we are to the actual
            // meeting time.

            var innerBuffer = new TimePeriod(talkTime);

            innerBuffer.StartTime -= TimeSpan.FromMinutes(30);
            innerBuffer.EndTime   += TimeSpan.FromHours(2);

            var updateTalkFile = Observable.Empty <Unit>();

            if (innerBuffer.Contains(DateTime.Now))
            {
                // Fire every 15 minutes, but only while in the proper time.
                // We only check when requested, so we will start right off the bat.
                updateTalkFile = Observable.Return(default(Unit))
                                 .Concat(Observable.Interval(TimeSpan.FromMinutes(15))
                                         .Where(_ => innerBuffer.Contains(DateTime.Now))
                                         .Select(_ => default(Unit))
                                         )
                                 .Where(_ => Settings.AutoDownloadNewMeeting);
            }

            // A view model to show the whole thing as a strip view.
            var fullVM = new Lazy <FullTalkAsStripViewModel>(() => new FullTalkAsStripViewModel(Locator.Current.GetService <IScreen>(), pdfFile));

            // All we do is sit and watch for the # of pages to change, and when it does, we fix up the list of SlideThumbViewModel.
            var newSlideInfo = from nPages in pdfFile.WhenAny(x => x.NumberOfPages, x => x.Value).DistinctUntilChanged()
                               from newSlides in CreateNewThumbs(nPages, pdfFile, fullVM)
                               select new
            {
                n      = nPages,
                slides = newSlides
            };

            newSlideInfo
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(info => SetNumberOfThumbNails(info.n, info.slides));
        }
    static void Main(string[] args)
    {
        var period = new TimePeriod(
            DateTime.Now.AddDays(-2),
            DateTime.Now.AddDays(1));
        var date     = DateTime.Now;
        var contains = period.Contains(date);                 // true
        var isBefore = period.IsBefore(date);                 // false
        var isAfter  = period.IsAfter(date);                  // false

        date     = DateTime.Now.AddDays(-10);
        contains = period.Contains(date);                 // false
        isBefore = period.IsBefore(date);                 // true
        isAfter  = period.IsAfter(date);                  // false
        date     = DateTime.Now.AddDays(10);
        contains = period.Contains(date);                 // false
        isBefore = period.IsBefore(date);                 // false
        isAfter  = period.IsAfter(date);                  // true
    }
Пример #4
0
        /// <summary>
        /// 移除
        /// </summary>
        /// <param name="prn"></param>
        /// <param name="epochs"></param>
        public void Remove(SatelliteType prn, TimePeriod epochs)
        {
            foreach (var item in this._data)
            {
                if (!epochs.Contains(item.ReceiverTime))
                {
                    continue;
                }

                item.Remove(prn);
            }
            IsChanged = true;
        }
Пример #5
0
 /// <summary>
 /// 从时段和系统类型判断是否支持
 /// </summary>
 /// <param name="satType"></param>
 /// <param name="satTime"></param>
 /// <returns></returns>
 public bool IsAvailable(List <SatelliteType> satType, Time satTime)
 {
     if (!TimePeriod.Contains(satTime))
     {
         return(false);
     }
     foreach (var item in satType)
     {
         if (!SatelliteTypes.Contains(item))
         {
             return(false);
         }
     }
     return(true);
 }
Пример #6
0
        /// <summary>
        /// 返回一个距离历元最近的结果。
        /// </summary>
        /// <param name="prn"></param>
        /// <param name="epoch">需要精确的时刻</param>
        /// <returns></returns>
        public double Get(SatelliteNumber prn, Time epoch)
        {
            if (Data != null)
            {
                if (Data.ContainsKeyBA(prn.ToString(), epoch))
                {
                    return(Data[epoch, prn.ToString()]);
                }

                if (!Data.ContainsKeyB(prn.ToString()))
                {
                    return(0);
                }

                if (!TimePeriod.Contains(epoch))
                {
                    return(0);
                }

                var vals = Data.GetValuesByKeyB(prn.ToString());

                //获取最近几个
                var dic = Geo.Utils.DoubleUtil.GetNearst(vals, m => m.SecondsOfWeek, epoch, FitCount);
                if (IsAverageOrFit)
                {
                    var ave = dic.Values.Average();
                    return(ave);
                }
                else
                {
                    LsPolyFit fit = new LsPolyFit(2);
                    fit.InitAndFitParams <Time>(dic, m => m.SecondsOfWeek);
                    var y = fit.GetY(epoch.SecondsOfWeek);
                    return(y);
                }
            }
            return(0);
        }
Пример #7
0
 /// <summary>
 /// 从时段和系统类型判断是否支持
 /// </summary>
 /// <param name="satType"></param>
 /// <param name="satTime"></param>
 /// <returns></returns>
 public bool IsAvailable(SatelliteType satType, Time satTime)
 {
     return((SatelliteTypes.Contains(satType)) && TimePeriod.Contains(satTime));
 }
Пример #8
0
 /// <summary>
 /// 是否包含指定系统和时间。
 /// </summary>
 /// <param name="prn"></param>
 /// <param name="time"></param>
 /// <returns></returns>
 public bool Contains(SatelliteNumber prn, Time time)
 {
     return(TimePeriod.Contains(time) && SatelliteTypes.Contains(prn.SatelliteType));
 }