1 /******************************************************************************* 2 * Copyright (c) 2000, 2008 IBM Corporation and others. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * IBM Corporation - initial API and implementation 10 * Port to the D programming language: 11 * Frank Benoit <benoit@tionex.de> 12 *******************************************************************************/ 13 module org.eclipse.swt.widgets.EventTable; 14 15 import java.lang.all; 16 17 import org.eclipse.swt.widgets.Listener; 18 import org.eclipse.swt.widgets.Event; 19 import org.eclipse.swt.widgets.Listener; 20 import org.eclipse.swt.widgets.TypedListener; 21 import org.eclipse.swt.internal.SWTEventListener; 22 import org.eclipse.swt.SWT; 23 import org.eclipse.swt.internal.SWTEventListener; 24 25 /** 26 * Instances of this class implement a simple 27 * look up mechanism that maps an event type 28 * to a listener. Multiple listeners for the 29 * same event type are supported. 30 */ 31 32 class EventTable { 33 int [] types; 34 Listener [] listeners; 35 int level; 36 static const int GROW_SIZE = 4; 37 38 public Listener [] getListeners (int eventType) { 39 if (types is null) return new Listener [0]; 40 int count = 0; 41 for (int i=0; i<types.length; i++) { 42 if (types [i] is eventType) count++; 43 } 44 if (count is 0) return new Listener [0]; 45 Listener [] result = new Listener [count]; 46 count = 0; 47 for (int i=0; i<types.length; i++) { 48 if (types [i] is eventType) { 49 result [count++] = listeners [i]; 50 } 51 } 52 return result; 53 } 54 55 public void hook (int eventType, Listener listener) { 56 if (types is null) types = new int [GROW_SIZE]; 57 if (listeners is null) listeners = new Listener [GROW_SIZE]; 58 ptrdiff_t length = types.length, index = length - 1; 59 while (index >= 0) { 60 if (types [index] !is 0) break; 61 --index; 62 } 63 index++; 64 if (index is length) { 65 int [] newTypes = new int [length + GROW_SIZE]; 66 System.arraycopy (types, 0, newTypes, 0, length); 67 types = newTypes; 68 Listener [] newListeners = new Listener [length + GROW_SIZE]; 69 SimpleType!(Listener).arraycopy (listeners, 0, newListeners, 0, length); 70 listeners = newListeners; 71 } 72 types [index] = eventType; 73 listeners [index] = listener; 74 } 75 76 public bool hooks (int eventType) { 77 if (types is null) return false; 78 for (int i=0; i<types.length; i++) { 79 if (types [i] is eventType) return true; 80 } 81 return false; 82 } 83 84 public void sendEvent (Event event) { 85 if (types is null) return; 86 level += level >= 0 ? 1 : -1; 87 try { 88 for (int i=0; i<types.length; i++) { 89 if (event.type is SWT.None) return; 90 if (types [i] is event.type) { 91 Listener listener = listeners [i]; 92 if (listener !is null) listener.handleEvent (event); 93 } 94 } 95 } finally { 96 bool compact = level < 0; 97 level -= level >= 0 ? 1 : -1; 98 if (compact && level is 0) { 99 int index = 0; 100 for (int i=0; i<types.length; i++) { 101 if (types [i] !is 0) { 102 types [index] = types [i]; 103 listeners [index] = listeners [i]; 104 index++; 105 } 106 } 107 for (int i=index; i<types.length; i++) { 108 types [i] = 0; 109 listeners [i] = null; 110 } 111 } 112 } 113 } 114 115 public int size () { 116 if (types is null) return 0; 117 int count = 0; 118 for (int i=0; i<types.length; i++) { 119 if (types [i] !is 0) count++; 120 } 121 return count; 122 } 123 124 void remove (int index) { 125 if (level is 0) { 126 ptrdiff_t end = types.length - 1; 127 System.arraycopy (types, index + 1, types, index, end - index); 128 SimpleType!(Listener).arraycopy (listeners, index + 1, listeners, index, end - index); 129 index = cast(int)/*64bit*/end; 130 } else { 131 if (level > 0) level = -level; 132 } 133 types [index] = 0; 134 listeners [index] = null; 135 } 136 137 public void unhook (int eventType, Listener listener) { 138 if (types is null) return; 139 for (int i=0; i<types.length; i++) { 140 if (types [i] is eventType && listeners [i] is listener) { 141 remove (i); 142 return; 143 } 144 } 145 } 146 147 public void unhook (int eventType, SWTEventListener listener) { 148 if (types is null) return; 149 for (int i=0; i<types.length; i++) { 150 if (types [i] is eventType) { 151 if ( auto typedListener = cast(TypedListener) listeners [i] ) { 152 if (typedListener.getEventListener () is listener) { 153 remove (i); 154 return; 155 } 156 } 157 } 158 } 159 } 160 161 }