Mercurial > projects > dwt2
annotate org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/ComputedList.d @ 97:c86eb8b3098e
packageimport
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Tue, 21 Apr 2009 11:18:25 +0200 |
parents | b74ac5dfcc06 |
children |
rev | line source |
---|---|
95
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
1 /************************************************************************************************************ |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
2 * Copyright (c) 2007 Matthew Hall and others. All rights reserved. This program and the |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
3 * accompanying materials are made available under the terms of the Eclipse Public License v1.0 which |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
4 * accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
5 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
6 * Contributors: |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
7 * Matthew Hall - initial API and implementation |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
8 * IBM Corporation - initial API and implementation |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
9 * Brad Reynolds - initial API and implementation (through bug 116920 and bug 147515) |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
10 * Matthew Hall - bug 211786 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
11 ***********************************************************************************************************/ |
96
b74ac5dfcc06
package to module and java.lang.all import
Frank Benoit <benoit@tionex.de>
parents:
95
diff
changeset
|
12 module org.eclipse.core.databinding.observable.list.ComputedList; |
97 | 13 import org.eclipse.core.databinding.observable.list.IListChangeListener; |
14 import org.eclipse.core.databinding.observable.list.AbstractObservableList; | |
15 import org.eclipse.core.databinding.observable.list.ListDiffEntry; | |
16 import org.eclipse.core.databinding.observable.list.ListDiff; | |
96
b74ac5dfcc06
package to module and java.lang.all import
Frank Benoit <benoit@tionex.de>
parents:
95
diff
changeset
|
17 |
b74ac5dfcc06
package to module and java.lang.all import
Frank Benoit <benoit@tionex.de>
parents:
95
diff
changeset
|
18 import java.lang.all; |
95
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
19 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
20 import java.util.ArrayList; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
21 import java.util.Collections; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
22 import java.util.List; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
23 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
24 import org.eclipse.core.databinding.observable.ChangeEvent; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
25 import org.eclipse.core.databinding.observable.Diffs; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
26 import org.eclipse.core.databinding.observable.IChangeListener; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
27 import org.eclipse.core.databinding.observable.IObservable; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
28 import org.eclipse.core.databinding.observable.IStaleListener; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
29 import org.eclipse.core.databinding.observable.ObservableTracker; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
30 import org.eclipse.core.databinding.observable.Realm; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
31 import org.eclipse.core.databinding.observable.StaleEvent; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
32 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
33 /** |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
34 * A Lazily calculated list that automatically computes and registers listeners |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
35 * on its dependencies as long as all of its dependencies are IObservable |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
36 * objects |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
37 * <p> |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
38 * This class is thread safe. All state accessing methods must be invoked from |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
39 * the {@link Realm#isCurrent() current realm}. Methods for adding and removing |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
40 * listeners may be invoked from any thread. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
41 * </p> |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
42 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
43 * @since 1.1 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
44 */ |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
45 public abstract class ComputedList : AbstractObservableList { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
46 private List cachedList = new ArrayList(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
47 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
48 private bool dirty = true; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
49 private bool stale = false; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
50 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
51 private IObservable[] dependencies = new IObservable[0]; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
52 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
53 /** |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
54 * Creates a computed list in the default realm and with an unknown (null) |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
55 * element type. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
56 */ |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
57 public this() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
58 this(Realm.getDefault(), null); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
59 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
60 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
61 /** |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
62 * Creates a computed list in the default realm and with the given element |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
63 * type. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
64 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
65 * @param elementType |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
66 * the element type, may be <code>null</code> to indicate |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
67 * unknown element type |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
68 */ |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
69 public this(Object elementType) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
70 this(Realm.getDefault(), elementType); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
71 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
72 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
73 /** |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
74 * Creates a computed list in given realm and with an unknown (null) element |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
75 * type. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
76 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
77 * @param realm |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
78 * the realm |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
79 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
80 */ |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
81 public this(Realm realm) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
82 this(realm, null); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
83 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
84 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
85 /** |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
86 * Creates a computed list in the given realm and with the given element |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
87 * type. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
88 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
89 * @param realm |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
90 * the realm |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
91 * @param elementType |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
92 * the element type, may be <code>null</code> to indicate |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
93 * unknown element type |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
94 */ |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
95 public this(Realm realm, Object elementType) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
96 super(realm); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
97 this.elementType = elementType; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
98 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
99 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
100 /** |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
101 * Inner class that implements interfaces that we don't want to expose as |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
102 * public API. Each interface could have been implemented using a separate |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
103 * anonymous class, but we combine them here to reduce the memory overhead |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
104 * and number of classes. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
105 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
106 * <p> |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
107 * The Runnable calls calculate and stores the result in cachedList. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
108 * </p> |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
109 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
110 * <p> |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
111 * The IChangeListener stores each observable in the dependencies list. This |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
112 * is registered as the listener when calling ObservableTracker, to detect |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
113 * every observable that is used by computeValue. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
114 * </p> |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
115 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
116 * <p> |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
117 * The IChangeListener is attached to every dependency. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
118 * </p> |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
119 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
120 */ |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
121 private class PrivateInterface : Runnable, IChangeListener, |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
122 IStaleListener { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
123 public void run() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
124 cachedList = calculate(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
125 if (cachedList is null) |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
126 cachedList = Collections.EMPTY_LIST; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
127 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
128 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
129 public void handleStale(StaleEvent event) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
130 if (!dirty) |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
131 makeStale(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
132 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
133 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
134 public void handleChange(ChangeEvent event) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
135 makeDirty(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
136 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
137 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
138 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
139 private PrivateInterface privateInterface = new PrivateInterface(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
140 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
141 private Object elementType; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
142 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
143 protected int doGetSize() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
144 return doGetList().size(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
145 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
146 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
147 public Object get(int index) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
148 getterCalled(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
149 return doGetList().get(index); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
150 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
151 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
152 private final List getList() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
153 getterCalled(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
154 return doGetList(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
155 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
156 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
157 final List doGetList() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
158 if (dirty) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
159 // This line will do the following: |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
160 // - Run the calculate method |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
161 // - While doing so, add any observable that is touched to the |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
162 // dependencies list |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
163 IObservable[] newDependencies = ObservableTracker.runAndMonitor( |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
164 privateInterface, privateInterface, null); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
165 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
166 // If any dependencies are stale, a stale event will be fired here |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
167 // even if we were already stale before recomputing. This is in case |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
168 // clients assume that a list change is indicative of non-staleness. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
169 stale = false; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
170 for (int i = 0; i < newDependencies.length; i++) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
171 if (newDependencies[i].isStale()) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
172 makeStale(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
173 break; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
174 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
175 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
176 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
177 if (!stale) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
178 for (int i = 0; i < newDependencies.length; i++) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
179 newDependencies[i].addStaleListener(privateInterface); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
180 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
181 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
182 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
183 dependencies = newDependencies; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
184 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
185 dirty = false; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
186 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
187 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
188 return cachedList; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
189 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
190 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
191 private void getterCalled() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
192 ObservableTracker.getterCalled(this); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
193 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
194 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
195 /** |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
196 * Subclasses must override this method to calculate the list contents. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
197 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
198 * @return the object's list. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
199 */ |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
200 protected abstract List calculate(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
201 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
202 private void makeDirty() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
203 if (!dirty) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
204 dirty = true; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
205 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
206 makeStale(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
207 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
208 stopListening(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
209 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
210 // copy the old list |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
211 final List oldList = new ArrayList(cachedList); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
212 // Fire the "dirty" event. This implementation recomputes the new |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
213 // list lazily. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
214 fireListChange(new class() ListDiff { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
215 ListDiffEntry[] differences; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
216 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
217 public ListDiffEntry[] getDifferences() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
218 if (differences is null) |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
219 differences = Diffs.computeListDiff(oldList, getList()) |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
220 .getDifferences(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
221 return differences; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
222 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
223 }); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
224 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
225 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
226 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
227 private void stopListening() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
228 if (dependencies !is null) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
229 for (int i = 0; i < dependencies.length; i++) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
230 IObservable observable = dependencies[i]; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
231 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
232 observable.removeChangeListener(privateInterface); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
233 observable.removeStaleListener(privateInterface); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
234 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
235 dependencies = null; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
236 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
237 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
238 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
239 private void makeStale() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
240 if (!stale) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
241 stale = true; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
242 fireStale(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
243 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
244 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
245 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
246 public bool isStale() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
247 // recalculate list if dirty, to ensure staleness is correct. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
248 getList(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
249 return stale; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
250 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
251 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
252 public Object getElementType() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
253 return elementType; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
254 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
255 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
256 public synchronized void addChangeListener(IChangeListener listener) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
257 super.addChangeListener(listener); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
258 // If somebody is listening, we need to make sure we attach our own |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
259 // listeners |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
260 computeListForListeners(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
261 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
262 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
263 public synchronized void addListChangeListener(IListChangeListener listener) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
264 super.addListChangeListener(listener); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
265 // If somebody is listening, we need to make sure we attach our own |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
266 // listeners |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
267 computeListForListeners(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
268 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
269 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
270 private void computeListForListeners() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
271 // Some clients just add a listener and expect to get notified even if |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
272 // they never called getValue(), so we have to call getValue() ourselves |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
273 // here to be sure. Need to be careful about realms though, this method |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
274 // can be called outside of our realm. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
275 // See also bug 198211. If a client calls this outside of our realm, |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
276 // they may receive change notifications before the runnable below has |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
277 // been executed. It is their job to figure out what to do with those |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
278 // notifications. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
279 getRealm().exec(new class() Runnable { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
280 public void run() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
281 if (dependencies is null) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
282 // We are not currently listening. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
283 // But someone is listening for changes. Call getValue() |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
284 // to make sure we start listening to the observables we |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
285 // depend on. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
286 getList(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
287 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
288 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
289 }); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
290 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
291 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
292 public synchronized void dispose() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
293 stopListening(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
294 super.dispose(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
295 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
296 } |