View Javadoc

1   package cz.cuni.amis.pogamut.base.communication.command.react;
2   
3   import cz.cuni.amis.pogamut.base.communication.command.IAct;
4   import cz.cuni.amis.pogamut.base.communication.command.ICommandListener;
5   import cz.cuni.amis.pogamut.base.communication.messages.CommandMessage;
6   import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEvent;
7   import cz.cuni.amis.pogamut.base.communication.worldview.react.EventReact;
8   import cz.cuni.amis.pogamut.base.communication.worldview.react.EventReactOnce;
9   
10  /**
11   * This abstract class allows you to easily hook a specific outgoing-command-handling behavior. It automatically
12   * register a listener for a specified {@link CommandMessage} for you and calls {@link CommandReact#react(CommandMessage)}
13   * method automatically.
14   * <p><p>
15   * If you need to react only once to the event, use {@link EventReactOnce}.
16   * <p><p>
17   * Use {@link EventReact#enable()} and {@link EventReact#disable()} to enable react / disable react. The reaction is enabled
18   * as default.
19   * <p><p>
20   * <b>WARNING:</b>Use as anonymous class, but <b>save it as a field</b> of your class! Note, that we're using weak-references to 
21   * listeners and if you do not save pointer to the object, it will be gc()ed!
22   * 
23   * @author Jimmy
24   *
25   * @param <EVENT>
26   */
27  public abstract class CommandReact<COMMAND extends CommandMessage> {
28  
29  	protected ICommandListener<COMMAND> reactListener = new ICommandListener<COMMAND>() {
30  
31  		@Override
32  		public void notify(COMMAND event) {
33  			preReact(event);
34  			react(event);
35  			postReact(event);
36  		}
37  	
38  	};
39  	
40  	protected IAct reactAct;
41  
42  	protected Class<COMMAND> reactCommandClass;
43  	
44  	private boolean reactHooked = false;
45  	
46  	public CommandReact(Class<COMMAND> commandClass, IAct worldView) {
47  		this.reactAct = worldView;
48  		this.reactCommandClass = commandClass;
49  		enable();
50  	}
51  	
52  	/**
53  	 * Disables the reaction.
54  	 */
55  	public synchronized void disable() {
56  		if (reactHooked) {
57  			reactHooked = false;
58  			reactAct.removeCommandListener(reactCommandClass, reactListener);
59  		}
60  	}
61  	
62  	/**
63  	 * Enables the reaction.
64  	 */
65  	public synchronized void enable() {
66  		if (!reactHooked) {
67  			reactHooked = true;
68  			if (!reactAct.isCommandListening(reactCommandClass, reactListener)) reactAct.addCommandListener(reactCommandClass, reactListener);
69  		}
70  	}
71  	
72  	/**
73  	 * pre-{@link EventReact#react(IWorldEvent)} hook allowing you to do additional work before the react method.
74  	 * @param event
75  	 */
76  	protected void preReact(COMMAND event) {
77  	}
78  
79  	/**
80  	 * React upon event notification.
81  	 * @param event
82  	 */
83  	protected abstract void react(COMMAND event);
84  	
85  	/**
86  	 * post-{@link EventReact#react(IWorldEvent)} hook allowing you to do additional work after the react method.
87  	 * @param event
88  	 */
89  	protected void postReact(COMMAND event) {
90  	}
91  
92  }