Skip to content

Instantly share code, notes, and snippets.

@ndefeijter
Created June 12, 2016 08:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ndefeijter/2191f8a43ce903c5d9ea69f02c7ee7e9 to your computer and use it in GitHub Desktop.
Save ndefeijter/2191f8a43ce903c5d9ea69f02c7ee7e9 to your computer and use it in GitHub Desktop.
package com.firebase.ui;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Query;
import com.firebase.ui.FirebaseArray.OnChangedListener;
import java.util.ArrayList;
import java.util.List;
public class FirebaseArrays {
private final List<FirebaseArray> arrays = new ArrayList<>();
private final List<OnChangedListenerImpl> listeners = new ArrayList<>();
private OnChangedListener aggregatedListener;
public void add(final Query ref) {
if (null == ref) throw new IllegalArgumentException("null == ref");
add(new FirebaseArray(ref));
}
private void add(final FirebaseArray array) {
if (null == array) throw new IllegalArgumentException("null == array");
final OnChangedListenerImpl onChangedListener = new OnChangedListenerImpl();
listeners.add(onChangedListener);
arrays.add(array);
array.setOnChangedListener(onChangedListener);
}
public void remove(final Query ref) {
throw new UnsupportedOperationException("TODO: implement me");
}
private void remove(final FirebaseArray array) {
final int arrayIndex = arrays.indexOf(array);
if (arrayIndex >= 0) {
arrays.remove(arrayIndex);
listeners.remove(arrayIndex);
array.setOnChangedListener(null);
array.cleanup();
}
}
public void cleanup() {
final int count = getCount();
final List<FirebaseArray> arraysCopy = new ArrayList<>(arrays);
for (final FirebaseArray array : arraysCopy) {
remove(array);
}
if (aggregatedListener != null) {
for (int i = count - 1; i >= 0; i--) {
aggregatedListener.onChanged(OnChangedListener.EventType.Removed, i, -1);
}
}
}
public int getCount() {
int count = 0;
for (final FirebaseArray array : arrays) {
count += array.getCount();
}
return count;
}
public DataSnapshot getItem(int index) {
final int[] arrayIndexAndOffset = getArrayIndexAndOffsetForAggregatedIndex(index);
final int arrayIndex = arrayIndexAndOffset[0];
final int arrayOffset = arrayIndexAndOffset[1];
final FirebaseArray array = arrays.get(arrayIndex);
final DataSnapshot snapshot = array.getItem(index - arrayOffset);
return snapshot;
}
public void setOnChangedListener(OnChangedListener listener) {
aggregatedListener = listener;
}
private int[] getArrayIndexAndOffsetForAggregatedIndex(final int index) {
return getArrayIndexAndOffsetForListenerOrAggregatedIndex(null, index);
}
private int[] getArrayIndexAndOffsetForListener(final OnChangedListenerImpl listener) {
return getArrayIndexAndOffsetForListenerOrAggregatedIndex(listener, -1);
}
private int[] getArrayIndexAndOffsetForListenerOrAggregatedIndex(final OnChangedListenerImpl listener, final int index) {
for (int offset = 0, i = 0; i < listeners.size(); i++) {
final FirebaseArray array = arrays.get(i);
final int arrayCount = array.getCount();
if (null != listener) {
final OnChangedListenerImpl listenerCandidate = listeners.get(i);
if (listenerCandidate == listener) {
return new int[]{i, offset};
}
} else {
if (index < offset + arrayCount) {
return new int[]{i, offset};
}
}
offset += arrayCount;
}
if (null != listener) {
throw new IllegalArgumentException("unknown: " + listener);
} else {
throw new IndexOutOfBoundsException("index=" + index);
}
}
private class OnChangedListenerImpl implements OnChangedListener {
@Override
public void onChanged(final EventType type, final int index, final int oldIndex) {
final int[] arrayIndexAndOffset = getArrayIndexAndOffsetForListener(this);
final int arrayIndex = arrayIndexAndOffset[0];
final int arrayOffset = arrayIndexAndOffset[1];
notifyChangedListeners(type, arrayOffset + index, arrayOffset + oldIndex);
}
private void notifyChangedListeners(OnChangedListener.EventType type, int index, int oldIndex) {
if (aggregatedListener != null) {
aggregatedListener.onChanged(type, index, oldIndex);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment