Merge "Revert "Added Bindable annotation processor.""
diff --git a/KDataBinder/.idea/uiDesigner.xml b/KDataBinder/.idea/uiDesigner.xml
deleted file mode 100644
index e96534f..0000000
--- a/KDataBinder/.idea/uiDesigner.xml
+++ /dev/null
@@ -1,124 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="Palette2">
- <group name="Swing">
- <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
- </item>
- <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
- </item>
- <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
- </item>
- <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
- <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
- </item>
- <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
- <initial-values>
- <property name="text" value="Button" />
- </initial-values>
- </item>
- <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
- <initial-values>
- <property name="text" value="RadioButton" />
- </initial-values>
- </item>
- <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
- <initial-values>
- <property name="text" value="CheckBox" />
- </initial-values>
- </item>
- <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
- <initial-values>
- <property name="text" value="Label" />
- </initial-values>
- </item>
- <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
- <preferred-size width="150" height="-1" />
- </default-constraints>
- </item>
- <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
- <preferred-size width="150" height="-1" />
- </default-constraints>
- </item>
- <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
- <preferred-size width="150" height="-1" />
- </default-constraints>
- </item>
- <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
- <preferred-size width="150" height="50" />
- </default-constraints>
- </item>
- <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
- <preferred-size width="150" height="50" />
- </default-constraints>
- </item>
- <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
- <preferred-size width="150" height="50" />
- </default-constraints>
- </item>
- <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
- </item>
- <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
- <preferred-size width="150" height="50" />
- </default-constraints>
- </item>
- <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
- <preferred-size width="150" height="50" />
- </default-constraints>
- </item>
- <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
- <preferred-size width="150" height="50" />
- </default-constraints>
- </item>
- <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
- <preferred-size width="200" height="200" />
- </default-constraints>
- </item>
- <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
- <preferred-size width="200" height="200" />
- </default-constraints>
- </item>
- <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
- </item>
- <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
- </item>
- <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
- </item>
- <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
- </item>
- <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
- <preferred-size width="-1" height="20" />
- </default-constraints>
- </item>
- <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
- </item>
- <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
- </item>
- </group>
- </component>
-</project>
\ No newline at end of file
diff --git a/annotationprocessor/build.gradle b/annotationprocessor/build.gradle
deleted file mode 100644
index 19c563d..0000000
--- a/annotationprocessor/build.gradle
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-apply plugin: 'java'
-apply plugin: 'maven'
-
-buildscript {
- repositories {
- mavenLocal()
- mavenCentral()
- }
-}
-
-repositories {
- mavenCentral()
-}
-
-sourceSets {
- main {
- java {
- srcDir 'src/main/java'
- }
- }
-}
-
-uploadArchives {
- repositories {
- mavenDeployer {
- repository(url: mavenLocal().url)
- pom.version = '0.1-SNAPSHOT'
- pom.artifactId = 'annotationprocessor'
- pom.groupId='com.android.databinding'
- }
- }
-}
diff --git a/library/src/main/java/com/android/databinding/library/AbsObservable.java b/library/src/main/java/com/android/databinding/library/AbsObservable.java
deleted file mode 100644
index 9a2f438..0000000
--- a/library/src/main/java/com/android/databinding/library/AbsObservable.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2014 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 com.android.databinding.library;
-
-public abstract class AbsObservable implements Observable {
- private ChangeListenerRegistry mCallbacks;
-
- public AbsObservable() {
- }
-
- @Override
- public synchronized void addListener(OnPropertyChangedListener listener) {
- if (mCallbacks == null) {
- mCallbacks = new ChangeListenerRegistry();
- }
- mCallbacks.add(listener);
- }
-
- @Override
- public synchronized void removeListener(OnPropertyChangedListener listener) {
- if (mCallbacks != null) {
- mCallbacks.remove(listener);
- }
- }
-
- public synchronized void notifyChange() {
- if (mCallbacks != null) {
- mCallbacks.notifyCallbacks(this, 0);
- }
- }
-
- public synchronized void notifyChange(int id) {
- if (mCallbacks != null) {
- mCallbacks.notifyCallbacks(this, id);
- }
- }
-}
diff --git a/library/src/main/java/com/android/databinding/library/BaseObservable.java b/library/src/main/java/com/android/databinding/library/BaseObservable.java
new file mode 100644
index 0000000..30c4a74
--- /dev/null
+++ b/library/src/main/java/com/android/databinding/library/BaseObservable.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2014 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 com.android.databinding.library;
+
+import java.util.concurrent.CopyOnWriteArraySet;
+
+public class BaseObservable implements Observable {
+ final ObservableHelper mHelper;
+
+ public BaseObservable() {
+ mHelper = new ObservableHelper(this);
+ }
+
+ @Override
+ public void register(ObservableListener listener) {
+ mHelper.register(listener);
+ }
+
+ @Override
+ public void unRegister(ObservableListener listener) {
+ mHelper.unRegister(listener);
+ }
+
+ public void fireChange() {
+ mHelper.fireChange();
+ }
+ public void fireChange(String fieldName) {
+ mHelper.fireChange(fieldName);
+ }
+ public void fireChange(int fieldId) {mHelper.fireChange(fieldId);}
+}
diff --git a/library/src/main/java/com/android/databinding/library/CallbackRegistry.java b/library/src/main/java/com/android/databinding/library/CallbackRegistry.java
deleted file mode 100644
index 820561f..0000000
--- a/library/src/main/java/com/android/databinding/library/CallbackRegistry.java
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Copyright (C) 2014 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 com.android.databinding.library;
-
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Tracks callbacks for the event. This class supports reentrant modification
- * of the callbacks during notification without adversely disrupting notifications.
- * A common pattern for callbacks is to receive a notification and then remove
- * themselves. This class handles this behavior with constant memory under
- * most circumstances.
- *
- * <p>A subclass of {@link com.android.databinding.library.CallbackRegistry.NotifierCallback} must be passed to
- * the constructor to define how notifications should be called. That implementation
- * does the actual notification on the listener.</p>
- *
- * <p>This class supports only callbacks with at most two parameters.
- * Typically, these are the notification originator and a parameter, but these may
- * be used as required. If more than two parameters are required or primitive types
- * must be used, <code>A</code> should be some kind of containing structure that
- * the subclass may reuse between notifications.</p>
- *
- * @param <C> The callback type.
- * @param <T> The notification sender type. Typically this is the containing class.
- */
-public class CallbackRegistry<C, T> implements Cloneable {
- private static final String TAG = "CallbackRegistry";
-
- /** An ordered collection of listeners waiting to be notified. */
- private List<C> mCallbacks = new ArrayList<C>();
-
- /**
- * A bit flag for the first 64 listeners that are removed during notification.
- * The lowest significant bit corresponds to the 0th index into mCallbacks.
- * For a small number of callbacks, no additional array of objects needs to
- * be allocated.
- */
- private long mFirst64Removed = 0x0;
-
- /**
- * Bit flags for the remaining callbacks that are removed during notification.
- * When there are more than 64 callbacks and one is marked for removal, a dynamic
- * array of bits are allocated for the callbacks.
- */
- private long[] mRemainderRemoved;
-
- /** The recursion level of the notification */
- private int mNotificationLevel;
-
- /** The notification mechanism for notifying an event. */
- private final NotifierCallback<C, T> mNotifier;
-
- /**
- * Creates an EventRegistry that notifies the event with notifier.
- * @param notifier The class to use to notify events.
- */
- public CallbackRegistry(NotifierCallback<C, T> notifier) {
- mNotifier = notifier;
- }
-
- /**
- * Notify all callbacks.
- *
- * @param sender The originator. This is an opaque parameter passed to
- * {@link com.android.databinding.library.CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int)}
- * @param arg An opaque parameter passed to
- * {@link com.android.databinding.library.CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int)}
- */
- public synchronized void notifyCallbacks(T sender, int arg) {
- mNotificationLevel++;
- notifyRecurse(sender, arg);
- mNotificationLevel--;
- if (mNotificationLevel == 0) {
- if (mRemainderRemoved != null) {
- for (int i = mRemainderRemoved.length - 1; i >= 0; i--) {
- final long removedBits = mRemainderRemoved[i];
- if (removedBits != 0) {
- removeRemovedCallbacks((i + 1) * Long.SIZE, removedBits);
- mRemainderRemoved[i] = 0;
- }
- }
- }
- if (mFirst64Removed != 0) {
- removeRemovedCallbacks(0, mFirst64Removed);
- mFirst64Removed = 0;
- }
- }
- }
-
- /**
- * Notify up to the first Long.SIZE callbacks that don't have a bit set in <code>removed</code>.
- *
- * @param sender The originator. This is an opaque parameter passed to
- * {@link com.android.databinding.library.CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int)}
- * @param arg An opaque parameter passed to
- * {@link com.android.databinding.library.CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int)}
- */
- private void notifyFirst64(T sender, int arg) {
- final int maxNotified = Math.min(Long.SIZE, mCallbacks.size());
- notifyCallbacks(sender, arg, 0, maxNotified, mFirst64Removed);
- }
-
- /**
- * Notify all callbacks using a recursive algorithm to avoid allocating on the heap.
- * This part captures the callbacks beyond Long.SIZE that have no bits allocated for
- * removal before it recurses into {@link #notifyRemainder(Object, int, int)}.
- *
- * <p>Recursion is used to avoid allocating temporary state on the heap.</p>
- *
- * @param sender The originator. This is an opaque parameter passed to
- * {@link com.android.databinding.library.CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int)}
- * @param arg An opaque parameter passed to
- * {@link com.android.databinding.library.CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int)}
- */
- private void notifyRecurse(T sender, int arg) {
- final int callbackCount = mCallbacks.size();
- final int remainderIndex = mRemainderRemoved == null ? -1 : mRemainderRemoved.length - 1;
-
- // Now we've got all callbakcs that have no mRemainderRemoved value, so notify the
- // others.
- notifyRemainder(sender, arg, remainderIndex);
-
- // notifyRemainder notifies all at maxIndex, so we'd normally start at maxIndex + 1
- // However, we must also keep track of those in mFirst64Removed, so we add 2 instead:
- final int startCallbackIndex = (remainderIndex + 2) * Long.SIZE;
-
- // The remaining have no bit set
- notifyCallbacks(sender, arg, startCallbackIndex, callbackCount, 0);
- }
-
- /**
- * Notify callbacks that have mRemainderRemoved bits set for remainderIndex. If
- * remainderIndex is -1, the first 64 will be notified instead.
- *
- * @param sender The originator. This is an opaque parameter passed to
- * {@link com.android.databinding.library.CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int)}
- * @param arg An opaque parameter passed to
- * {@link com.android.databinding.library.CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int)}
- * @param remainderIndex The index into mRemainderRemoved that should be notified.
- */
- private void notifyRemainder(T sender, int arg, int remainderIndex) {
- if (remainderIndex < 0) {
- notifyFirst64(sender, arg);
- } else {
- final long bits = mRemainderRemoved[remainderIndex];
- final int startIndex = (remainderIndex + 1) * Long.SIZE;
- final int endIndex = Math.min(mCallbacks.size(), startIndex + Long.SIZE);
- notifyRemainder(sender, arg, remainderIndex - 1);
- notifyCallbacks(sender, arg, startIndex, endIndex, bits);
- }
- }
-
- /**
- * Notify callbacks from startIndex to endIndex, using bits as the bit status
- * for whether they have been removed or not. bits should be from mRemainderRemoved or
- * mFirst64Removed. bits set to 0 indicates that all callbacks from startIndex to
- * endIndex should be notified.
- *
- * @param sender The originator. This is an opaque parameter passed to
- * {@link com.android.databinding.library.CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int)}
- * @param arg An opaque parameter passed to
- * {@link com.android.databinding.library.CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int)}
- * @param startIndex The index into the mCallbacks to start notifying.
- * @param endIndex One past the last index into mCallbacks to notify.
- * @param bits A bit field indicating which callbacks have been removed and shouldn't
- * be notified.
- */
- private void notifyCallbacks(T sender, int arg, final int startIndex, final int endIndex,
- final long bits) {
- long bitMask = 1;
- for (int i = startIndex; i < endIndex; i++) {
- if ((bits & bitMask) == 0) {
- mNotifier.onNotifyCallback(mCallbacks.get(i), sender, arg);
- }
- bitMask <<= 1;
- }
- }
-
- /**
- * Add a callback to be notified. If the callback is already in the list, another won't
- * be added. This does not affect current notifications.
- * @param callback The callback to add.
- */
- public synchronized void add(C callback) {
- int index = mCallbacks.lastIndexOf(callback);
- if (index < 0 || isRemoved(index)) {
- mCallbacks.add(callback);
- }
- }
-
- /**
- * Returns true if the callback at index has been marked for removal.
- *
- * @param index The index into mCallbacks to check.
- * @return true if the callback at index has been marked for removal.
- */
- private boolean isRemoved(int index) {
- if (index < Long.SIZE) {
- // It is in the first 64 callbacks, just check the bit.
- final long bitMask = 1L << index;
- return (mFirst64Removed & bitMask) != 0;
- } else if (mRemainderRemoved == null) {
- // It is after the first 64 callbacks, but nothing else was marked for removal.
- return false;
- } else {
- final int maskIndex = (index / Long.SIZE) - 1;
- if (maskIndex >= mRemainderRemoved.length) {
- // There are some items in mRemainderRemoved, but nothing at the given index.
- return false;
- } else {
- // There is something marked for removal, so we have to check the bit.
- final long bits = mRemainderRemoved[maskIndex];
- final long bitMask = 1L << (index % Long.SIZE);
- return (bits & bitMask) != 0;
- }
- }
- }
-
- /**
- * Removes callbacks from startIndex to startIndex + Long.SIZE, based
- * on the bits set in removed.
- * @param startIndex The index into the mCallbacks to start removing callbacks.
- * @param removed The bits indicating removal, where each bit is set for one callback
- * to be removed.
- */
- private void removeRemovedCallbacks(int startIndex, long removed) {
- // The naive approach should be fine. There may be a better bit-twiddling approach.
- final int endIndex = startIndex + Long.SIZE;
-
- long bitMask = 1L << (Long.SIZE - 1);
- for (int i = endIndex - 1; i >= startIndex; i--) {
- if ((removed & bitMask) != 0) {
- mCallbacks.remove(i);
- }
- bitMask >>>= 1;
- }
- }
-
- /**
- * Remove a callback. This callback won't be notified after this call completes.
- * @param callback The callback to remove.
- */
- public synchronized void remove(C callback) {
- if (mNotificationLevel == 0) {
- mCallbacks.remove(callback);
- } else {
- int index = mCallbacks.lastIndexOf(callback);
- if (index >= 0) {
- setRemovalBit(index);
- }
- }
- }
-
- private void setRemovalBit(int index) {
- if (index < Long.SIZE) {
- // It is in the first 64 callbacks, just check the bit.
- final long bitMask = 1L << index;
- mFirst64Removed |= bitMask;
- } else {
- final int remainderIndex = (index / Long.SIZE) - 1;
- if (mRemainderRemoved == null) {
- mRemainderRemoved = new long[mCallbacks.size() / Long.SIZE];
- } else if (mRemainderRemoved.length < remainderIndex) {
- // need to make it bigger
- long[] newRemainders = new long[mCallbacks.size() / Long.SIZE];
- System.arraycopy(mRemainderRemoved, 0, newRemainders, 0, mRemainderRemoved.length);
- mRemainderRemoved = newRemainders;
- }
- final long bitMask = 1L << (index % Long.SIZE);
- mRemainderRemoved[remainderIndex] |= bitMask;
- }
- }
-
- /*
- private void clearRemovalBit(int index) {
- if (index < Long.SIZE) {
- // It is in the first 64 callbacks, just check the bit.
- final long bitMask = 1L << index;
- mFirst64Removed &= ~bitMask;
- } else if (mRemainderRemoved != null) {
- final int maskIndex = (index / Long.SIZE) - 1;
- if (maskIndex < mRemainderRemoved.length) {
- // There is something marked for removal, so we have to check the bit.
- final long bitMask = 1L << (index % Long.SIZE);
- mRemainderRemoved[maskIndex] &= ~bitMask;
- }
- }
- }
- */
-
- /**
- * Makes a copy of the registered callbacks and returns it.
- *
- * @return a copy of the registered callbacks.
- */
- public synchronized ArrayList<C> copyListeners() {
- ArrayList<C> callbacks = new ArrayList<C>(mCallbacks.size());
- int numListeners = mCallbacks.size();
- for (int i = 0; i < numListeners; i++) {
- if (!isRemoved(i)) {
- callbacks.add(mCallbacks.get(i));
- }
- }
- return callbacks;
- }
-
- /**
- * Returns true if there are no registered callbacks or false otherwise.
- *
- * @return true if there are no registered callbacks or false otherwise.
- */
- public synchronized boolean isEmpty() {
- if (mCallbacks.isEmpty()) {
- return true;
- } else if (mNotificationLevel == 0) {
- return false;
- } else {
- int numListeners = mCallbacks.size();
- for (int i = 0; i < numListeners; i++) {
- if (!isRemoved(i)) {
- return false;
- }
- }
- return true;
- }
- }
-
- /**
- * Removes all callbacks from the list.
- */
- public synchronized void clear() {
- if (mNotificationLevel == 0) {
- mCallbacks.clear();
- } else if (!mCallbacks.isEmpty()) {
- for (int i = mCallbacks.size() - 1; i >= 0; i--) {
- setRemovalBit(i);
- }
- }
- }
-
- public synchronized CallbackRegistry<C, T> clone() {
- CallbackRegistry<C, T> clone = null;
- try {
- clone = (CallbackRegistry<C, T>) super.clone();
- clone.mFirst64Removed = 0;
- clone.mRemainderRemoved = null;
- clone.mNotificationLevel = 0;
- clone.mCallbacks = new ArrayList<C>();
- final int numListeners = mCallbacks.size();
- for (int i = 0; i < numListeners; i++) {
- if (!isRemoved(i)) {
- clone.mCallbacks.add(mCallbacks.get(i));
- }
- }
- } catch (CloneNotSupportedException e) {
- Log.e(TAG, "Could not clone CallbackRegistry", e);
- }
- return clone;
- }
-
- /**
- * Class used to notify events from CallbackRegistry.
- *
- * @param <C> The callback type.
- * @param <T> The notification sender type. Typically this is the containing class.
- */
- public abstract static class NotifierCallback<C, T> {
- /**
- * Used to notify the callback.
- *
- * @param callback The callback to notify.
- * @param sender The opaque sender object.
- * @param arg The opaque notification parameter.
- * @see CallbackRegistry#CallbackRegistry(com.android.databinding.library.CallbackRegistry.NotifierCallback)
- */
- public abstract void onNotifyCallback(C callback, T sender, int arg);
- }
-}
diff --git a/library/src/main/java/com/android/databinding/library/ChangeListenerRegistry.java b/library/src/main/java/com/android/databinding/library/ChangeListenerRegistry.java
deleted file mode 100644
index 46de743..0000000
--- a/library/src/main/java/com/android/databinding/library/ChangeListenerRegistry.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2014 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 com.android.databinding.library;
-
-/**
- * Created by mount on 12/15/14.
- */
-public class ChangeListenerRegistry extends
- CallbackRegistry<OnPropertyChangedListener, Observable> {
-
- private static final CallbackRegistry.NotifierCallback<OnPropertyChangedListener, Observable> NOTIFIER_CALLBACK = new CallbackRegistry.NotifierCallback<OnPropertyChangedListener, Observable>() {
- @Override
- public void onNotifyCallback(OnPropertyChangedListener callback, Observable sender,
- int arg) {
- callback.onPropertyChanged(arg);
- }
- };
-
- public ChangeListenerRegistry() {
- super(NOTIFIER_CALLBACK);
- }
-}
diff --git a/library/src/main/java/com/android/databinding/library/Observable.java b/library/src/main/java/com/android/databinding/library/Observable.java
index 59ffd0e..e825dd5 100644
--- a/library/src/main/java/com/android/databinding/library/Observable.java
+++ b/library/src/main/java/com/android/databinding/library/Observable.java
@@ -17,6 +17,6 @@
package com.android.databinding.library;
public interface Observable {
- public void addListener(OnPropertyChangedListener listener);
- public void removeListener(OnPropertyChangedListener listener);
+ public void register(ObservableListener listener);
+ public void unRegister(ObservableListener listener);
}
diff --git a/library/src/main/java/com/android/databinding/library/ObservableHelper.java b/library/src/main/java/com/android/databinding/library/ObservableHelper.java
new file mode 100644
index 0000000..bac5686
--- /dev/null
+++ b/library/src/main/java/com/android/databinding/library/ObservableHelper.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 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 com.android.databinding.library;
+
+import java.util.concurrent.CopyOnWriteArraySet;
+
+public class ObservableHelper implements Observable {
+ final Observable owner;
+ CopyOnWriteArraySet<ObservableListener> mListeners;
+
+ public ObservableHelper(Observable owner) {
+ this.owner = owner;
+ }
+
+ private synchronized CopyOnWriteArraySet<ObservableListener> getListeners(boolean createIfMissing) {
+ if (mListeners == null) {
+ if (createIfMissing) {
+ mListeners = new CopyOnWriteArraySet<>();
+ }
+ }
+ return mListeners;
+ }
+
+ public void fireChange() {
+ fireChange("");
+ }
+ public void fireChange(String fieldName) {
+ fireChange(DataBinder.convertToId(fieldName));
+ }
+ public void fireChange(int fieldId) {
+ final CopyOnWriteArraySet<ObservableListener> listeners = getListeners(false);
+ if (listeners == null) {
+ return;
+ }
+ for (ObservableListener listener : listeners) {
+ listener.onChange(fieldId);
+ }
+ }
+
+ @Override
+ public void register(ObservableListener listener) {
+ getListeners(true).add(listener);
+ }
+
+ @Override
+ public void unRegister(ObservableListener listener) {
+ final CopyOnWriteArraySet<ObservableListener> listeners = getListeners(false);
+ if (listener != null) {
+ listeners.remove(listener);
+ }
+ }
+}
diff --git a/library/src/main/java/com/android/databinding/library/OnPropertyChangedListener.java b/library/src/main/java/com/android/databinding/library/ObservableListener.java
similarity index 86%
rename from library/src/main/java/com/android/databinding/library/OnPropertyChangedListener.java
rename to library/src/main/java/com/android/databinding/library/ObservableListener.java
index eab1e9c..04ccd38 100644
--- a/library/src/main/java/com/android/databinding/library/OnPropertyChangedListener.java
+++ b/library/src/main/java/com/android/databinding/library/ObservableListener.java
@@ -16,6 +16,7 @@
package com.android.databinding.library;
-public interface OnPropertyChangedListener {
- public void onPropertyChanged(int fieldId);
+public interface ObservableListener {
+ public void onChange();
+ public void onChange(int fieldId);
}
diff --git a/library/src/main/java/com/android/databinding/library/ViewDataBinder.java b/library/src/main/java/com/android/databinding/library/ViewDataBinder.java
index c0ac85c..f1a3bf5 100644
--- a/library/src/main/java/com/android/databinding/library/ViewDataBinder.java
+++ b/library/src/main/java/com/android/databinding/library/ViewDataBinder.java
@@ -16,11 +16,16 @@
package com.android.databinding.library;
+import android.util.SparseIntArray;
import android.view.View;
import java.lang.Override;
import java.lang.Runnable;
import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
abstract public class ViewDataBinder {
WeakReferencedListener[] mLocalFieldObservers;
@@ -107,7 +112,7 @@
listener.setTarget(observable);
}
- protected abstract class WeakReferencedListener implements OnPropertyChangedListener {
+ protected abstract class WeakReferencedListener implements ObservableListener {
WeakReference<Observable> mTarget;
public WeakReferencedListener() {
@@ -116,7 +121,7 @@
public void setTarget(Observable observable) {
if (observable != null) {
mTarget = new WeakReference<>(observable);
- observable.addListener(this);
+ observable.register(this);
} else {
mTarget = null;
}
@@ -125,7 +130,7 @@
public boolean unregister() {
Observable oldTarget = getTarget();
if (oldTarget != null) {
- oldTarget.removeListener(this);
+ oldTarget.unRegister(this);
}
mTarget = null;
return oldTarget != null;
@@ -143,7 +148,16 @@
}
@Override
- public void onPropertyChanged(int fieldId) {
+ public void onChange() {
+ Observable obj = getTarget();
+ if (obj == null) {
+ return;//how come i live if it died ?
+ }
+ ViewDataBinder.this.handleFieldChange(mLocalFieldId, obj, 0);
+ }
+
+ @Override
+ public void onChange(int fieldId) {
Observable obj = getTarget();
if (obj == null) {
return;//how come i live if it died ?
diff --git a/samples/BindingDemo/app/build.gradle b/samples/BindingDemo/app/build.gradle
index 2347998..45e7ebe 100644
--- a/samples/BindingDemo/app/build.gradle
+++ b/samples/BindingDemo/app/build.gradle
@@ -17,8 +17,6 @@
apply plugin: 'com.android.application'
apply plugin: 'com.android.databinding'
-def generatedSources = "$buildDir/generated/source/br"
-
android {
compileSdkVersion 21
buildToolsVersion "21.1.1"
@@ -40,19 +38,6 @@
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
- sourceSets {
- //main.java.srcDirs += generatedSources
- }
-}
-
-android.applicationVariants.all { variant ->
- variant.javaCompile.doFirst {
- println "*** compile doFirst ${variant.name}"
- new File(generatedSources).mkdirs()
- variant.javaCompile.options.compilerArgs += [
- '-s', generatedSources
- ]
- }
}
dependencies {
@@ -62,5 +47,4 @@
compile 'com.android.support:recyclerview-v7:21.0.2'
compile 'com.android.support:gridlayout-v7:21+'
compile 'com.android.support:cardview-v7:21.0.2'
- provided 'com.android.databinding:annotationprocessor:0.1-SNAPSHOT'
}
diff --git a/samples/BindingDemo/app/src/main/java/com/android/example/bindingdemo/MainActivity.java b/samples/BindingDemo/app/src/main/java/com/android/example/bindingdemo/MainActivity.java
index 02f3d7b..51b1c90 100644
--- a/samples/BindingDemo/app/src/main/java/com/android/example/bindingdemo/MainActivity.java
+++ b/samples/BindingDemo/app/src/main/java/com/android/example/bindingdemo/MainActivity.java
@@ -1,6 +1,5 @@
package com.android.example.bindingdemo;
-import android.binding.Bindable;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
@@ -10,14 +9,15 @@
import android.view.View;
import android.view.ViewGroup;
-import com.android.databinding.library.ChangeListenerRegistry;
-import com.android.databinding.library.Observable;
-import com.android.databinding.library.OnPropertyChangedListener;
+import com.android.example.bindingdemo.generated.BR;
import com.android.example.bindingdemo.generated.ListItemBinder;
import com.android.example.bindingdemo.generated.MainActivityBinder;
import com.android.example.bindingdemo.vo.User;
import com.android.example.bindingdemo.vo.Users;
import com.android.databinding.library.DataBinder;
+import com.android.databinding.library.Observable;
+import com.android.databinding.library.ObservableHelper;
+import com.android.databinding.library.ObservableListener;
import java.util.ArrayList;
import java.util.Arrays;
@@ -28,13 +28,13 @@
UserAdapter tkAdapter;
UserAdapter robotAdapter;
MainActivityBinder dataBinder;
- @Bindable
User selected;
- ChangeListenerRegistry mChangeListeners = new ChangeListenerRegistry();
+ ObservableHelper helper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ helper = new ObservableHelper(this);
dataBinder = DataBinder.createBinder(MainActivityBinder.class, this, R.layout.main_activity, null);
setContentView(dataBinder.getRoot());
dataBinder.getRobotList().setHasFixedSize(true);
@@ -64,7 +64,7 @@
return;
}
this.selected = selected;
- mChangeListeners.notifyCallbacks(this, android.binding.BR.selected);
+ helper.fireChange(BR.selected);
}
public View.OnClickListener onSave = new View.OnClickListener() {
@@ -130,20 +130,21 @@
}
@Override
- public void addListener(OnPropertyChangedListener onPropertyChangedListener) {
- mChangeListeners.add(onPropertyChangedListener);
+ public void register(ObservableListener observableListener) {
+ helper.register(observableListener);
}
@Override
- public void removeListener(OnPropertyChangedListener onPropertyChangedListener) {
- mChangeListeners.remove(onPropertyChangedListener);
+ public void unRegister(ObservableListener observableListener) {
+ helper.unRegister(observableListener);
}
public class UserAdapter extends DataBoundAdapter<ListItemBinder> implements View.OnClickListener, Observable {
- List<User> userList = new ArrayList<User>();
- ChangeListenerRegistry mChangeListeners = new ChangeListenerRegistry();
+ List<User> userList = new ArrayList<>();
+ ObservableHelper mHelper;
public UserAdapter(User[] toolkities) {
super(R.layout.list_item, ListItemBinder.class);
+ mHelper = new ObservableHelper(this);
userList.addAll(Arrays.asList(toolkities));
}
@@ -161,7 +162,6 @@
}
@Override
- @Bindable
public int getItemCount() {
return userList.size();
}
@@ -172,7 +172,7 @@
}
userList.add(user);
notifyItemInserted(userList.size() - 1);
- mChangeListeners.notifyCallbacks(this, android.binding.BR.itemCount);
+ mHelper.fireChange("itemCount");
}
public void remove(User user) {
@@ -182,7 +182,7 @@
}
userList.remove(i);
notifyItemRemoved(i);
- mChangeListeners.notifyCallbacks(this, android.binding.BR.itemCount);
+ mHelper.fireChange("itemCount");
}
@Override
@@ -198,13 +198,13 @@
}
@Override
- public void addListener(OnPropertyChangedListener onPropertyChangedListener) {
- mChangeListeners.add(onPropertyChangedListener);
+ public void register(ObservableListener observableListener) {
+ mHelper.register(observableListener);
}
@Override
- public void removeListener(OnPropertyChangedListener onPropertyChangedListener) {
- mChangeListeners.remove(onPropertyChangedListener);
+ public void unRegister(ObservableListener observableListener) {
+ mHelper.unRegister(observableListener);
}
}
}
diff --git a/samples/BindingDemo/app/src/main/java/com/android/example/bindingdemo/vo/User.java b/samples/BindingDemo/app/src/main/java/com/android/example/bindingdemo/vo/User.java
index 8ea225d..091dc5c 100644
--- a/samples/BindingDemo/app/src/main/java/com/android/example/bindingdemo/vo/User.java
+++ b/samples/BindingDemo/app/src/main/java/com/android/example/bindingdemo/vo/User.java
@@ -1,23 +1,17 @@
package com.android.example.bindingdemo.vo;
-import android.binding.Bindable;
import android.graphics.Color;
-import com.android.databinding.library.AbsObservable;
+import com.android.databinding.library.BaseObservable;
import java.util.Objects;
-public class User extends AbsObservable {
- @Bindable
+public class User extends BaseObservable {
private String name;
- @Bindable
private String lastName;
- @Bindable
private int photoResource = 0;
private int favoriteColor = Color.RED;
- @Bindable
private int group;
-
public static final int TOOLKITTY = 1;
public static final int ROBOT = 2;
@@ -33,7 +27,7 @@
return;
}
this.group = group;
- notifyChange(android.binding.BR.group);
+ fireChange("group");
}
public int getGroup() {
@@ -49,7 +43,7 @@
return;
}
this.name = name;
- notifyChange(android.binding.BR.name);
+ fireChange("name");
}
public String getLastName() {
@@ -61,7 +55,7 @@
return;
}
this.lastName = lastName;
- notifyChange(android.binding.BR.lastName);
+ fireChange("lastName");
}
public int getPhotoResource() {
@@ -73,7 +67,7 @@
return;
}
this.photoResource = photoResource;
- notifyChange(android.binding.BR.photoResource);
+ fireChange("photoResource");
}
public int getFavoriteColor() {
diff --git a/samples/BindingDemo/gradle/wrapper/gradle-wrapper.properties b/samples/BindingDemo/gradle/wrapper/gradle-wrapper.properties
index 1d32c67..ddbd613 100644
--- a/samples/BindingDemo/gradle/wrapper/gradle-wrapper.properties
+++ b/samples/BindingDemo/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,22 @@
-#Mon Dec 15 15:24:30 PST 2014
+#
+# Copyright (C) 2014 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.
+#
+
+#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-all.zip
diff --git a/settings.gradle b/settings.gradle
index e1f91a6..c069a57 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,4 +1,4 @@
-include ':library', ':annotationprocessor'
+include ':library'
include ':compiler'
include ':gradlePlugin'
-include ':grammerBuilder'
+include ':grammerBuilder'
\ No newline at end of file