View Javadoc

1   package cz.cuni.amis.pogamut.base.communication.worldview.event;
2   
3   import java.util.concurrent.ExecutionException;
4   import java.util.concurrent.Future;
5   import java.util.concurrent.TimeUnit;
6   
7   import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView;
8   import cz.cuni.amis.pogamut.base.component.bus.event.BusAwareCountDownLatch;
9   import cz.cuni.amis.utils.exception.PogamutException;
10  
11  /**
12   * Use this if you want to wait for first appearance of some IWorldObject with known string ID.
13   * 
14   * @author ik
15   */
16  public class WorldEventFuture<T extends IWorldEvent> implements Future<T> {
17  	
18  	public static class WorldEventFutureException extends PogamutException {
19  
20  		public WorldEventFutureException(String message, Object origin) {
21  			super(message, origin);
22  		}
23  		
24  	}
25  
26      private final IWorldView worldView;
27      private final Class<T> eventClass;
28      
29      private T worldEvent = null;
30      private BusAwareCountDownLatch latch;
31      private IWorldEventListener<T> listener = null;
32  	private boolean cancelled = false;
33  	
34      /**
35       * Creates new instance of future that waits for the event of given class.
36       * @param worldView WorldView where the object will appear
37       * @param eventClass class of the event we're waiting for
38       */
39      @SuppressWarnings("unchecked")
40      public WorldEventFuture(final IWorldView worldView, final Class<T> eventClass) {
41      	this.worldView = worldView;
42      	this.eventClass = eventClass;
43      	latch = new BusAwareCountDownLatch(1, worldView.getEventBus(), worldView);
44  		worldView.addEventListener(
45              eventClass,
46              listener = new IWorldEventListener<T>() {
47                  @Override
48                  public void notify(T event) {
49                  	worldEvent = event;
50                      worldView.removeEventListener(eventClass, this);
51                      customEventEncounteredHook(worldEvent);
52                      latch.countDown();
53                  }
54              }
55          );    		
56      }
57  
58      /**
59       * Utility method for custom handling of the first-encounter event.
60       * @param obj
61       */
62      protected void customEventEncounteredHook(T obj) {
63      }
64  
65      @Override
66      public synchronized boolean cancel(boolean mayInterruptIfRunning) {
67          if (latch != null) latch.countDown();
68          cancelled  = true;
69          worldView.removeEventListener(eventClass, listener);
70          return true;
71      }
72  
73      @Override
74      public synchronized boolean isCancelled() {
75          return cancelled;
76      }
77  
78      @Override
79      public boolean isDone() {
80          return worldEvent != null;
81      }
82  
83      /**
84       * @return the object that was awaited
85       * @throws InterruptedException
86       * @throws ExecutionException
87       */
88      @Override
89      public T get() {
90          latch.await();
91          return worldEvent;
92      }
93  
94      @Override
95      public T get(long timeout, TimeUnit unit) {
96          latch.await(timeout, unit);
97          return worldEvent;
98      }
99  }