annotate org.eclipse.core.databinding/src/org/eclipse/core/databinding/observable/ObservableTracker.d @ 78:0a55d2d5a946

Added file for databinding
author Frank Benoit <benoit@tionex.de>
date Tue, 14 Apr 2009 11:35:29 +0200
parents
children 383ce7bd736b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
78
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1 /*******************************************************************************
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
2 * Copyright (c) 2005, 2008 IBM Corporation and others.
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
3 * All rights reserved. This program and the accompanying materials
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
4 * are made available under the terms of the Eclipse Public License v1.0
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
5 * which accompanies this distribution, and is available at
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
6 * http://www.eclipse.org/legal/epl-v10.html
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
7 *
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
8 * Contributors:
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
9 * IBM Corporation - initial API and implementation
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
10 * Matthew Hall - Fix NPE, more detailed assert messages (bug 210115)
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
11 *******************************************************************************/
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
12 module org.eclipse.core.databinding.observable.ObservableTracker;
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
13
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
14 import java.lang.all;
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
15
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
16 import java.util.HashSet;
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
17 import java.util.Iterator;
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
18 import java.util.Set;
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
19
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
20 import org.eclipse.core.internal.databinding.IdentityWrapper;
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
21 import org.eclipse.core.runtime.Assert;
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
22
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
23 /**
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
24 * This class makes it possible to monitor whenever an IObservable is read from.
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
25 * This can be used to automatically attach and remove listeners. How to use it:
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
26 *
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
27 * <p>
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
28 * If you are implementing an IObservable, invoke getterCalled(this) whenever a
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
29 * getter is called - that is, whenever your observable is read from. You only
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
30 * need to do this once per method call. If one getter delegates to another, the
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
31 * outer getter doesn't need to call the method since the inner one will.
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
32 * </p>
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
33 *
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
34 * <p>
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
35 * If you want to determine what observables were used in a particular block of
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
36 * code, call runAndMonitorcast(Runnable). This will execute the given runnable and
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
37 * return the set of observables that were read from.
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
38 * </p>
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
39 *
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
40 * <p>
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
41 * This can be used to automatically attach listeners. For example, imagine you
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
42 * have a block of code that updates some widget by reading from a bunch of
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
43 * observables. Whenever one of those observables changes, you want to re-run
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
44 * the code and cause the widget to be refreshed. You could do this in the
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
45 * traditional manner by attaching one listener to each observable and
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
46 * re-running your widget update code whenever one of them changes, but this
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
47 * code is repetitive and requires updating the listener code whenever you
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
48 * refactor the widget updating code.
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
49 * </p>
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
50 *
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
51 * <p>
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
52 * Alternatively, you could use a utility class that runs the code in a
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
53 * runAndMonitor block and automatically attach listeners to any observable used
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
54 * in updating the widget. The advantage of the latter approach is that it,
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
55 * eliminates the code for attaching and detaching listeners and will always
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
56 * stay in synch with changes to the widget update logic.
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
57 * </p>
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
58 *
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
59 * @since 1.0
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
60 */
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
61 public class ObservableTracker {
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
62
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
63 /**
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
64 * Threadlocal storage pointing to the current Set of IObservables, or null
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
65 * if none. Note that this is actually the top of a stack. Whenever a method
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
66 * changes the current value, it remembers the old value as a local variable
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
67 * and restores the old value when the method exits.
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
68 */
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
69 private static ThreadLocal currentChangeListener = new ThreadLocal();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
70
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
71 private static ThreadLocal currentStaleListener = new ThreadLocal();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
72
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
73 private static ThreadLocal currentObservableSet = new ThreadLocal();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
74
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
75 /**
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
76 * Invokes the given runnable, and returns the set of IObservables that were
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
77 * read by the runnable. If the runnable calls this method recursively, the
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
78 * result will not contain IObservables that were used within the inner
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
79 * runnable.
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
80 *
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
81 * @param runnable
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
82 * runnable to execute
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
83 * @param changeListener
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
84 * listener to register with all accessed observables
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
85 * @param staleListener
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
86 * listener to register with all accessed observables, or
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
87 * <code>null</code> if no stale listener is to be registered
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
88 * @return an array of unique observable objects
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
89 */
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
90 public static IObservable[] runAndMonitor(Runnable runnable,
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
91 IChangeListener changeListener, IStaleListener staleListener) {
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
92 // Remember the previous value in the listener stack
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
93 Set lastObservableSet = cast(Set) currentObservableSet.get();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
94 IChangeListener lastChangeListener = cast(IChangeListener) currentChangeListener
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
95 .get();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
96 IStaleListener lastStaleListener = cast(IStaleListener) currentStaleListener
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
97 .get();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
98
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
99 Set observableSet = new HashSet();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
100 // Push the new listeners to the top of the stack
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
101 currentObservableSet.set(observableSet);
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
102 currentChangeListener.set(changeListener);
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
103 currentStaleListener.set(staleListener);
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
104 try {
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
105 runnable.run();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
106 } finally {
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
107 // Pop the new listener off the top of the stack (by restoring the
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
108 // previous listener)
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
109 currentObservableSet.set(lastObservableSet);
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
110 currentChangeListener.set(lastChangeListener);
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
111 currentStaleListener.set(lastStaleListener);
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
112 }
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
113
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
114 int i = 0;
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
115 IObservable[] result = new IObservable[observableSet.size()];
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
116 for (Iterator it = observableSet.iterator(); it.hasNext();) {
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
117 IdentityWrapper wrapper = cast(IdentityWrapper) it.next();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
118 result[i++] = cast(IObservable) wrapper.unwrap();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
119 }
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
120
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
121 return result;
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
122 }
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
123
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
124 /**
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
125 * Runs the given runnable without tracking dependencies.
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
126 * @param runnable
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
127 *
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
128 * @since 1.1
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
129 */
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
130 public static void runAndIgnore(Runnable runnable) {
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
131 // Remember the previous value in the listener stack
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
132 Set lastObservableSet = cast(Set) currentObservableSet.get();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
133 IChangeListener lastChangeListener = cast(IChangeListener) currentChangeListener
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
134 .get();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
135 IStaleListener lastStaleListener = cast(IStaleListener) currentStaleListener
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
136 .get();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
137 currentObservableSet.set(null);
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
138 currentChangeListener.set(null);
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
139 currentStaleListener.set(null);
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
140 try {
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
141 runnable.run();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
142 } finally {
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
143 // Pop the new listener off the top of the stack (by restoring the
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
144 // previous listener)
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
145 currentObservableSet.set(lastObservableSet);
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
146 currentChangeListener.set(lastChangeListener);
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
147 currentStaleListener.set(lastStaleListener);
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
148 }
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
149 }
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
150
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
151 /*
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
152 * Returns the same string as the default Object.toString() implementation.
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
153 * getterCalled() uses this method IObservable.toString() to avoid infinite
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
154 * recursion and stack overflow.
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
155 */
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
156 private static String toString(IObservable observable) {
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
157 return observable.getClass().getName() + "@" //$NON-NLS-1$
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
158 + Integer.toHexString(System.identityHashCode(observable));
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
159 }
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
160
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
161 /**
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
162 * Notifies the ObservableTracker that an observable was read from. The
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
163 * JavaDoc for methods that invoke this method should include the following
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
164 * tag: "@TrackedGetter This method will notify ObservableTracker that the
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
165 * receiver has been read from". This lets callers know that they can rely
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
166 * on automatic updates from the object without explicitly attaching a
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
167 * listener.
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
168 *
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
169 * @param observable
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
170 */
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
171 public static void getterCalled(IObservable observable) {
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
172 Realm realm = observable.getRealm();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
173 if (realm is null) // observable.isDisposed() would be more appropriate if it existed
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
174 Assert.isTrue(false, "Getter called on disposed observable " //$NON-NLS-1$
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
175 + toString(observable));
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
176 if (!realm.isCurrent())
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
177 Assert.isTrue(false, "Getter called outside realm of observable " //$NON-NLS-1$
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
178 + toString(observable));
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
179
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
180 Set lastObservableSet = cast(Set) currentObservableSet.get();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
181 if (lastObservableSet is null) {
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
182 return;
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
183 }
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
184 IChangeListener lastChangeListener = cast(IChangeListener) currentChangeListener
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
185 .get();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
186 IStaleListener lastStaleListener = cast(IStaleListener) currentStaleListener
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
187 .get();
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
188
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
189 bool added = false;
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
190 if (lastObservableSet !is null) {
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
191 added = lastObservableSet.add(new IdentityWrapper(observable));
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
192 }
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
193
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
194 // If anyone is listening for observable usage...
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
195 if (added && lastChangeListener !is null) {
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
196 observable.addChangeListener(lastChangeListener);
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
197 }
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
198 if (added && lastStaleListener !is null) {
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
199 observable.addStaleListener(lastStaleListener);
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
200 }
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
201 }
0a55d2d5a946 Added file for databinding
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
202 }