Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 19034007b9bdff92baab4de825a4a803750cd571 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.debug.internal.core;


/**
 * Local version of org.eclipse.jface.util.ListenerList (modified)s
 */
public class ListenerList {
	/**
	 * The current number of listeners.
	 * Maintains invariant: 0 <= fSize <= listeners.length.
	 */
	private int fSize;

	/**
	 * The list of listeners.  Initially <code>null</code> but initialized
	 * to an array of size capacity the first time a listener is added.
	 * Maintains invariant: listeners != null if and only if fSize != 0
	 */
	private Object[] fListeners= null;

	/**
	 * The empty array singleton instance, returned by getListeners()
	 * when size == 0.
	 */
	private static final Object[] EmptyArray= new Object[0];

	/**
	 * Creates a listener list with the given initial capacity.
	 *
	 * @param capacity the number of listeners which this list can initially accept 
	 *    without growing its internal representation; must be at least 1
	 */
	public ListenerList(int capacity) {
		if (capacity < 1) {
			throw new IllegalArgumentException();
		}
		fListeners= new Object[capacity];
		fSize= 0;
	}

	/**
	 * Adds a listener to the list.
	 * Has no effect if an identical listener is already registered.
	 *
	 * @param listener a listener
	 */
	public synchronized void add(Object listener) {
		if (listener == null) {
			throw new IllegalArgumentException();
		}
		// check for duplicates using identity
		for (int i= 0; i < fSize; ++i) {
			if (fListeners[i] == listener) {
				return;
			}
		}
		// grow array if necessary
		if (fSize == fListeners.length) {
			Object[] temp= new Object[(fSize * 2) + 1];
			System.arraycopy(fListeners, 0, temp, 0, fSize);
			fListeners= temp;
		}
		fListeners[fSize++]= listener;
	}

	/**
	 * Returns an array containing all the registered listeners.
	 * The resulting array is unaffected by subsequent adds or removes.
	 * If there are no listeners registered, the result is an empty array
	 * singleton instance (no garbage is created).
	 * Use this method when notifying listeners, so that any modifications
	 * to the listener list during the notification will have no effect on the
	 * notification itself.
	 */
	public synchronized Object[] getListeners() {
		if (fSize == 0) {
			return EmptyArray;
		}
		Object[] result= new Object[fSize];
		System.arraycopy(fListeners, 0, result, 0, fSize);
		return result;
	}

	/**
	 * Removes a listener from the list.
	 * Has no effect if an identical listener was not already registered.
	 *
	 * @param listener a listener
	 */
	public synchronized void remove(Object listener) {
		if (listener == null) {
			throw new IllegalArgumentException();
		}

		for (int i= 0; i < fSize; ++i) {
			if (fListeners[i] == listener) {
				if (--fSize == 0) {
					fListeners= new Object[1];
				} else {
					if (i < fSize) {
						fListeners[i]= fListeners[fSize];
					}
					fListeners[fSize]= null;
				}
				return;
			}
		}
	}

	/**
	 * Removes all the listeners from the list.
	 */
	public synchronized void removeAll() {
		fListeners= new Object[0];
		fSize= 0;
	}

	/**
	 * Returns the number of registered listeners
	 *
	 * @return the number of registered listeners
	 */
	public int size() {
		return fSize;
	}
}

Back to the top