Mercurial > projects > dwt2
annotate org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/ComputedList.d @ 95:6208d4f6a277
Added trees for databinding.beans and observable
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Tue, 21 Apr 2009 10:55:51 +0200 |
parents | |
children | b74ac5dfcc06 |
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 ***********************************************************************************************************/ |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
12 package org.eclipse.core.databinding.observable.list; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
13 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
14 import java.util.ArrayList; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
15 import java.util.Collections; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
16 import java.util.List; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
17 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
18 import org.eclipse.core.databinding.observable.ChangeEvent; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
19 import org.eclipse.core.databinding.observable.Diffs; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
20 import org.eclipse.core.databinding.observable.IChangeListener; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
21 import org.eclipse.core.databinding.observable.IObservable; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
22 import org.eclipse.core.databinding.observable.IStaleListener; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
23 import org.eclipse.core.databinding.observable.ObservableTracker; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
24 import org.eclipse.core.databinding.observable.Realm; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
25 import org.eclipse.core.databinding.observable.StaleEvent; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
26 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
27 /** |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
28 * 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
|
29 * 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
|
30 * objects |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
31 * <p> |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
32 * 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
|
33 * 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
|
34 * listeners may be invoked from any thread. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
35 * </p> |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
36 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
37 * @since 1.1 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
38 */ |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
39 public abstract class ComputedList : AbstractObservableList { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
40 private List cachedList = new ArrayList(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
41 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
42 private bool dirty = true; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
43 private bool stale = false; |
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 private IObservable[] dependencies = new IObservable[0]; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
46 |
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 * 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
|
49 * element type. |
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 public this() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
52 this(Realm.getDefault(), null); |
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 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
55 /** |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
56 * 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
|
57 * type. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
58 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
59 * @param elementType |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
60 * 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
|
61 * unknown element type |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
62 */ |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
63 public this(Object elementType) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
64 this(Realm.getDefault(), elementType); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
65 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
66 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
67 /** |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
68 * 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
|
69 * type. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
70 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
71 * @param realm |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
72 * the realm |
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 */ |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
75 public this(Realm realm) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
76 this(realm, null); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
77 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
78 |
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 * 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
|
81 * type. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
82 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
83 * @param realm |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
84 * the realm |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
85 * @param elementType |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
86 * 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
|
87 * unknown element 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 public this(Realm realm, Object elementType) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
90 super(realm); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
91 this.elementType = elementType; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
92 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
93 |
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 * 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
|
96 * 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
|
97 * 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
|
98 * and number of classes. |
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 * <p> |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
101 * 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
|
102 * </p> |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
103 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
104 * <p> |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
105 * 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
|
106 * 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
|
107 * every observable that is used by computeValue. |
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 is attached to every dependency. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
112 * </p> |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
113 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
114 */ |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
115 private class PrivateInterface : Runnable, IChangeListener, |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
116 IStaleListener { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
117 public void run() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
118 cachedList = calculate(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
119 if (cachedList is null) |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
120 cachedList = Collections.EMPTY_LIST; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
121 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
122 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
123 public void handleStale(StaleEvent event) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
124 if (!dirty) |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
125 makeStale(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
126 } |
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 public void handleChange(ChangeEvent event) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
129 makeDirty(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
130 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
131 } |
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 private PrivateInterface privateInterface = new PrivateInterface(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
134 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
135 private Object elementType; |
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 protected int doGetSize() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
138 return doGetList().size(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
139 } |
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 public Object get(int index) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
142 getterCalled(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
143 return doGetList().get(index); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
144 } |
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 private final List getList() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
147 getterCalled(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
148 return doGetList(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
149 } |
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 final List doGetList() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
152 if (dirty) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
153 // This line will do the following: |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
154 // - Run the calculate method |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
155 // - 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
|
156 // dependencies list |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
157 IObservable[] newDependencies = ObservableTracker.runAndMonitor( |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
158 privateInterface, privateInterface, null); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
159 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
160 // 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
|
161 // 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
|
162 // 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
|
163 stale = false; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
164 for (int i = 0; i < newDependencies.length; i++) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
165 if (newDependencies[i].isStale()) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
166 makeStale(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
167 break; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
168 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
169 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
170 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
171 if (!stale) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
172 for (int i = 0; i < newDependencies.length; i++) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
173 newDependencies[i].addStaleListener(privateInterface); |
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 dependencies = newDependencies; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
178 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
179 dirty = false; |
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 return cachedList; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
183 } |
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 private void getterCalled() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
186 ObservableTracker.getterCalled(this); |
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 |
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 * 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
|
191 * |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
192 * @return the object's list. |
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 protected abstract List calculate(); |
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 private void makeDirty() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
197 if (!dirty) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
198 dirty = true; |
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 makeStale(); |
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 stopListening(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
203 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
204 // copy the old list |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
205 final List oldList = new ArrayList(cachedList); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
206 // 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
|
207 // list lazily. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
208 fireListChange(new class() ListDiff { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
209 ListDiffEntry[] differences; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
210 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
211 public ListDiffEntry[] getDifferences() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
212 if (differences is null) |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
213 differences = Diffs.computeListDiff(oldList, getList()) |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
214 .getDifferences(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
215 return 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 }); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
218 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
219 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
220 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
221 private void stopListening() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
222 if (dependencies !is null) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
223 for (int i = 0; i < dependencies.length; i++) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
224 IObservable observable = dependencies[i]; |
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 observable.removeChangeListener(privateInterface); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
227 observable.removeStaleListener(privateInterface); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
228 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
229 dependencies = null; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
230 } |
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 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
233 private void makeStale() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
234 if (!stale) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
235 stale = true; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
236 fireStale(); |
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 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
240 public bool isStale() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
241 // 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
|
242 getList(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
243 return stale; |
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 Object getElementType() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
247 return elementType; |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
248 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
249 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
250 public synchronized void addChangeListener(IChangeListener listener) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
251 super.addChangeListener(listener); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
252 // 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
|
253 // listeners |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
254 computeListForListeners(); |
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 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
257 public synchronized void addListChangeListener(IListChangeListener listener) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
258 super.addListChangeListener(listener); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
259 // 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
|
260 // listeners |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
261 computeListForListeners(); |
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 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
264 private void computeListForListeners() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
265 // 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
|
266 // 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
|
267 // 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
|
268 // can be called outside of our realm. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
269 // 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
|
270 // 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
|
271 // 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
|
272 // notifications. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
273 getRealm().exec(new class() Runnable { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
274 public void run() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
275 if (dependencies is null) { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
276 // We are not currently listening. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
277 // But someone is listening for changes. Call getValue() |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
278 // 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
|
279 // depend on. |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
280 getList(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
281 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
282 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
283 }); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
284 } |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
285 |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
286 public synchronized void dispose() { |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
287 stopListening(); |
6208d4f6a277
Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
288 super.dispose(); |
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 } |