From 3f6629081bfe7dd70f907c4d397a6922eb3debd1 Mon Sep 17 00:00:00 2001 From: Gavriil Sitnikov Date: Fri, 3 Jun 2016 18:19:52 +0300 Subject: [PATCH] useless loadRange calls fixed --- .../adapters/ObservableCollectionAdapter.java | 133 +++++++++--------- 1 file changed, 69 insertions(+), 64 deletions(-) diff --git a/src/main/java/ru/touchin/roboswag/components/listing/adapters/ObservableCollectionAdapter.java b/src/main/java/ru/touchin/roboswag/components/listing/adapters/ObservableCollectionAdapter.java index 61500d5..4120011 100644 --- a/src/main/java/ru/touchin/roboswag/components/listing/adapters/ObservableCollectionAdapter.java +++ b/src/main/java/ru/touchin/roboswag/components/listing/adapters/ObservableCollectionAdapter.java @@ -26,7 +26,6 @@ import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; -import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -38,8 +37,10 @@ import ru.touchin.roboswag.core.observables.collections.Change; import ru.touchin.roboswag.core.observables.collections.ObservableCollection; import ru.touchin.roboswag.core.observables.collections.ObservableList; import ru.touchin.roboswag.core.utils.ShouldNotHappenException; +import rx.Observable; import rx.Subscription; import rx.functions.Actions; +import rx.subjects.BehaviorSubject; /** * Created by Gavriil Sitnikov on 20/11/2015. @@ -51,42 +52,37 @@ public abstract class ObservableCollectionAdapter Collection simpleChanges(@Nullable final ObservableCollection oldCollection, - @Nullable final ObservableCollection newCollection, - final int offset) { - final int oldSize = getNullableCollectionSize(oldCollection); - final int newSize = getNullableCollectionSize(newCollection); - final List result = new ArrayList<>(); - if (oldSize < newSize) { - result.add(new Change(Change.Type.INSERTED, oldSize + offset, newSize - oldSize)); - } else if (newSize > oldSize) { - result.add(new Change(Change.Type.REMOVED, newSize + offset, oldSize - newSize)); - } - if (newSize != 0 && oldSize != 0) { - result.add(new Change(Change.Type.CHANGED, offset, Math.min(oldSize, newSize))); - } - return result; - } - + private final BehaviorSubject> observableCollectionSubject + = BehaviorSubject.create((ObservableCollection) null); @NonNull private final UiBindable uiBindable; @Nullable private OnItemClickListener onItemClickListener; - @Nullable - private ObservableCollection observableCollection; - @Nullable - private Subscription itemsProviderSubscription; - private int lastUpdatedChangeNumber; + private int lastUpdatedChangeNumber = UNKNOWN_UPDATE; + @NonNull + private final Observable newItemsUpdatingObservable; + @NonNull + private final Observable historyPreLoadingObservable; public ObservableCollectionAdapter(@NonNull final UiBindable uiBindable) { super(); this.uiBindable = uiBindable; + uiBindable.bind(observableCollectionSubject + .switchMap(observableCollection -> observableCollection != null ? observableCollection.observeChanges() : Observable.empty())) + .subscribe(this::onItemsChanged); + newItemsUpdatingObservable = uiBindable.untilStop(observableCollectionSubject + .switchMap(observableCollection -> observableCollection != null ? observableCollection.loadItem(0) : Observable.empty())); + historyPreLoadingObservable = uiBindable.untilStop(observableCollectionSubject + .switchMap(observableCollection -> observableCollection != null + ? Observable.just(observableCollection).concatWith(observableCollection.observeChanges().map(ignored -> observableCollection)) + : Observable.empty()) + .switchMap(changedObservableCollection -> { + final int size = changedObservableCollection.size(); + return changedObservableCollection.loadRange(size, size + PRE_LOADING_COUNT); + })); } @NonNull @@ -103,44 +99,45 @@ public abstract class ObservableCollectionAdapter getObservableCollection() { - return observableCollection; + public ObservableCollection getObservableCollectionSubject() { + return observableCollectionSubject.getValue(); } protected int itemsOffset() { return 0; } - public void setObservableCollection(@Nullable final ObservableCollection observableCollection) { - if (itemsProviderSubscription != null) { - itemsProviderSubscription.unsubscribe(); - itemsProviderSubscription = null; - } - final Collection changes = simpleChanges(this.observableCollection, observableCollection, itemsOffset()); - this.observableCollection = observableCollection; - if (!changes.isEmpty()) { - notifyAboutChanges(changes); - } - if (this.observableCollection != null) { - itemsProviderSubscription = uiBindable.bind(this.observableCollection.observeChanges()) - .subscribe(this::onItemsChanged); + private void refreshUpdate() { + notifyDataSetChanged(); + if (observableCollectionSubject.getValue() != null) { + lastUpdatedChangeNumber = observableCollectionSubject.getValue().getChangesCount(); + } else { + lastUpdatedChangeNumber = UNKNOWN_UPDATE; } } + public void setObservableCollection(@Nullable final ObservableCollection observableCollection) { + this.observableCollectionSubject.onNext(observableCollection); + refreshUpdate(); + } + protected void onItemsChanged(@NonNull final ObservableCollection.CollectionChange collectionChange) { - if (observableCollection == null) { + if (observableCollectionSubject.getValue() == null) { return; } if (Looper.myLooper() != Looper.getMainLooper()) { Lc.assertion("Items changes called on not main thread"); return; } - if (collectionChange.getNumber() != observableCollection.getChangesCount() + if (collectionChange.getNumber() != observableCollectionSubject.getValue().getChangesCount() || collectionChange.getNumber() != lastUpdatedChangeNumber + 1) { - notifyDataSetChanged(); + if (lastUpdatedChangeNumber < collectionChange.getNumber()) { + refreshUpdate(); + } return; } notifyAboutChanges(collectionChange.getChanges()); + lastUpdatedChangeNumber = observableCollectionSubject.getValue().getChangesCount(); } private void notifyAboutChanges(@NonNull final Collection changes) { @@ -164,9 +161,7 @@ public abstract class ObservableCollectionAdapter onItemClickListener) { this.onItemClickListener = onItemClickListener; - if (observableCollection != null && !observableCollection.isEmpty()) { - notifyItemRangeChanged(itemsOffset(), observableCollection.size()); - } + refreshUpdate(); } @Override @@ -184,15 +179,16 @@ public abstract class ObservableCollectionAdapter onItemClickListener.onItemClicked(item, position), getItemClickDelay()); } @@ -202,15 +198,15 @@ public abstract class ObservableCollectionAdapter observableCollection, + @SuppressWarnings("unchecked") + public void bindPosition(@NonNull final ObservableCollection observableCollection, + @NonNull final ObservableCollectionAdapter adapter, final int position) { - if (preLoadingSubscription != null) { - preLoadingSubscription.unsubscribe(); + if (newItemsUpdatingSubscription != null) { + newItemsUpdatingSubscription.unsubscribe(); + newItemsUpdatingSubscription = null; + } + if (historyPreLoadingSubscription != null) { + historyPreLoadingSubscription.unsubscribe(); + historyPreLoadingSubscription = null; + } + if (position == adapter.itemsOffset()) { + newItemsUpdatingSubscription = adapter.newItemsUpdatingObservable.subscribe(Actions.empty(), Actions.empty()); + } + if (position - adapter.itemsOffset() > observableCollection.size() - PRE_LOADING_COUNT) { + historyPreLoadingSubscription = adapter.historyPreLoadingObservable.subscribe(Actions.empty(), Actions.empty()); } - preLoadingSubscription = uiBindable - .untilStop(observableCollection - .loadRange(Math.max(0, position - PRE_LOADING_COUNT), position + PRE_LOADING_COUNT) - .first()) - .subscribe(Actions.empty(), Actions.empty()); } }