/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.databinding; import android.support.v4.util.Pools; /** * Utility class for managing ObservableList callbacks. */ public class ListChangeRegistry extends CallbackRegistry<ObservableList.OnListChangedCallback, ObservableList, ListChangeRegistry.ListChanges> { private static final Pools.SynchronizedPool<ListChanges> sListChanges = new Pools.SynchronizedPool<>(10); private static final int ALL = 0; private static final int CHANGED = 1; private static final int INSERTED = 2; private static final int MOVED = 3; private static final int REMOVED = 4; private static final CallbackRegistry.NotifierCallback<ObservableList.OnListChangedCallback, ObservableList, ListChanges> NOTIFIER_CALLBACK = new CallbackRegistry.NotifierCallback< ObservableList.OnListChangedCallback, ObservableList, ListChanges>() { @Override public void onNotifyCallback(ObservableList.OnListChangedCallback callback, ObservableList sender, int notificationType, ListChanges listChanges) { switch (notificationType) { case CHANGED: callback.onItemRangeChanged(sender, listChanges.start, listChanges.count); break; case INSERTED: callback.onItemRangeInserted(sender, listChanges.start, listChanges.count); break; case MOVED: callback.onItemRangeMoved(sender, listChanges.start, listChanges.to, listChanges.count); break; case REMOVED: callback.onItemRangeRemoved(sender, listChanges.start, listChanges.count); break; default: callback.onChanged(sender); break; } } }; /** * Notify registered callbacks that there was an unknown or whole-list change. * * @param list The list that changed. */ public void notifyChanged(ObservableList list) { notifyCallbacks(list, ALL, null); } /** * Notify registered callbacks that some elements have changed. * * @param list The list that changed. * @param start The index of the first changed element. * @param count The number of changed elements. */ public void notifyChanged(ObservableList list, int start, int count) { ListChanges listChanges = acquire(start, 0, count); notifyCallbacks(list, CHANGED, listChanges); } /** * Notify registered callbacks that elements were inserted. * * @param list The list that changed. * @param start The index where the elements were inserted. * @param count The number of elements that were inserted. */ public void notifyInserted(ObservableList list, int start, int count) { ListChanges listChanges = acquire(start, 0, count); notifyCallbacks(list, INSERTED, listChanges); } /** * Notify registered callbacks that elements were moved. * * @param list The list that changed. * @param from The index of the first element moved. * @param to The index of where the element was moved to. * @param count The number of elements moved. */ public void notifyMoved(ObservableList list, int from, int to, int count) { ListChanges listChanges = acquire(from, to, count); notifyCallbacks(list, MOVED, listChanges); } /** * Notify registered callbacks that elements were deleted. * * @param list The list that changed. * @param start The index of the first element to be removed. * @param count The number of elements removed. */ public void notifyRemoved(ObservableList list, int start, int count) { ListChanges listChanges = acquire(start, 0, count); notifyCallbacks(list, REMOVED, listChanges); } private static ListChanges acquire(int start, int to, int count) { ListChanges listChanges = sListChanges.acquire(); if (listChanges == null) { listChanges = new ListChanges(); } listChanges.start = start; listChanges.to = to; listChanges.count = count; return listChanges; } @Override public synchronized void notifyCallbacks(ObservableList sender, int notificationType, ListChanges listChanges) { super.notifyCallbacks(sender, notificationType, listChanges); if (listChanges != null) { sListChanges.release(listChanges); } } public ListChangeRegistry() { super(NOTIFIER_CALLBACK); } static class ListChanges { public int start; public int count; public int to; } }