Ejemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CommonReactiveSource{TSource, TUIView, TUIViewCell, TSectionInfo}"/> class.
        /// </summary>
        /// <param name="adapter">The adapter to use which we want to display information for.</param>
        public CommonReactiveSource(IUICollViewAdapter <TUIView, TUIViewCell> adapter)
        {
            _adapter               = adapter;
            _mainThreadId          = Thread.CurrentThread.ManagedThreadId;
            _mainDisposables       = new CompositeDisposable();
            _sectionInfoDisposable = new SerialDisposable();
            _mainDisposables.Add(_sectionInfoDisposable);
            _pendingChanges = new List <Tuple <int, PendingChange> >();
            _sectionInfo    = Array.Empty <TSectionInfo>();

            _mainDisposables.Add(
                this
                .ObservableForProperty(
                    x => x.SectionInfo,
                    beforeChange: true,
                    skipInitial: true)
                .Subscribe(
                    _ => SectionInfoChanging(),
                    ex => this.Log().ErrorException("Error occurred whilst SectionInfo changing.", ex)));

            _mainDisposables.Add(
                this
                .WhenAnyValue(x => x.SectionInfo)
                .Subscribe(
                    SectionInfoChanged,
                    ex => this.Log().ErrorException("Error occurred when SectionInfo changed.", ex)));
        }
Ejemplo n.º 2
0
        public CommonReactiveSource(IUICollViewAdapter <TUIView, TUIViewCell> adapter)
        {
            this.adapter = adapter;

            mainDisp.Add(setupDisp);

            mainDisp.Add(this
                         .WhenAnyValue(x => x.SectionInfo)
                         .ObserveOn(RxApp.MainThreadScheduler)
                         .Subscribe(resetup, exc => this.Log().ErrorException("Error while watching for SectionInfo.", exc)));
        }
Ejemplo n.º 3
0
        public CommonReactiveSource(IUICollViewAdapter <TUIView, TUIViewCell> adapter)
        {
            this.adapter = adapter;

            mainDisp.Add(setupDisp);
            mainDisp.Add(this
                         .ObservableForProperty(
                             x => x.SectionInfo,
                             true /* beforeChange */,
                             true /* skipInitial */)
                         .Subscribe(
                             _ => unsetupAll(),
                             ex => this.Log().ErrorException("Error while SectionInfo was changing.", ex)));

            mainDisp.Add(this
                         .WhenAnyValue(x => x.SectionInfo)
                         .Subscribe(resetupAll, ex => this.Log().ErrorException("Error while watching for SectionInfo.", ex)));
        }
Ejemplo n.º 4
0
        public CommonReactiveSource(IUICollViewAdapter <TUIView, TUIViewCell> adapter)
        {
            this.adapter = adapter;
            this.sectionSubscriptions = new Dictionary <TSectionInfo, IDisposable>();
            this.pendingChanges       = new List <Tuple <int, NotifyCollectionChangedEventArgs> >();

            mainDisp.Add(setupDisp);
            mainDisp.Add(this
                         .ObservableForProperty(
                             x => x.SectionInfo,
                             true /* beforeChange */,
                             true /* skipInitial */)
                         .Subscribe(
                             _ => DetachFromSectionInfo(),
                             ex => this.Log().ErrorException("Error while SectionInfo was changing.", ex)));

            mainDisp.Add(this
                         .WhenAnyValue(x => x.SectionInfo)
                         .Subscribe(AttachToSectionInfo, ex => this.Log().ErrorException("Error while watching for SectionInfo.", ex)));
        }
Ejemplo n.º 5
0
        public CommonReactiveSource(
            IUICollViewAdapter <TUIView, TUIViewCell> adapter,
            IEnumerable <ISectionInformation <TUIView, TUIViewCell> > sectionInfo)
        {
            this.adapter     = adapter;
            this.sectionInfo = sectionInfo.ToList();

            for (int i = 0; i < this.sectionInfo.Count; i++)
            {
                var current = this.sectionInfo[i].Collection;

                var section = i;
                var disp    = current.Changed.Buffer(TimeSpan.FromMilliseconds(250), RxApp.MainThreadScheduler).Subscribe(xs => {
                    if (xs.Count == 0)
                    {
                        return;
                    }

                    var resetOnlyNotification = new [] { new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset) };

                    this.Log().Info("Changed contents: [{0}]", String.Join(",", xs.Select(x => x.Action.ToString())));
                    if (xs.Any(x => x.Action == NotifyCollectionChangedAction.Reset))
                    {
                        this.Log().Info("About to call ReloadData");
                        adapter.ReloadData();
                        didPerformUpdates.OnNext(resetOnlyNotification);
                        return;
                    }

                    var updates           = xs.Select(ea => Tuple.Create(ea, getChangedIndexes(ea))).ToList();
                    var allChangedIndexes = updates.SelectMany(u => u.Item2).ToList();
                    // Detect if we're changing the same cell more than
                    // once - if so, issue a reset and be done
                    if (allChangedIndexes.Count != allChangedIndexes.Distinct().Count())
                    {
                        this.Log().Info("Detected a dupe in the changelist. Issuing Reset");
                        adapter.ReloadData();
                        didPerformUpdates.OnNext(resetOnlyNotification);
                        return;
                    }

                    this.Log().Info("Beginning update");
                    adapter.PerformBatchUpdates(() => {
                        foreach (var update in updates.AsEnumerable().Reverse())
                        {
                            var changeAction   = update.Item1.Action;
                            var changedIndexes = update.Item2;
                            switch (changeAction)
                            {
                            case NotifyCollectionChangedAction.Add:
                                doUpdate(adapter.InsertItems, changedIndexes, section);
                                break;

                            case NotifyCollectionChangedAction.Remove:
                                doUpdate(adapter.DeleteItems, changedIndexes, section);
                                break;

                            case NotifyCollectionChangedAction.Replace:
                                doUpdate(adapter.ReloadItems, changedIndexes, section);
                                break;

                            case NotifyCollectionChangedAction.Move:
                                // NB: ReactiveList currently only supports single-item
                                // moves
                                var ea = update.Item1;
                                this.Log().Info("Calling MoveRow: {0}-{1} => {0}{2}", section, ea.OldStartingIndex, ea.NewStartingIndex);

                                adapter.MoveItem(
                                    NSIndexPath.FromRowSection(ea.OldStartingIndex, section),
                                    NSIndexPath.FromRowSection(ea.NewStartingIndex, section));
                                break;

                            default:
                                this.Log().Info("Unknown Action: {0}", changeAction);
                                break;
                            }
                        }

                        this.Log().Info("Ending update");
                        didPerformUpdates.OnNext(xs);
                    });
                });

                innerDisp.Add(disp);
            }
        }