Make filtered MemoryHabitLists update automatically

This commit is contained in:
2017-06-20 10:34:21 -04:00
parent 71fe6137be
commit 00660d3e36
6 changed files with 177 additions and 78 deletions

View File

@@ -155,7 +155,7 @@ public abstract class HabitList implements Iterable<Habit>
* @param from the habit that should be moved
* @param to the habit that currently occupies the desired position
*/
public abstract void reorder(Habit from, Habit to);
public abstract void reorder(@NonNull Habit from, @NonNull Habit to);
public void repair()
{

View File

@@ -36,31 +36,37 @@ import static org.isoron.uhabits.core.models.HabitList.Order.BY_SCORE;
public class MemoryHabitList extends HabitList
{
@NonNull
private LinkedList<Habit> list;
private LinkedList<Habit> list = new LinkedList<>();
private Comparator<Habit> comparator = null;
@NonNull
private Order order;
private Order order = Order.BY_POSITION;
@Nullable
private MemoryHabitList parent = null;
public MemoryHabitList()
{
super();
list = new LinkedList<>();
order = Order.BY_POSITION;
}
protected MemoryHabitList(@NonNull HabitMatcher matcher)
protected MemoryHabitList(@NonNull HabitMatcher matcher,
Comparator<Habit> comparator,
@NonNull MemoryHabitList parent)
{
super(matcher);
list = new LinkedList<>();
order = Order.BY_POSITION;
this.parent = parent;
this.comparator = comparator;
parent.getObservable().addListener(this::loadFromParent);
loadFromParent();
}
@Override
public synchronized void add(@NonNull Habit habit)
throws IllegalArgumentException
{
throwIfHasParent();
if (list.contains(habit))
throw new IllegalArgumentException("habit already added");
@@ -71,6 +77,8 @@ public class MemoryHabitList extends HabitList
if (id == null) habit.setId((long) list.size());
list.addLast(habit);
resort();
getObservable().notifyListeners();
}
@Override
@@ -78,7 +86,7 @@ public class MemoryHabitList extends HabitList
{
for (Habit h : list)
{
if (h.getId() == null) continue;
if (h.getId() == null) throw new IllegalStateException();
if (h.getId() == id) return h;
}
return null;
@@ -95,10 +103,7 @@ public class MemoryHabitList extends HabitList
@Override
public synchronized HabitList getFiltered(HabitMatcher matcher)
{
MemoryHabitList habits = new MemoryHabitList(matcher);
habits.comparator = comparator;
for (Habit h : this) if (matcher.matches(h)) habits.add(h);
return habits;
return new MemoryHabitList(matcher, comparator, this);
}
@Override
@@ -115,44 +120,6 @@ public class MemoryHabitList extends HabitList
resort();
}
@Override
public int indexOf(@NonNull Habit h)
{
return list.indexOf(h);
}
@Override
public Iterator<Habit> iterator()
{
return Collections.unmodifiableCollection(list).iterator();
}
@Override
public synchronized void remove(@NonNull Habit habit)
{
list.remove(habit);
}
@Override
public synchronized void reorder(Habit from, Habit to)
{
int toPos = indexOf(to);
list.remove(from);
list.add(toPos, from);
}
@Override
public int size()
{
return list.size();
}
@Override
public void update(List<Habit> habits)
{
// NOP
}
private Comparator<Habit> getComparatorByOrder(Order order)
{
Comparator<Habit> nameComparator =
@@ -180,6 +147,71 @@ public class MemoryHabitList extends HabitList
throw new IllegalStateException();
}
@Override
public int indexOf(@NonNull Habit h)
{
return list.indexOf(h);
}
@NonNull
@Override
public Iterator<Habit> iterator()
{
return Collections.unmodifiableCollection(list).iterator();
}
@Override
public synchronized void remove(@NonNull Habit habit)
{
throwIfHasParent();
list.remove(habit);
}
@Override
public synchronized void reorder(@NonNull Habit from, @NonNull Habit to)
{
throwIfHasParent();
if (indexOf(from) < 0)
throw new IllegalArgumentException(
"list does not contain (from) habit");
int toPos = indexOf(to);
if (toPos < 0)
throw new IllegalArgumentException(
"list does not contain (to) habit");
list.remove(from);
list.add(toPos, from);
}
@Override
public int size()
{
return list.size();
}
@Override
public void update(List<Habit> habits)
{
// NOP
}
private void throwIfHasParent()
{
if (parent != null) throw new IllegalStateException(
"Filtered lists cannot be modified directly. " +
"You should modify the parent list instead.");
}
private synchronized void loadFromParent()
{
if (parent == null) throw new IllegalStateException();
list.clear();
for (Habit h : parent) if (filter.matches(h)) list.add(h);
resort();
}
private synchronized void resort()
{
if (comparator != null) Collections.sort(list, comparator);