Mercurial > projects > dwt2
comparison org.eclipse.equinox.common/src/org/eclipse/core/runtime/ListenerList.d @ 105:bbe49769ec18
...
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 08 Nov 2009 12:42:30 +0100 |
parents | bc29606a740c |
children |
comparison
equal
deleted
inserted
replaced
104:88652073d1c2 | 105:bbe49769ec18 |
---|---|
2 * Copyright (c) 2004, 2006 IBM Corporation and others. | 2 * Copyright (c) 2004, 2006 IBM Corporation and others. |
3 * All rights reserved. This program and the accompanying materials | 3 * All rights reserved. This program and the accompanying materials |
4 * are made available under the terms of the Eclipse Public License v1.0 | 4 * are made available under the terms of the Eclipse Public License v1.0 |
5 * which accompanies this distribution, and is available at | 5 * which accompanies this distribution, and is available at |
6 * http://www.eclipse.org/legal/epl-v10.html | 6 * http://www.eclipse.org/legal/epl-v10.html |
7 * | 7 * |
8 * Contributors: | 8 * Contributors: |
9 * IBM Corporation - initial API and implementation | 9 * IBM Corporation - initial API and implementation |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | 10 *******************************************************************************/ |
13 module org.eclipse.core.runtime.ListenerList; | 11 // Port to the D programming language: |
12 // Frank Benoit <benoit@tionex.de> | |
13 module org.eclipse.core.runtimeListenerList; | |
14 | 14 |
15 import java.lang.all; | 15 import java.lang.all; |
16 | 16 |
17 | |
17 /** | 18 /** |
18 * This class is a thread safe list that is designed for storing lists of listeners. | 19 * This class is a thread safe list that is designed for storing lists of listeners. |
19 * The implementation is optimized for minimal memory footprint, frequent reads | 20 * The implementation is optimized for minimal memory footprint, frequent reads |
20 * and infrequent writes. Modification of the list is synchronized and relatively | 21 * and infrequent writes. Modification of the list is synchronized and relatively |
21 * expensive, while accessing the listeners is very fast. Readers are given access | 22 * expensive, while accessing the listeners is very fast. Readers are given access |
22 * to the underlying array data structure for reading, with the trust that they will | 23 * to the underlying array data structure for reading, with the trust that they will |
23 * not modify the underlying array. | 24 * not modify the underlying array. |
24 * <p> | 25 * <p> |
25 * <a name="same">A listener list handles the <i>same</i> listener being added | 26 * <a name="same">A listener list handles the <i>same</i> listener being added |
26 * multiple times, and tolerates removal of listeners that are the same as other | 27 * multiple times, and tolerates removal of listeners that are the same as other |
27 * listeners in the list. For this purpose, listeners can be compared with each other | 28 * listeners in the list. For this purpose, listeners can be compared with each other |
28 * using either equality or identity, as specified in the list constructor. | 29 * using either equality or identity, as specified in the list constructor. |
29 * </p> | 30 * </p> |
30 * <p> | 31 * <p> |
31 * Use the <code>getListeners</code> method when notifying listeners. The recommended | 32 * Use the <code>getListeners</code> method when notifying listeners. The recommended |
32 * code sequence for notifying all registered listeners of say, | 33 * code sequence for notifying all registered listeners of say, |
33 * <code>FooListener.eventHappened</code>, is: | 34 * <code>FooListener.eventHappened</code>, is: |
34 * | 35 * |
35 * <pre> | 36 * <pre> |
36 * Object[] listeners = myListenerList.getListeners(); | 37 * Object[] listeners = myListenerList.getListeners(); |
37 * for (int i = 0; i < listeners.length; ++i) { | 38 * for (int i = 0; i < listeners.length; ++i) { |
38 * ((FooListener) listeners[i]).eventHappened(event); | 39 * ((FooListener) listeners[i]).eventHappened(event); |
39 * } | 40 * } |
40 * </pre> | 41 * </pre> |
41 * | 42 * |
42 * </p><p> | 43 * </p><p> |
43 * This class can be used without OSGi running. | 44 * This class can be used without OSGi running. |
44 * </p> | 45 * </p> |
45 * @since org.eclipse.equinox.common 3.2 | 46 * @since org.eclipse.equinox.common 3.2 |
46 */ | 47 */ |
47 public class ListenerList { | 48 public class ListenerList { |
48 | 49 |
49 /** | 50 /** |
50 * The empty array singleton instance. | 51 * The empty array singleton instance. |
51 */ | 52 */ |
52 private static const Object[] EmptyArray; | 53 private static final Object[] EmptyArray = new Object[0]; |
53 | 54 |
54 /** | 55 /** |
55 * Mode constant (value 0) indicating that listeners should be considered | 56 * Mode constant (value 0) indicating that listeners should be considered |
56 * the <a href="#same">same</a> if they are equal. | 57 * the <a href="#same">same</a> if they are equal. |
57 */ | 58 */ |
58 public static const int EQUALITY = 0; | 59 public static final int EQUALITY = 0; |
59 | 60 |
60 /** | 61 /** |
61 * Mode constant (value 1) indicating that listeners should be considered | 62 * Mode constant (value 1) indicating that listeners should be considered |
62 * the <a href="#same">same</a> if they are identical. | 63 * the <a href="#same">same</a> if they are identical. |
63 */ | 64 */ |
64 public static const int IDENTITY = 1; | 65 public static final int IDENTITY = 1; |
65 | 66 |
66 /** | 67 /** |
67 * Indicates the comparison mode used to determine if two | 68 * Indicates the comparison mode used to determine if two |
68 * listeners are equivalent | 69 * listeners are equivalent |
69 */ | 70 */ |
70 private final bool identity; | 71 private final bool identity; |
71 | 72 |
72 /** | 73 /** |
73 * The list of listeners. Initially empty but initialized | 74 * The list of listeners. Initially empty but initialized |
74 * to an array of size capacity the first time a listener is added. | 75 * to an array of size capacity the first time a listener is added. |
75 * Maintains invariant: listeners !is null | 76 * Maintains invariant: listeners != null |
76 */ | 77 */ |
77 private Object[] listeners; | 78 private /+volatile+/ Object[] listeners = EmptyArray; |
78 | 79 |
79 /** | 80 /** |
80 * Creates a listener list in which listeners are compared using equality. | 81 * Creates a listener list in which listeners are compared using equality. |
81 */ | 82 */ |
82 public this() { | 83 public this() { |
83 this(EQUALITY); | 84 thiscast(EQUALITY); |
84 } | 85 } |
85 | 86 |
86 /** | 87 /** |
87 * Creates a listener list using the provided comparison mode. | 88 * Creates a listener list using the provided comparison mode. |
88 * | 89 * |
89 * @param mode The mode used to determine if listeners are the <a href="#same">same</a>. | 90 * @param mode The mode used to determine if listeners are the <a href="#same">same</a>. |
90 */ | 91 */ |
91 public this(int mode) { | 92 public this(int mode) { |
92 if (mode !is EQUALITY && mode !is IDENTITY) | 93 if (mode !is EQUALITY && mode !is IDENTITY) |
93 throw new IllegalArgumentException( null ); | 94 throw new IllegalArgumentException(); |
94 this.identity = mode is IDENTITY; | 95 this.identity = mode is IDENTITY; |
95 } | 96 } |
96 | 97 |
97 /** | 98 /** |
98 * Adds a listener to this list. This method has no effect if the <a href="#same">same</a> | 99 * Adds a listener to this list. This method has no effect if the <a href="#same">same</a> |
99 * listener is already registered. | 100 * listener is already registered. |
100 * | 101 * |
101 * @param listener the non-<code>null</code> listener to add | 102 * @param listener the non-<code>null</code> listener to add |
102 */ | 103 */ |
103 public synchronized void add(Object listener) { | 104 public synchronized void add(Object listener) { |
104 // This method is synchronized to protect against multiple threads adding | 105 // This method is synchronized to protect against multiple threads adding |
105 // or removing listeners concurrently. This does not block concurrent readers. | 106 // or removing listeners concurrently. This does not block concurrent readers. |
106 if (listener is null) | 107 if (listener is null) |
107 throw new IllegalArgumentException( null ); | 108 throw new IllegalArgumentException(); |
108 // check for duplicates | 109 // check for duplicates |
109 final int oldSize = listeners.length; | 110 final int oldSize = listeners.length; |
110 for (int i = 0; i < oldSize; ++i) { | 111 for (int i = 0; i < oldSize; ++i) { |
111 Object listener2 = listeners[i]; | 112 Object listener2 = listeners[i]; |
112 if (identity ? listener is listener2 : listener.opEquals(listener2)) | 113 if (identity ? listener is listener2 : listener.opEquals(listener2)) |
113 return; | 114 return; |
123 /** | 124 /** |
124 * Returns an array containing all the registered listeners. | 125 * Returns an array containing all the registered listeners. |
125 * The resulting array is unaffected by subsequent adds or removes. | 126 * The resulting array is unaffected by subsequent adds or removes. |
126 * If there are no listeners registered, the result is an empty array. | 127 * If there are no listeners registered, the result is an empty array. |
127 * Use this method when notifying listeners, so that any modifications | 128 * Use this method when notifying listeners, so that any modifications |
128 * to the listener list during the notification will have no effect on | 129 * to the listener list during the notification will have no effect on |
129 * the notification itself. | 130 * the notification itself. |
130 * <p> | 131 * <p> |
131 * Note: Callers of this method <b>must not</b> modify the returned array. | 132 * Note: Callers of this method <b>must not</b> modify the returned array. |
132 * | 133 * |
133 * @return the list of registered listeners | 134 * @return the list of registered listeners |
134 */ | 135 */ |
135 public Object[] getListeners() { | 136 public Object[] getListeners() { |
136 return listeners; | 137 return listeners; |
145 public bool isEmpty() { | 146 public bool isEmpty() { |
146 return listeners.length is 0; | 147 return listeners.length is 0; |
147 } | 148 } |
148 | 149 |
149 /** | 150 /** |
150 * Removes a listener from this list. Has no effect if the <a href="#same">same</a> | 151 * Removes a listener from this list. Has no effect if the <a href="#same">same</a> |
151 * listener was not already registered. | 152 * listener was not already registered. |
152 * | 153 * |
153 * @param listener the non-<code>null</code> listener to remove | 154 * @param listener the non-<code>null</code> listener to remove |
154 */ | 155 */ |
155 public synchronized void remove(Object listener) { | 156 public synchronized void remove(Object listener) { |
156 // This method is synchronized to protect against multiple threads adding | 157 // This method is synchronized to protect against multiple threads adding |
157 // or removing listeners concurrently. This does not block concurrent readers. | 158 // or removing listeners concurrently. This does not block concurrent readers. |
158 if (listener is null) | 159 if (listener is null) |
159 throw new IllegalArgumentException( null ); | 160 throw new IllegalArgumentException(); |
160 int oldSize = listeners.length; | 161 int oldSize = listeners.length; |
161 for (int i = 0; i < oldSize; ++i) { | 162 for (int i = 0; i < oldSize; ++i) { |
162 Object listener2 = listeners[i]; | 163 Object listener2 = listeners[i]; |
163 if (identity ? listener is listener2 : listener.opEquals(listener2)) { | 164 if (identity ? listener is listener2 : listener.opEquals(listener2)) { |
164 if (oldSize is 1) { | 165 if (oldSize is 1) { |
182 * @return the number of registered listeners | 183 * @return the number of registered listeners |
183 */ | 184 */ |
184 public int size() { | 185 public int size() { |
185 return listeners.length; | 186 return listeners.length; |
186 } | 187 } |
187 | 188 |
188 /** | 189 /** |
189 * Removes all listeners from this list. | 190 * Removes all listeners from this list. |
190 */ | 191 */ |
191 public synchronized void clear() { | 192 public synchronized void clear() { |
192 listeners = EmptyArray; | 193 listeners = EmptyArray; |