/// <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 }
/// <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; }
/// <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); }
/// <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); }
/// <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)); }
/// <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)); }