import android.os.Build;
import android.util.Log;
+import org.jetbrains.annotations.NotNull;
+
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
public class ObservableList<T> extends Observable implements List<T> {
private List<T> list;
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+ private int notificationBlocks = 0;
+ private boolean notificationWasBlocked = false;
public ObservableList(List<T> list) {
this.list = list;
}
private void forceNotify() {
+ if (notificationBlocked()) return;
setChanged();
notifyObservers();
}
+ private boolean notificationBlocked() {
+ return notificationWasBlocked = (notificationBlocks > 0);
+ }
private void forceNotify(int index) {
+ if (notificationBlocked()) return;
setChanged();
notifyObservers(index);
}
return list.lastIndexOf(o);
}
}
+ @NotNull
public ListIterator<T> listIterator() {
if (!lock.isWriteLockedByCurrentThread()) throw new RuntimeException(
"Iterators break encapsulation and ignore locking. Write-lock first");
return list.listIterator();
}
+ @NotNull
public ListIterator<T> listIterator(int index) {
if (!lock.isWriteLockedByCurrentThread()) throw new RuntimeException(
"Iterators break encapsulation and ignore locking. Write-lock first");
return list.listIterator(index);
}
+ @NotNull
public List<T> subList(int fromIndex, int toIndex) {
try (LockHolder lh = lockForReading()) {
return list.subList(fromIndex, toIndex);
}
}
+ @NotNull
@RequiresApi(api = Build.VERSION_CODES.N)
public Spliterator<T> spliterator() {
if (!lock.isWriteLockedByCurrentThread()) throw new RuntimeException(
rLock.lock();
return new LockHolder(rLock);
}
+ public void blockNotifications() {
+ notificationBlocks++;
+ }
+ public void unblockNotifications() {
+ notificationBlocks--;
+ if ((notificationBlocks == 0) && notificationWasBlocked) notifyObservers();
+ }
}
\ No newline at end of file