Home | History | Annotate | Download | only in databinding
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package android.databinding;
     17 
     18 import android.support.v4.util.Pools;
     19 
     20 /**
     21  * Utility class for managing ObservableList callbacks.
     22  */
     23 public class ListChangeRegistry
     24         extends
     25         CallbackRegistry<ObservableList.OnListChangedCallback, ObservableList,
     26                 ListChangeRegistry.ListChanges> {
     27     private static final Pools.SynchronizedPool<ListChanges> sListChanges =
     28             new Pools.SynchronizedPool<ListChanges>(10);
     29 
     30     private static final int ALL = 0;
     31     private static final int CHANGED = 1;
     32     private static final int INSERTED = 2;
     33     private static final int MOVED = 3;
     34     private static final int REMOVED = 4;
     35 
     36     private static final CallbackRegistry.NotifierCallback<ObservableList.OnListChangedCallback,
     37             ObservableList, ListChanges> NOTIFIER_CALLBACK = new CallbackRegistry.NotifierCallback<
     38             ObservableList.OnListChangedCallback, ObservableList, ListChanges>() {
     39         @Override
     40         public void onNotifyCallback(ObservableList.OnListChangedCallback callback,
     41                 ObservableList sender, int notificationType, ListChanges listChanges) {
     42             switch (notificationType) {
     43                 case CHANGED:
     44                     callback.onItemRangeChanged(sender, listChanges.start, listChanges.count);
     45                     break;
     46                 case INSERTED:
     47                     callback.onItemRangeInserted(sender, listChanges.start, listChanges.count);
     48                     break;
     49                 case MOVED:
     50                     callback.onItemRangeMoved(sender, listChanges.start, listChanges.to,
     51                             listChanges.count);
     52                     break;
     53                 case REMOVED:
     54                     callback.onItemRangeRemoved(sender, listChanges.start, listChanges.count);
     55                     break;
     56                 default:
     57                     callback.onChanged(sender);
     58                     break;
     59             }
     60         }
     61     };
     62 
     63     /**
     64      * Notify registered callbacks that there was an unknown or whole-list change.
     65      *
     66      * @param list The list that changed.
     67      */
     68     public void notifyChanged(ObservableList list) {
     69         notifyCallbacks(list, ALL, null);
     70     }
     71 
     72     /**
     73      * Notify registered callbacks that some elements have changed.
     74      *
     75      * @param list The list that changed.
     76      * @param start The index of the first changed element.
     77      * @param count The number of changed elements.
     78      */
     79     public void notifyChanged(ObservableList list, int start, int count) {
     80         ListChanges listChanges = acquire(start, 0, count);
     81         notifyCallbacks(list, CHANGED, listChanges);
     82     }
     83 
     84     /**
     85      * Notify registered callbacks that elements were inserted.
     86      *
     87      * @param list The list that changed.
     88      * @param start The index where the elements were inserted.
     89      * @param count The number of elements that were inserted.
     90      */
     91     public void notifyInserted(ObservableList list, int start, int count) {
     92         ListChanges listChanges = acquire(start, 0, count);
     93         notifyCallbacks(list, INSERTED, listChanges);
     94     }
     95 
     96     /**
     97      * Notify registered callbacks that elements were moved.
     98      *
     99      * @param list The list that changed.
    100      * @param from The index of the first element moved.
    101      * @param to The index of where the element was moved to.
    102      * @param count The number of elements moved.
    103      */
    104     public void notifyMoved(ObservableList list, int from, int to, int count) {
    105         ListChanges listChanges = acquire(from, to, count);
    106         notifyCallbacks(list, MOVED, listChanges);
    107     }
    108 
    109     /**
    110      * Notify registered callbacks that elements were deleted.
    111      *
    112      * @param list The list that changed.
    113      * @param start The index of the first element to be removed.
    114      * @param count The number of elements removed.
    115      */
    116     public void notifyRemoved(ObservableList list, int start, int count) {
    117         ListChanges listChanges = acquire(start, 0, count);
    118         notifyCallbacks(list, REMOVED, listChanges);
    119     }
    120 
    121     private static ListChanges acquire(int start, int to, int count) {
    122         ListChanges listChanges = sListChanges.acquire();
    123         if (listChanges == null) {
    124             listChanges = new ListChanges();
    125         }
    126         listChanges.start = start;
    127         listChanges.to = to;
    128         listChanges.count = count;
    129         return listChanges;
    130     }
    131 
    132     @Override
    133     public synchronized void notifyCallbacks(ObservableList sender, int notificationType,
    134             ListChanges listChanges) {
    135         super.notifyCallbacks(sender, notificationType, listChanges);
    136         if (listChanges != null) {
    137             sListChanges.release(listChanges);
    138         }
    139     }
    140 
    141     public ListChangeRegistry() {
    142         super(NOTIFIER_CALLBACK);
    143     }
    144 
    145     static class ListChanges {
    146         public int start;
    147         public int count;
    148         public int to;
    149     }
    150 }
    151