1 /* 2 * Copyright the original author or authors. 3 * 4 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.mozilla.org/MPL/MPL-1.1.html 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import org.as2lib.app.exec.Executable; 18 import org.as2lib.app.exec.Call; 19 import org.as2lib.core.BasicClass; 20 import org.as2lib.env.event.impulse.ImpulseListener; 21 import org.as2lib.env.except.IllegalArgumentException; 22 import org.as2lib.util.ArrayUtil; 23 24 /** 25 * {@code AbstractImpulse} is a helper class that contains shared API to be used 26 * by different {@link org.as2lib.env.event.impulse.Impulse} Implementations. 27 * 28 * @author Martin Heidegger 29 * @version 1.0 30 */ 31 class org.as2lib.env.event.impulse.AbstractImpulse extends BasicClass { 32 33 /** Broadcaster for connected executables */ 34 private var execBroadcaster:Object; 35 36 /** Broadcaster for connected impulselisteners */ 37 private var impulseBroadcaster:Object; 38 39 /** 40 * Constructs a new impulse. 41 */ 42 public function AbstractImpulse() { 43 // Creation of ASBroadcasters for the events. 44 execBroadcaster = new Object(); 45 AsBroadcaster.initialize(execBroadcaster); 46 impulseBroadcaster = new Object(); 47 AsBroadcaster.initialize(impulseBroadcaster); 48 } 49 50 /** 51 * Connects a executable as listener to the frame execution. 52 * 53 * @param exe Executable to be added as listener 54 */ 55 public function connectExecutable(exe:Executable):Void { 56 addListener(exe); 57 } 58 59 /** 60 * Adds a list of listeners to listen to the impulse events. 61 * 62 * @param listeners List of listeners to be added. 63 * @throws IllegalArgumentException if a listener could not be added. 64 */ 65 public function addAllListeners(listeners:Array):Void { 66 for(var i=0; i<listeners.length; i++) { 67 addListener(listeners[i]); 68 } 69 } 70 71 /** 72 * Method to add any supported listener to the FrameImpulse. 73 * 74 * <p>Adds a listener to the Impulse. The listener will be informed on 75 * each frame change. 76 * 77 * <p>Note: If a certain listener implements more than one supported event it 78 * will listen to all of them at one execution (execute, onFrameImpulse, 79 * onImpulse). 80 * 81 * @param listener to be added. 82 * @throws IllegalArgumentException if the listener doesn't match any type. 83 */ 84 public function addListener(listener):Void { 85 var notAdded:Boolean = true; 86 if(listener instanceof Executable) { 87 execBroadcaster.addListener(listener); 88 notAdded = false; 89 } 90 if(listener instanceof ImpulseListener) { 91 impulseBroadcaster.addListener(listener); 92 notAdded = false; 93 } 94 if(notAdded) { 95 throw new IllegalArgumentException("Passed listener doesn't match" 96 +" any possible listener type.", this 97 , arguments); 98 } 99 } 100 101 /** 102 * Methode to add a {@link ImpulseListener} as listener to the Impulse. 103 * 104 * <p>Some parts of the code get better readable if you use a complete 105 * clear name like "onImpulse" to define your code. With 106 * {@code .addImpulseListener} you can add a listener that specially 107 * listens only to this naming of the same event that will be executed as 108 * "execute". 109 * 110 * <p>Example: 111 * 112 * <p>Listener: 113 * <code> 114 * import org.as2lib.env.event.impulse.ImpulseListener; 115 * import org.as2lib.env.event.impulse.Impulse; 116 * 117 * class TraceTimeImpulseListener implements ImpulseListener { 118 * public function onImpulse(impulse:Impulse):Void { 119 * trace("Impulse executed at "+getTimer()); 120 * } 121 * } 122 * </code> 123 * 124 * <p>Usage: 125 * <code> 126 * import org.as2lib.env.event.impulse.FrameImpulse; 127 * 128 * var impulse:FrameImpulse = FrameImpulse.getInstance(); 129 * impulse.addImpulseListener(new TraceTimeImpulseListener()); 130 * </code> 131 * 132 * @param listener Listener to be added. 133 */ 134 public function addImpulseListener(listener:ImpulseListener):Void { 135 addListener(listener); 136 } 137 138 /** 139 * Removes a listener of any type that might be added. 140 * 141 * @param listener Listener to be removed. 142 * @throws IllegalArgumentException if you pass a listener that is of a 143 * illegal type. 144 */ 145 public function removeListener(listener):Void { 146 var notRemoved:Boolean = true; 147 if(listener instanceof Executable) { 148 execBroadcaster.removeListener(listener); 149 notRemoved = false; 150 } 151 if(listener instanceof ImpulseListener) { 152 impulseBroadcaster.removeListener(listener); 153 notRemoved = false; 154 } 155 if(notRemoved) { 156 throw new IllegalArgumentException("Passed listener doesn't match" 157 +" any possible listener type.", this 158 , arguments); 159 } 160 } 161 162 /** 163 * Disconnects a {@link Executable} from listening to the impulse. 164 * 165 * @param exe {@link Executable} to disconnect. 166 */ 167 public function disconnectExecutable(exe:Executable):Void { 168 removeListener(exe); 169 } 170 171 /** 172 * Removes a {@link ImpulseListener} from listening to the impulse. 173 * 174 * @param listener {@link ImpulseListener} to remove from listening. 175 */ 176 public function removeImpulseListener(listener:ImpulseListener):Void { 177 removeListener(listener); 178 } 179 180 /** 181 * Removes all added Listeners from listening to the impulse. 182 */ 183 public function removeAllListeners(Void):Void { 184 removeAllImpulseListeners(); 185 disconnectAllExecutables(); 186 } 187 188 /** 189 * Removes all added {@link ImpulseListener}s from listening to the impulse. 190 */ 191 public function removeAllImpulseListeners(Void):Void { 192 var c:Call = new Call(this, removeListener); 193 c.forEach(impulseBroadcaster._listeners); 194 } 195 196 /** 197 * Disconnects all connected {@link Executable}s from the impulse. 198 */ 199 public function disconnectAllExecutables(Void):Void { 200 var c:Call = new Call(this, removeListener); 201 c.forEach(execBroadcaster._listeners); 202 } 203 204 205 /** 206 * Getter for the list of all added listeners. 207 * 208 * <p>This method returns a list of all listeners added with eihter 209 * {@link #connectExecutable}, {@link #addListener} or 210 * {@link #addImpulseListener} 211 * 212 * @return List that contains all added listeners. 213 */ 214 public function getAllListeners(Void):Array { 215 var result:Array = new Array(); 216 result = result.concat(getAllConnectedExecutables()); 217 result = result.concat(getAllImpulseListeners()); 218 return result; 219 } 220 221 /** 222 * Getter for the list of all connected {@link Executable}s. 223 * 224 * @return List that contains all connected {@link Executable}s. 225 */ 226 public function getAllConnectedExecutables(Void):Array { 227 return execBroadcaster._listeners.concat(); 228 } 229 230 /** 231 * Getter for the list of all added {@link ImpulseListener}s. 232 * 233 * @return List that contains all added {@link ImpulseListener}s. 234 */ 235 public function getAllImpulseListeners(Void):Array { 236 return impulseBroadcaster._listeners.concat(); 237 } 238 239 /** 240 * Adds a list of {@link ImpulseListener}s as listener to the events. 241 * 242 * @param listeners List of all listeners to add. 243 * @throws IllegalArgumentException if one listener didn't match to any listener type. 244 * @see #addListener 245 */ 246 public function addAllImpulseListeners(listeners:Array):Void { 247 for(var i=0; i<listeners.length; i++) { 248 addListener(listeners[i]); 249 } 250 } 251 252 /** 253 * Connects a list of {@link Executables}s to the impulse. 254 * 255 * @param listeners List of all listeners to add. 256 * @throws IllegalArgumentException if one listener didn't match to any listener type. 257 * @see #addListener 258 */ 259 public function connectAllExecutables(executables:Array):Void { 260 for(var i=0; i<executables.length; i++) { 261 addListener(executables[i]); 262 } 263 } 264 265 /** 266 * Validates if a certain listener of any type is currently added to the 267 * impulse. 268 * 269 * @param listener Listener to be validated. 270 * @return {@code true} if the certain executable is connected. 271 * @see #addListener 272 */ 273 public function hasListener(listener):Boolean { 274 if (hasImpulseListener(listener)) { 275 return true; 276 } 277 if (isExecutableConnected(listener)) { 278 return true; 279 } 280 return false; 281 } 282 283 /** 284 * Validates if a certain {@link ImpulseListener} is currently added to the 285 * impulse. 286 * 287 * @param listener {@link ImpulseListener} to be validated. 288 * @return {@code true} if the certain executable is connected. 289 */ 290 public function hasImpulseListener(listener:ImpulseListener):Boolean { 291 return ArrayUtil.contains(impulseBroadcaster._listeners, listener); 292 } 293 294 /** 295 * Validates if a certain {@link Executable} is currently connected to the 296 * impulse. 297 * 298 * @param exe {@link Executable} to be validated. 299 * @return {@code true} if the certain executable is connected. 300 */ 301 public function isExecutableConnected(exe:Executable):Boolean { 302 return ArrayUtil.contains(execBroadcaster._listeners, exe); 303 } 304 305 }