package com.airbnb.epoxy;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
/** Defines an operation that makes a change to the epoxy model list. */
class UpdateOp {
@IntDef({ADD, REMOVE, UPDATE, MOVE})
@Retention(RetentionPolicy.SOURCE)
@interface Type {
}
static final int ADD = 0;
static final int REMOVE = 1;
static final int UPDATE = 2;
static final int MOVE = 3;
@Type int type;
int positionStart;
/** Holds the target position if this is a MOVE */
int itemCount;
ArrayList<EpoxyModel<?>> payloads;
private UpdateOp() {
}
static UpdateOp instance(@Type int type, int positionStart, int itemCount,
@Nullable EpoxyModel<?> payload) {
UpdateOp op = new UpdateOp();
op.type = type;
op.positionStart = positionStart;
op.itemCount = itemCount;
op.addPayload(payload);
return op;
}
/** Returns the index one past the last item in the affected range. */
int positionEnd() {
return positionStart + itemCount;
}
boolean isAfter(int position) {
return position < positionStart;
}
boolean isBefore(int position) {
return position >= positionEnd();
}
boolean contains(int position) {
return position >= positionStart && position < positionEnd();
}
void addPayload(@Nullable EpoxyModel<?> payload) {
if (payload == null) {
return;
}
if (payloads == null) {
// In most cases this won't be a batch update so we can expect just one payload
payloads = new ArrayList<>(1);
} else if (payloads.size() == 1) {
// There are multiple payloads, but we don't know how big the batch will end up being.
// To prevent resizing the list many times we bump it to a medium size
payloads.ensureCapacity(10);
}
payloads.add(payload);
}
@Override
public String toString() {
return "UpdateOp{"
+ "type=" + type
+ ", positionStart=" + positionStart
+ ", itemCount=" + itemCount
+ '}';
}
}