discord-jadx/app/src/main/java/androidx/recyclerview/widget/AdapterHelper.java

604 lines
21 KiB
Java

package androidx.recyclerview.widget;
import androidx.core.util.Pools;
import androidx.recyclerview.widget.OpReorderer;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AdapterHelper implements OpReorderer.Callback {
private static final boolean DEBUG = false;
public static final int POSITION_TYPE_INVISIBLE = 0;
public static final int POSITION_TYPE_NEW_OR_LAID_OUT = 1;
private static final String TAG = "AHT";
public final Callback mCallback;
public final boolean mDisableRecycler;
private int mExistingUpdateTypes;
public Runnable mOnItemProcessedCallback;
public final OpReorderer mOpReorderer;
public final ArrayList<UpdateOp> mPendingUpdates;
public final ArrayList<UpdateOp> mPostponedList;
private Pools.Pool<UpdateOp> mUpdateOpPool;
public interface Callback {
RecyclerView.ViewHolder findViewHolder(int i);
void markViewHoldersUpdated(int i, int i2, Object obj);
void offsetPositionsForAdd(int i, int i2);
void offsetPositionsForMove(int i, int i2);
void offsetPositionsForRemovingInvisible(int i, int i2);
void offsetPositionsForRemovingLaidOutOrNewView(int i, int i2);
void onDispatchFirstPass(UpdateOp updateOp);
void onDispatchSecondPass(UpdateOp updateOp);
}
public static class UpdateOp {
public static final int ADD = 1;
public static final int MOVE = 8;
public static final int POOL_SIZE = 30;
public static final int REMOVE = 2;
public static final int UPDATE = 4;
public int cmd;
public int itemCount;
public Object payload;
public int positionStart;
public UpdateOp(int i, int i2, int i3, Object obj) {
this.cmd = i;
this.positionStart = i2;
this.itemCount = i3;
this.payload = obj;
}
public String cmdToString() {
int i = this.cmd;
return i != 1 ? i != 2 ? i != 4 ? i != 8 ? "??" : "mv" : "up" : "rm" : "add";
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
UpdateOp updateOp = (UpdateOp) obj;
int i = this.cmd;
if (i != updateOp.cmd) {
return false;
}
if (i == 8 && Math.abs(this.itemCount - this.positionStart) == 1 && this.itemCount == updateOp.positionStart && this.positionStart == updateOp.itemCount) {
return true;
}
if (this.itemCount != updateOp.itemCount || this.positionStart != updateOp.positionStart) {
return false;
}
Object obj2 = this.payload;
if (obj2 != null) {
if (!obj2.equals(updateOp.payload)) {
return false;
}
} else if (updateOp.payload != null) {
return false;
}
return true;
}
public int hashCode() {
return (((this.cmd * 31) + this.positionStart) * 31) + this.itemCount;
}
public String toString() {
return Integer.toHexString(System.identityHashCode(this)) + "[" + cmdToString() + ",s:" + this.positionStart + "c:" + this.itemCount + ",p:" + this.payload + "]";
}
}
public AdapterHelper(Callback callback) {
this(callback, false);
}
public AdapterHelper(Callback callback, boolean z2) {
this.mUpdateOpPool = new Pools.SimplePool(30);
this.mPendingUpdates = new ArrayList<>();
this.mPostponedList = new ArrayList<>();
this.mExistingUpdateTypes = 0;
this.mCallback = callback;
this.mDisableRecycler = z2;
this.mOpReorderer = new OpReorderer(this);
}
private void applyAdd(UpdateOp updateOp) {
postponeAndUpdateViewHolders(updateOp);
}
private void applyMove(UpdateOp updateOp) {
postponeAndUpdateViewHolders(updateOp);
}
private void applyRemove(UpdateOp updateOp) {
char c2;
boolean z2;
int i = updateOp.positionStart;
int i2 = updateOp.itemCount + i;
char c3 = 65535;
int i3 = i;
int i4 = 0;
while (i3 < i2) {
if (this.mCallback.findViewHolder(i3) != null || canFindInPreLayout(i3)) {
if (c3 == 0) {
dispatchAndUpdateViewHolders(obtainUpdateOp(2, i, i4, null));
z2 = true;
} else {
z2 = false;
}
c2 = 1;
} else {
if (c3 == 1) {
postponeAndUpdateViewHolders(obtainUpdateOp(2, i, i4, null));
z2 = true;
} else {
z2 = false;
}
c2 = 0;
}
if (z2) {
i3 -= i4;
i2 -= i4;
i4 = 1;
} else {
i4++;
}
i3++;
c3 = c2;
}
if (i4 != updateOp.itemCount) {
recycleUpdateOp(updateOp);
updateOp = obtainUpdateOp(2, i, i4, null);
}
if (c3 == 0) {
dispatchAndUpdateViewHolders(updateOp);
} else {
postponeAndUpdateViewHolders(updateOp);
}
}
private void applyUpdate(UpdateOp updateOp) {
int i = updateOp.positionStart;
int i2 = updateOp.itemCount + i;
int i3 = i;
char c2 = 65535;
int i4 = 0;
while (i < i2) {
if (this.mCallback.findViewHolder(i) != null || canFindInPreLayout(i)) {
if (c2 == 0) {
dispatchAndUpdateViewHolders(obtainUpdateOp(4, i3, i4, updateOp.payload));
i3 = i;
i4 = 0;
}
c2 = 1;
} else {
if (c2 == 1) {
postponeAndUpdateViewHolders(obtainUpdateOp(4, i3, i4, updateOp.payload));
i3 = i;
i4 = 0;
}
c2 = 0;
}
i4++;
i++;
}
if (i4 != updateOp.itemCount) {
Object obj = updateOp.payload;
recycleUpdateOp(updateOp);
updateOp = obtainUpdateOp(4, i3, i4, obj);
}
if (c2 == 0) {
dispatchAndUpdateViewHolders(updateOp);
} else {
postponeAndUpdateViewHolders(updateOp);
}
}
private boolean canFindInPreLayout(int i) {
int size = this.mPostponedList.size();
for (int i2 = 0; i2 < size; i2++) {
UpdateOp updateOp = this.mPostponedList.get(i2);
int i3 = updateOp.cmd;
if (i3 == 8) {
if (findPositionOffset(updateOp.itemCount, i2 + 1) == i) {
return true;
}
} else if (i3 == 1) {
int i4 = updateOp.positionStart;
int i5 = updateOp.itemCount + i4;
while (i4 < i5) {
if (findPositionOffset(i4, i2 + 1) == i) {
return true;
}
i4++;
}
continue;
} else {
continue;
}
}
return false;
}
private void dispatchAndUpdateViewHolders(UpdateOp updateOp) {
int i;
int i2 = updateOp.cmd;
if (i2 == 1 || i2 == 8) {
throw new IllegalArgumentException("should not dispatch add or move for pre layout");
}
int updatePositionWithPostponed = updatePositionWithPostponed(updateOp.positionStart, i2);
int i3 = updateOp.positionStart;
int i4 = updateOp.cmd;
if (i4 == 2) {
i = 0;
} else if (i4 == 4) {
i = 1;
} else {
throw new IllegalArgumentException("op should be remove or update." + updateOp);
}
int i5 = 1;
for (int i6 = 1; i6 < updateOp.itemCount; i6++) {
int updatePositionWithPostponed2 = updatePositionWithPostponed((i * i6) + updateOp.positionStart, updateOp.cmd);
int i7 = updateOp.cmd;
if (i7 == 2 ? updatePositionWithPostponed2 == updatePositionWithPostponed : i7 == 4 && updatePositionWithPostponed2 == updatePositionWithPostponed + 1) {
i5++;
} else {
UpdateOp obtainUpdateOp = obtainUpdateOp(i7, updatePositionWithPostponed, i5, updateOp.payload);
dispatchFirstPassAndUpdateViewHolders(obtainUpdateOp, i3);
recycleUpdateOp(obtainUpdateOp);
if (updateOp.cmd == 4) {
i3 += i5;
}
updatePositionWithPostponed = updatePositionWithPostponed2;
i5 = 1;
}
}
Object obj = updateOp.payload;
recycleUpdateOp(updateOp);
if (i5 > 0) {
UpdateOp obtainUpdateOp2 = obtainUpdateOp(updateOp.cmd, updatePositionWithPostponed, i5, obj);
dispatchFirstPassAndUpdateViewHolders(obtainUpdateOp2, i3);
recycleUpdateOp(obtainUpdateOp2);
}
}
private void postponeAndUpdateViewHolders(UpdateOp updateOp) {
this.mPostponedList.add(updateOp);
int i = updateOp.cmd;
if (i == 1) {
this.mCallback.offsetPositionsForAdd(updateOp.positionStart, updateOp.itemCount);
} else if (i == 2) {
this.mCallback.offsetPositionsForRemovingLaidOutOrNewView(updateOp.positionStart, updateOp.itemCount);
} else if (i == 4) {
this.mCallback.markViewHoldersUpdated(updateOp.positionStart, updateOp.itemCount, updateOp.payload);
} else if (i == 8) {
this.mCallback.offsetPositionsForMove(updateOp.positionStart, updateOp.itemCount);
} else {
throw new IllegalArgumentException("Unknown update op type for " + updateOp);
}
}
private int updatePositionWithPostponed(int i, int i2) {
int i3;
int i4;
for (int size = this.mPostponedList.size() - 1; size >= 0; size--) {
UpdateOp updateOp = this.mPostponedList.get(size);
int i5 = updateOp.cmd;
if (i5 == 8) {
int i6 = updateOp.positionStart;
int i7 = updateOp.itemCount;
if (i6 < i7) {
i4 = i6;
i3 = i7;
} else {
i3 = i6;
i4 = i7;
}
if (i < i4 || i > i3) {
if (i < i6) {
if (i2 == 1) {
updateOp.positionStart = i6 + 1;
updateOp.itemCount = i7 + 1;
} else if (i2 == 2) {
updateOp.positionStart = i6 - 1;
updateOp.itemCount = i7 - 1;
}
}
} else if (i4 == i6) {
if (i2 == 1) {
updateOp.itemCount = i7 + 1;
} else if (i2 == 2) {
updateOp.itemCount = i7 - 1;
}
i++;
} else {
if (i2 == 1) {
updateOp.positionStart = i6 + 1;
} else if (i2 == 2) {
updateOp.positionStart = i6 - 1;
}
i--;
}
} else {
int i8 = updateOp.positionStart;
if (i8 <= i) {
if (i5 == 1) {
i -= updateOp.itemCount;
} else if (i5 == 2) {
i += updateOp.itemCount;
}
} else if (i2 == 1) {
updateOp.positionStart = i8 + 1;
} else if (i2 == 2) {
updateOp.positionStart = i8 - 1;
}
}
}
for (int size2 = this.mPostponedList.size() - 1; size2 >= 0; size2--) {
UpdateOp updateOp2 = this.mPostponedList.get(size2);
if (updateOp2.cmd == 8) {
int i9 = updateOp2.itemCount;
if (i9 == updateOp2.positionStart || i9 < 0) {
this.mPostponedList.remove(size2);
recycleUpdateOp(updateOp2);
}
} else if (updateOp2.itemCount <= 0) {
this.mPostponedList.remove(size2);
recycleUpdateOp(updateOp2);
}
}
return i;
}
public AdapterHelper addUpdateOp(UpdateOp... updateOpArr) {
Collections.addAll(this.mPendingUpdates, updateOpArr);
return this;
}
public int applyPendingUpdatesToPosition(int i) {
int size = this.mPendingUpdates.size();
for (int i2 = 0; i2 < size; i2++) {
UpdateOp updateOp = this.mPendingUpdates.get(i2);
int i3 = updateOp.cmd;
if (i3 != 1) {
if (i3 == 2) {
int i4 = updateOp.positionStart;
if (i4 <= i) {
int i5 = updateOp.itemCount;
if (i4 + i5 > i) {
return -1;
}
i -= i5;
} else {
continue;
}
} else if (i3 == 8) {
int i6 = updateOp.positionStart;
if (i6 == i) {
i = updateOp.itemCount;
} else {
if (i6 < i) {
i--;
}
if (updateOp.itemCount <= i) {
i++;
}
}
}
} else if (updateOp.positionStart <= i) {
i += updateOp.itemCount;
}
}
return i;
}
public void consumePostponedUpdates() {
int size = this.mPostponedList.size();
for (int i = 0; i < size; i++) {
this.mCallback.onDispatchSecondPass(this.mPostponedList.get(i));
}
recycleUpdateOpsAndClearList(this.mPostponedList);
this.mExistingUpdateTypes = 0;
}
public void consumeUpdatesInOnePass() {
consumePostponedUpdates();
int size = this.mPendingUpdates.size();
for (int i = 0; i < size; i++) {
UpdateOp updateOp = this.mPendingUpdates.get(i);
int i2 = updateOp.cmd;
if (i2 == 1) {
this.mCallback.onDispatchSecondPass(updateOp);
this.mCallback.offsetPositionsForAdd(updateOp.positionStart, updateOp.itemCount);
} else if (i2 == 2) {
this.mCallback.onDispatchSecondPass(updateOp);
this.mCallback.offsetPositionsForRemovingInvisible(updateOp.positionStart, updateOp.itemCount);
} else if (i2 == 4) {
this.mCallback.onDispatchSecondPass(updateOp);
this.mCallback.markViewHoldersUpdated(updateOp.positionStart, updateOp.itemCount, updateOp.payload);
} else if (i2 == 8) {
this.mCallback.onDispatchSecondPass(updateOp);
this.mCallback.offsetPositionsForMove(updateOp.positionStart, updateOp.itemCount);
}
Runnable runnable = this.mOnItemProcessedCallback;
if (runnable != null) {
runnable.run();
}
}
recycleUpdateOpsAndClearList(this.mPendingUpdates);
this.mExistingUpdateTypes = 0;
}
public void dispatchFirstPassAndUpdateViewHolders(UpdateOp updateOp, int i) {
this.mCallback.onDispatchFirstPass(updateOp);
int i2 = updateOp.cmd;
if (i2 == 2) {
this.mCallback.offsetPositionsForRemovingInvisible(i, updateOp.itemCount);
} else if (i2 == 4) {
this.mCallback.markViewHoldersUpdated(i, updateOp.itemCount, updateOp.payload);
} else {
throw new IllegalArgumentException("only remove and update ops can be dispatched in first pass");
}
}
public int findPositionOffset(int i) {
return findPositionOffset(i, 0);
}
public int findPositionOffset(int i, int i2) {
int size = this.mPostponedList.size();
while (i2 < size) {
UpdateOp updateOp = this.mPostponedList.get(i2);
int i3 = updateOp.cmd;
if (i3 == 8) {
int i4 = updateOp.positionStart;
if (i4 == i) {
i = updateOp.itemCount;
} else {
if (i4 < i) {
i--;
}
if (updateOp.itemCount <= i) {
i++;
}
}
} else {
int i5 = updateOp.positionStart;
if (i5 > i) {
continue;
} else if (i3 == 2) {
int i6 = updateOp.itemCount;
if (i < i5 + i6) {
return -1;
}
i -= i6;
} else if (i3 == 1) {
i += updateOp.itemCount;
}
}
i2++;
}
return i;
}
public boolean hasAnyUpdateTypes(int i) {
return (i & this.mExistingUpdateTypes) != 0;
}
public boolean hasPendingUpdates() {
return this.mPendingUpdates.size() > 0;
}
public boolean hasUpdates() {
return !this.mPostponedList.isEmpty() && !this.mPendingUpdates.isEmpty();
}
@Override // androidx.recyclerview.widget.OpReorderer.Callback
public UpdateOp obtainUpdateOp(int i, int i2, int i3, Object obj) {
UpdateOp acquire = this.mUpdateOpPool.acquire();
if (acquire == null) {
return new UpdateOp(i, i2, i3, obj);
}
acquire.cmd = i;
acquire.positionStart = i2;
acquire.itemCount = i3;
acquire.payload = obj;
return acquire;
}
public boolean onItemRangeChanged(int i, int i2, Object obj) {
if (i2 < 1) {
return false;
}
this.mPendingUpdates.add(obtainUpdateOp(4, i, i2, obj));
this.mExistingUpdateTypes |= 4;
return this.mPendingUpdates.size() == 1;
}
public boolean onItemRangeInserted(int i, int i2) {
if (i2 < 1) {
return false;
}
this.mPendingUpdates.add(obtainUpdateOp(1, i, i2, null));
this.mExistingUpdateTypes |= 1;
return this.mPendingUpdates.size() == 1;
}
public boolean onItemRangeMoved(int i, int i2, int i3) {
if (i == i2) {
return false;
}
if (i3 == 1) {
this.mPendingUpdates.add(obtainUpdateOp(8, i, i2, null));
this.mExistingUpdateTypes |= 8;
return this.mPendingUpdates.size() == 1;
}
throw new IllegalArgumentException("Moving more than 1 item is not supported yet");
}
public boolean onItemRangeRemoved(int i, int i2) {
if (i2 < 1) {
return false;
}
this.mPendingUpdates.add(obtainUpdateOp(2, i, i2, null));
this.mExistingUpdateTypes |= 2;
return this.mPendingUpdates.size() == 1;
}
public void preProcess() {
this.mOpReorderer.reorderOps(this.mPendingUpdates);
int size = this.mPendingUpdates.size();
for (int i = 0; i < size; i++) {
UpdateOp updateOp = this.mPendingUpdates.get(i);
int i2 = updateOp.cmd;
if (i2 == 1) {
applyAdd(updateOp);
} else if (i2 == 2) {
applyRemove(updateOp);
} else if (i2 == 4) {
applyUpdate(updateOp);
} else if (i2 == 8) {
applyMove(updateOp);
}
Runnable runnable = this.mOnItemProcessedCallback;
if (runnable != null) {
runnable.run();
}
}
this.mPendingUpdates.clear();
}
@Override // androidx.recyclerview.widget.OpReorderer.Callback
public void recycleUpdateOp(UpdateOp updateOp) {
if (!this.mDisableRecycler) {
updateOp.payload = null;
this.mUpdateOpPool.release(updateOp);
}
}
public void recycleUpdateOpsAndClearList(List<UpdateOp> list) {
int size = list.size();
for (int i = 0; i < size; i++) {
recycleUpdateOp(list.get(i));
}
list.clear();
}
public void reset() {
recycleUpdateOpsAndClearList(this.mPendingUpdates);
recycleUpdateOpsAndClearList(this.mPostponedList);
this.mExistingUpdateTypes = 0;
}
}