View Javadoc

1   package cz.cuni.amis.pogamut.base3d.worldview.impl;
2   
3   import java.util.HashSet;
4   import java.util.Set;
5   
6   import com.google.inject.name.Named;
7   
8   import cz.cuni.amis.pogamut.base.communication.translator.event.IWorldChangeEvent;
9   import cz.cuni.amis.pogamut.base.communication.translator.event.IWorldObjectUpdatedEvent;
10  import cz.cuni.amis.pogamut.base.component.bus.IComponentBus;
11  import cz.cuni.amis.pogamut.base.component.bus.exception.ComponentNotRunningException;
12  import cz.cuni.amis.pogamut.base.component.bus.exception.ComponentPausedException;
13  import cz.cuni.amis.pogamut.base.component.controller.ComponentDependencies;
14  import cz.cuni.amis.pogamut.base.utils.logging.IAgentLogger;
15  import cz.cuni.amis.pogamut.base3d.worldview.object.IViewable;
16  
17  /**
18   * World view that is updated by protocol utilizing concept of batches. Each batch
19   * is separated by some message. After receiving this message additional events
20   * may be raised (eg. visibility update etc.).
21   * @author ik
22   */
23  public abstract class BatchAwareWorldView extends VisionWorldView {
24  
25  	public static final String WORLDVIEW_DEPENDENCY = "BatchAwareWorldViewDependency";
26  	
27      Set<IViewable> lastObjectBatch = new HashSet<IViewable>();
28      Set<IViewable> currentObjectBatch = new HashSet<IViewable>();
29  
30      public BatchAwareWorldView(@Named(WORLDVIEW_DEPENDENCY) ComponentDependencies dependencies, IComponentBus bus, IAgentLogger log) {
31          super(dependencies, bus, log);
32      }
33  
34      /**
35       * Is this event a batch end event? If so some extra events may be generated
36       * in processing this message.
37       * @param evt
38       * @return true if this is a batch ending event
39       */
40      protected abstract boolean isBatchEndEvent(IWorldChangeEvent evt);
41      
42  	/**
43  	 * Is this event a batch begin event? It is needed for the locking to be
44  	 * working correctly.
45  	 * 
46  	 * @param evt
47  	 * @return true if this is a batch ending event
48  	 */
49  	protected abstract boolean isBatchBeginEvent(IWorldChangeEvent evt);    
50  
51      /**
52       * Sets the visible flag to true on {@link IViewable} objects.
53       * @param obj Object that disappeared
54       */
55      protected abstract void setDisappearedFlag(IViewable obj);
56  
57      protected void batchAwareWorldViewNotify(IWorldChangeEvent event) {
58      	if (isBatchEndEvent(event)) {
59              // handle disappeared objects
60              lastObjectBatch.removeAll(currentObjectBatch);
61              for (IViewable obj : lastObjectBatch) {
62                  // set the visibility flag to false
63                  setDisappearedFlag(obj);
64                  // first generate update event
65                  objectUpdated(obj);                
66                  // IMPORTANT:               
67                  // then generate disappear event ... usually appeared/disappeared events will 
68                  // wrap the update event processing (e.g. like html tags they must open/...updates.../close)
69                  super.objectDisappeared(obj);                
70              }            
71              // exchange the two sets and clear current batch
72              Set<IViewable> swp = lastObjectBatch;
73              lastObjectBatch = currentObjectBatch;
74              currentObjectBatch = swp;
75              currentObjectBatch.clear();
76          } else {
77              if (event instanceof IWorldObjectUpdatedEvent && event instanceof IViewable) {
78                  IViewable viewable = (IViewable)get(((IWorldObjectUpdatedEvent)event).getId());
79                  if (viewable != null && viewable.isVisible()) {
80                      currentObjectBatch.add(viewable);
81                  }
82              }
83          }
84      }
85      
86      @Override
87      public synchronized void notify(IWorldChangeEvent event) {
88      	batchAwareWorldViewNotify(event);
89      	super.notify(event);
90      }
91      
92      @Override
93      public synchronized void notifyImmediately(IWorldChangeEvent event)
94      		throws ComponentNotRunningException, ComponentPausedException {
95      	batchAwareWorldViewNotify(event);
96      	super.notifyImmediately(event);
97      }
98      
99      @Override
100     protected void objectAppeared(IViewable obj) {
101     	super.objectAppeared(obj);
102     	currentObjectBatch.add(obj);
103     }
104     
105     @Override
106     protected void objectDisappeared(IViewable obj) {
107     	super.objectDisappeared(obj);
108     	lastObjectBatch.remove(obj);
109     	currentObjectBatch.remove(obj);
110     }
111     
112     /**
113      * Any objects waiting in {@link BatchAwareWorldView#currentObjectBatch} for processing?
114      * @return true if there is at least one object to process
115      */
116     public boolean hasObjectsToProcess() {
117     	return !currentObjectBatch.isEmpty();
118     }
119     
120 }