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.ArrayMap;
195cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount
205cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mountimport java.util.Collection;
215cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount
225cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mountpublic class ObservableArrayMap<K, V> extends ArrayMap<K, V> implements ObservableMap<K, V> {
235cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount
24d37b47419005587c52ca4c099432327b7f06478dYigit Boyar    private transient MapChangeRegistry mListeners;
255cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount
265cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    @Override
27722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount    public void addOnMapChangedCallback(
28722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount            OnMapChangedCallback<? extends ObservableMap<K, V>, K, V> listener) {
295cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        if (mListeners == null) {
305cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount            mListeners = new MapChangeRegistry();
315cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        }
325cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        mListeners.add(listener);
335cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    }
345cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount
355cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    @Override
36722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount    public void removeOnMapChangedCallback(
37722fe711207a37783dfa7142284b0ebe5bd503fbGeorge Mount            OnMapChangedCallback<? extends ObservableMap<K, V>, K, V> listener) {
385cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        if (mListeners != null) {
395cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount            mListeners.remove(listener);
405cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        }
415cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    }
425cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount
435cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    @Override
445cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    public void clear() {
455cc4e7270573c2c1a101fdade15287b405cf7d9cGeorge Mount        boolean wasEmpty = isEmpty();
465cc4e7270573c2c1a101fdade15287b405cf7d9cGeorge Mount        if (!wasEmpty) {
475cc4e7270573c2c1a101fdade15287b405cf7d9cGeorge Mount            super.clear();
485cc4e7270573c2c1a101fdade15287b405cf7d9cGeorge Mount            notifyChange(null);
495cc4e7270573c2c1a101fdade15287b405cf7d9cGeorge Mount        }
505cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    }
515cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount
525cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    public V put(K k, V v) {
535cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        V val = super.put(k, v);
545cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        notifyChange(k);
555cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        return v;
565cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    }
575cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount
585cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    @Override
595cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    public boolean removeAll(Collection<?> collection) {
605cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        boolean removed = false;
615cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        for (Object key : collection) {
625cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount            int index = indexOfKey(key);
635cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount            if (index >= 0) {
645cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount                removed = true;
655cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount                removeAt(index);
665cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount            }
675cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        }
685cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        return removed;
695cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    }
705cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount
715cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    @Override
725cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    public boolean retainAll(Collection<?> collection) {
735cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        boolean removed = false;
745cc4e7270573c2c1a101fdade15287b405cf7d9cGeorge Mount        for (int i = size() - 1; i >= 0; i--) {
755cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount            Object key = keyAt(i);
765cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount            if (!collection.contains(key)) {
775cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount                removeAt(i);
785cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount                removed = true;
795cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount            }
805cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        }
815cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        return removed;
825cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    }
835cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount
845cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    @Override
855cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    public V removeAt(int index) {
865cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        K key = keyAt(index);
875cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        V value = super.removeAt(index);
885cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        if (value != null) {
895cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount            notifyChange(key);
905cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        }
915cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        return value;
925cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    }
935cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount
945cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    @Override
955cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    public V setValueAt(int index, V value) {
965cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        K key = keyAt(index);
975cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        V oldValue = super.setValueAt(index, value);
985cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        notifyChange(key);
995cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        return oldValue;
1005cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    }
1015cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount
1025cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    private void notifyChange(Object key) {
1035cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        if (mListeners != null) {
1045cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount            mListeners.notifyCallbacks(this, 0, key);
1055cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount        }
1065cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount    }
1075cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount}
108