View Javadoc

1   package cz.cuni.amis.pogamut.ut2004.communication.translator.observer.state;
2   
3   import java.util.HashMap;
4   import java.util.List;
5   import java.util.Map;
6   
7   import cz.cuni.amis.fsm.FSMState;
8   import cz.cuni.amis.fsm.FSMTransition;
9   import cz.cuni.amis.fsm.IFSMState;
10  import cz.cuni.amis.pogamut.base.communication.messages.InfoMessage;
11  import cz.cuni.amis.pogamut.base.communication.translator.event.IWorldChangeEvent;
12  import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
13  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPoint;
14  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPointListEnd;
15  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPointListStart;
16  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPointNeighbourLink;
17  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPointNeighbourLinkEnd;
18  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPointNeighbourLinkStart;
19  import cz.cuni.amis.pogamut.ut2004.communication.translator.TranslatorContext;
20  import cz.cuni.amis.pogamut.ut2004.communication.translator.TranslatorMessages;
21  import cz.cuni.amis.pogamut.ut2004.communication.translator.UnexpectedMessageException;
22  import cz.cuni.amis.pogamut.ut2004.communication.translator.observer.support.AbstractObserverFSMState;
23  import cz.cuni.amis.pogamut.ut2004.communication.translator.shared.events.MapPointListObtained;
24  import java.util.logging.Level;
25  
26  /**
27   * Takes care of the navpoint list. It stores them inside a List object and when END message comes it sends
28   * them to the world view via <b>NavPointListObtained</b> event, note that before we send the nav points we're doing
29   * the preprocessing of those navpoints to interconnect them with links (NavPointNeighbourLink) filling
30   * respective fileds of incomingEdges and outgoingEdges.
31   * <p><p>
32   * The processing of navpoints and it's links is done via TranslatorContext.processNavPointLinks().
33   * 
34   * @author Jimmy
35   */
36  @FSMState(map={@FSMTransition(
37  					state=ObserverRunningState.class, 
38  					symbol={NavPointListEnd.class}, 
39  					transition={}),
40  			   @FSMTransition(
41  					state = NavPointNeighboursState.class, 
42  					symbol = { NavPointNeighbourLinkStart.class }, 
43  					transition = { }
44  			   )	
45  		  }
46  )
47  public class NavPointListState extends AbstractObserverFSMState<InfoMessage, TranslatorContext> {
48  	
49  	private boolean begun = false;
50  	
51  	private Map<UnrealId, NavPoint> navPoints = new HashMap<UnrealId, NavPoint>();
52  	
53  	private Map<UnrealId, List<NavPointNeighbourLink>> neighbours = new HashMap<UnrealId, List<NavPointNeighbourLink>>();
54  	
55  	private NavPoint currentNavPoint = null;
56  
57  	public NavPointListState() {
58  	}
59  	
60  	@Override
61  	public void stateEntering(TranslatorContext context, IFSMState<InfoMessage, TranslatorContext> fromState, InfoMessage symbol) {
62  		if (!begun) {
63  			if (!symbol.getClass().equals(NavPointListStart.class)) throw new UnexpectedMessageException(TranslatorMessages.unexpectedMessage(this, symbol, NavPointListStart.class), context.getLogger(), this);
64  			begun = true;
65  			return;
66  		}		
67  		if (!symbol.getClass().equals(NavPointNeighbourLinkEnd.class)) throw new UnexpectedMessageException(TranslatorMessages.unexpectedMessage(this, symbol, NavPointNeighbourLinkEnd.class), context.getLogger(), this);
68  		navPoints.put(currentNavPoint.getId(), currentNavPoint);
69  		neighbours.put(currentNavPoint.getId(), context.getNeighbours());
70  	}
71  	
72  	@Override
73  	public void stateLeaving(TranslatorContext context,
74  			IFSMState<InfoMessage, TranslatorContext> toState, InfoMessage symbol) {
75  		if (symbol.getClass().equals(NavPointNeighbourLinkStart.class)) return;	
76  		if (!symbol.getClass().equals(NavPointListEnd.class)) throw new UnexpectedMessageException(TranslatorMessages.unexpectedMessage(this, symbol, NavPointListEnd.class), context.getLogger(), this);
77  		
78  		long simTime = 
79  			(symbol instanceof IWorldChangeEvent ? ((IWorldChangeEvent)symbol).getSimTime() : 0);
80  		
81  		// we've received all the navpoints we could!		
82  		context.setNavPoints(navPoints);
83  		context.setNavPointLinks(neighbours);
84  		context.processNavPointLinks();
85  
86  		if (context.getItems() != null && context.getItems().size() > 0) {
87  			context.processNavPointsAndItems();
88  			if (context.getLogger().isLoggable(Level.FINE)) context.getLogger().fine("Pushing NavPoint events.");
89  			context.getEventQueue().pushEvent(context.getNavPoints().values().toArray(new IWorldChangeEvent[0]));
90  			if (context.getLogger().isLoggable(Level.FINE)) context.getLogger().fine("Pushing Item events.");
91  			context.getEventQueue().pushEvent(context.getItems().values().toArray(new IWorldChangeEvent[0]));
92  			context.getEventQueue().pushEvent(new MapPointListObtained(context.getNavPoints(), context.getItems(), simTime));
93  		} else {
94  			if (context.getLogger().isLoggable(Level.FINE)) context.getLogger().fine("Pushing NavPoint events.");
95  			context.getEventQueue().pushEvent(context.getNavPoints().values().toArray(new IWorldChangeEvent[0]));
96  		}
97  		
98  		// leaving the state, mark we haven't ever begun
99  		navPoints = new HashMap<UnrealId, NavPoint>(navPoints.size() + 20);
100 		neighbours = new HashMap<UnrealId, List<NavPointNeighbourLink>>(neighbours.size() + 20);
101 		begun = false;
102 	}
103 
104 	@Override
105 	protected void innerStateSymbol(TranslatorContext context, InfoMessage symbol) {
106 		if (!symbol.getClass().equals(NavPoint.class)) {
107 			if (!NavPoint.class.isAssignableFrom(symbol.getClass())) {
108 				throw new UnexpectedMessageException(TranslatorMessages.unexpectedMessage(this, symbol, NavPoint.class), context.getLogger(), this);
109 			}
110 		}
111 		currentNavPoint = (NavPoint)symbol;	
112 	}
113 
114 	@Override
115 	public void init(TranslatorContext context) {
116 	}
117 
118 	@Override
119 	public void restart(TranslatorContext context) {
120 		currentNavPoint = null;
121 		begun = false;
122 		navPoints = new HashMap<UnrealId, NavPoint>(navPoints.size() + 20);
123 		neighbours = new HashMap<UnrealId, List<NavPointNeighbourLink>>(neighbours.size() + 20);
124 	}
125 	
126 }