15cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount/* 25cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount * Copyright (C) 2015 The Android Open Source Project 35cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount * 45cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount * Licensed under the Apache License, Version 2.0 (the "License"); 55cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount * you may not use this file except in compliance with the License. 65cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount * You may obtain a copy of the License at 75cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount * 85cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount * http://www.apache.org/licenses/LICENSE-2.0 95cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount * 105cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount * Unless required by applicable law or agreed to in writing, software 115cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount * distributed under the License is distributed on an "AS IS" BASIS, 125cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount * See the License for the specific language governing permissions and 145cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount * limitations under the License. 155cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount */ 16fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding; 175cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount 185cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mountimport android.support.v4.util.Pools; 195cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount 20c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount/** 21c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * Utility class for managing ObservableList callbacks. 22c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount */ 235cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mountpublic class ListChangeRegistry 242c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount extends 25722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount CallbackRegistry<ObservableList.OnListChangedCallback, ObservableList, 26722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount ListChangeRegistry.ListChanges> { 275cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount private static final Pools.SynchronizedPool<ListChanges> sListChanges = 289784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar new Pools.SynchronizedPool<ListChanges>(10); 295cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount 305cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount private static final int ALL = 0; 315cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount private static final int CHANGED = 1; 325cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount private static final int INSERTED = 2; 335cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount private static final int MOVED = 3; 345cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount private static final int REMOVED = 4; 355cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount 36722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount private static final CallbackRegistry.NotifierCallback<ObservableList.OnListChangedCallback, 37722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount ObservableList, ListChanges> NOTIFIER_CALLBACK = new CallbackRegistry.NotifierCallback< 38722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount ObservableList.OnListChangedCallback, ObservableList, ListChanges>() { 395cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount @Override 40722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount public void onNotifyCallback(ObservableList.OnListChangedCallback callback, 41722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount ObservableList sender, int notificationType, ListChanges listChanges) { 425cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount switch (notificationType) { 435cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount case CHANGED: 44722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount callback.onItemRangeChanged(sender, listChanges.start, listChanges.count); 455cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount break; 465cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount case INSERTED: 47722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount callback.onItemRangeInserted(sender, listChanges.start, listChanges.count); 485cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount break; 495cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount case MOVED: 50722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount callback.onItemRangeMoved(sender, listChanges.start, listChanges.to, 51722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount listChanges.count); 525cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount break; 535cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount case REMOVED: 54722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount callback.onItemRangeRemoved(sender, listChanges.start, listChanges.count); 555cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount break; 565cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount default: 57722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount callback.onChanged(sender); 585cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount break; 595cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 605cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 615cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount }; 625cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount 63c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount /** 64c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * Notify registered callbacks that there was an unknown or whole-list change. 65c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * 66c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * @param list The list that changed. 67c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount */ 685cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount public void notifyChanged(ObservableList list) { 695cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount notifyCallbacks(list, ALL, null); 705cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 715cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount 72c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount /** 73c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * Notify registered callbacks that some elements have changed. 74c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * 75c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * @param list The list that changed. 76c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * @param start The index of the first changed element. 77c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * @param count The number of changed elements. 78c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount */ 795cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount public void notifyChanged(ObservableList list, int start, int count) { 805cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount ListChanges listChanges = acquire(start, 0, count); 815cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount notifyCallbacks(list, CHANGED, listChanges); 825cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 835cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount 84c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount /** 85c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * Notify registered callbacks that elements were inserted. 86c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * 87c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * @param list The list that changed. 88c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * @param start The index where the elements were inserted. 89c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * @param count The number of elements that were inserted. 90c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount */ 915cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount public void notifyInserted(ObservableList list, int start, int count) { 925cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount ListChanges listChanges = acquire(start, 0, count); 935cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount notifyCallbacks(list, INSERTED, listChanges); 945cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 955cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount 96c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount /** 97c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * Notify registered callbacks that elements were moved. 98c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * 99c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * @param list The list that changed. 100c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * @param from The index of the first element moved. 101c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * @param to The index of where the element was moved to. 102c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * @param count The number of elements moved. 103c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount */ 1045cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount public void notifyMoved(ObservableList list, int from, int to, int count) { 1055cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount ListChanges listChanges = acquire(from, to, count); 1065cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount notifyCallbacks(list, MOVED, listChanges); 1075cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 1085cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount 109c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount /** 110c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * Notify registered callbacks that elements were deleted. 111c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * 112c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * @param list The list that changed. 113c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * @param start The index of the first element to be removed. 114c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount * @param count The number of elements removed. 115c9a5d6f140f732ca0ff279a4b1ee315072e1c422George Mount */ 1165cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount public void notifyRemoved(ObservableList list, int start, int count) { 1175cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount ListChanges listChanges = acquire(start, 0, count); 1185cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount notifyCallbacks(list, REMOVED, listChanges); 1195cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 1205cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount 1215cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount private static ListChanges acquire(int start, int to, int count) { 1225cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount ListChanges listChanges = sListChanges.acquire(); 1235cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount if (listChanges == null) { 1245cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount listChanges = new ListChanges(); 1255cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 1265cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount listChanges.start = start; 1275cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount listChanges.to = to; 1285cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount listChanges.count = count; 1295cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount return listChanges; 1305cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 1315cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount 13265bf08e7cd0acc5e13ab131433e35981d4416a79George Mount @Override 13365bf08e7cd0acc5e13ab131433e35981d4416a79George Mount public synchronized void notifyCallbacks(ObservableList sender, int notificationType, 13465bf08e7cd0acc5e13ab131433e35981d4416a79George Mount ListChanges listChanges) { 13565bf08e7cd0acc5e13ab131433e35981d4416a79George Mount super.notifyCallbacks(sender, notificationType, listChanges); 13665bf08e7cd0acc5e13ab131433e35981d4416a79George Mount if (listChanges != null) { 13765bf08e7cd0acc5e13ab131433e35981d4416a79George Mount sListChanges.release(listChanges); 13865bf08e7cd0acc5e13ab131433e35981d4416a79George Mount } 13965bf08e7cd0acc5e13ab131433e35981d4416a79George Mount } 14065bf08e7cd0acc5e13ab131433e35981d4416a79George Mount 1415cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount public ListChangeRegistry() { 1425cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount super(NOTIFIER_CALLBACK); 1435cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 1445cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount 1455cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount static class ListChanges { 1465cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount public int start; 1475cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount public int count; 1485cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount public int to; 1495cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 1505cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount} 151