View Javadoc

1   package nl.tudelft.goal.ut2004.floydwarshall;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   import java.util.logging.Level;
6   import java.util.logging.Logger;
7   
8   import cz.cuni.amis.pogamut.base.agent.IGhostAgent;
9   import cz.cuni.amis.pogamut.base.agent.module.SensorModule;
10  import cz.cuni.amis.pogamut.base.agent.navigation.IPathFuture;
11  import cz.cuni.amis.pogamut.base.agent.navigation.IPathPlanner;
12  import cz.cuni.amis.pogamut.base.agent.navigation.impl.PrecomputedPathFuture;
13  import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
14  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPoint;
15  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPointNeighbourLink;
16  import cz.cuni.amis.pogamut.ut2004.communication.translator.shared.events.MapPointListObtained;
17  import cz.cuni.amis.utils.collections.MyCollections;
18  
19  /**
20   * Wrapper for a FloyWarschallMap shared by multiple agents.
21   * 
22   * @author M.P. Korstanje
23   */
24  public class SharedFloydWarshallMap extends SensorModule<IGhostAgent> implements IPathPlanner<NavPoint> {
25  
26  	/**
27  	 * Prohibited edges.
28  	 */
29  	protected int badEdgeFlag = 0;
30  
31  	/**
32  	 * Our map
33  	 */
34  	protected FloydWarshallMap sharedMap = null;
35  
36  	private IWorldEventListener<MapPointListObtained> mapListener = new IWorldEventListener<MapPointListObtained>() {
37  
38  		@Override
39  		public void notify(MapPointListObtained event) {
40  			if (log.isLoggable(Level.INFO))
41  				log.info("Map point list obtained.");
42  			sharedMap = FloydWarshallMapCache.getInstance().createMap(event, badEdgeFlag, log);
43  		}
44  	};
45  
46  	public SharedFloydWarshallMap(IGhostAgent bot) {
47  		this(bot, null);
48  	}
49  
50  	public SharedFloydWarshallMap(IGhostAgent bot, Logger log) {
51  		this(bot, FloydWarshallMap.BAD_EDGE_FLAG, log);
52  	}
53  
54  	public SharedFloydWarshallMap(IGhostAgent bot, int badEdgeFlag, Logger log) {
55  		super(bot, log);
56  		this.badEdgeFlag = badEdgeFlag;
57  		worldView.addEventListener(MapPointListObtained.class, mapListener);
58  	}
59  
60  	/**
61  	 * Transforms a list of navpoints owned by the (bot owning the) shared map
62  	 * to navpoints that we own. This is important with regards to visibility.
63  	 * 
64  	 * @param shared
65  	 * @return
66  	 */
67  	private List<NavPoint> clean(List<NavPoint> shared) {
68  		
69  		//Empty path.
70  		if(shared == null){
71  			return null;
72  		}
73  		
74  		List<NavPoint> clean = new ArrayList<NavPoint>(shared.size());
75  
76  		for (NavPoint navpoint : shared) {
77  			clean.add(clean(navpoint));
78  		}
79  
80  		return clean;
81  	}
82  
83  	/**
84  	 * Transforms a navpoint owned by the (bot owning the) shared map to
85  	 * navpoints that we own. This is important with regards to visibility.
86  	 * 
87  	 * @param shared
88  	 * @return
89  	 */
90  	private NavPoint clean(NavPoint shared) {
91  		return worldView.get(shared.getId(), NavPoint.class);
92  	}
93  
94  	/**
95  	 * Returns path between navpoints 'from' -> 'to'. The path begins with
96  	 * 'from' and ends with 'to'. If such path does not exist, it returns
97  	 * zero-sized path.
98  	 * <p>
99  	 * <p>
100 	 * Throws exception if object is disabled, see
101 	 * {@link FloydWarshallMap#setEnabled(boolean)}. Note that the object
102 	 * is enabled by default.
103 	 * 
104 	 * @param from
105 	 * @param to
106 	 * @return
107 	 */
108 	@Override
109 	public IPathFuture<NavPoint> computePath(NavPoint from, NavPoint to) {
110 		return new PrecomputedPathFuture<NavPoint>(from, to, getPath(from, to));
111 	}
112 
113 	/**
114 	 * Whether navpoint 'to' is reachable from the navpoint 'from'.
115 	 * <p>
116 	 * <p>
117 	 * Throws exception if object is disabled, see
118 	 * {@link FloydWarshallMap#setEnabled(boolean)}. Note that the object
119 	 * is enabled by default.
120 	 * 
121 	 * @param from
122 	 * @param to
123 	 * @return
124 	 */
125 	public boolean reachable(NavPoint from, NavPoint to) {
126 		return sharedMap.reachable(from, to);
127 	}
128 
129 	/**
130 	 * Calculate's distance between two nav points (using pathfinding).
131 	 * <p>
132 	 * <p>
133 	 * Throws exception if object is disabled, see
134 	 * {@link FloydWarshallMap#setEnabled(boolean)}. Note that the object
135 	 * is enabled by default.
136 	 * 
137 	 * @return Distance or POSITIVE_INFINITY if there's no path.
138 	 */
139 	public float getDistance(NavPoint from, NavPoint to) {
140 		return sharedMap.getDistance(from, to);
141 	}
142 
143 	/**
144 	 * Returns path between navpoints 'from' -> 'to'. The path begins with
145 	 * 'from' and ends with 'to'. If such path doesn't exist, returns null.
146 	 * <p>
147 	 * <p>
148 	 * Throws exception if object is disabled, see
149 	 * {@link FloydWarshallMap#setEnabled(boolean)}. Note that the object
150 	 * is enabled by default.
151 	 * 
152 	 * @param from
153 	 * @param to
154 	 * @return
155 	 */
156 	public List<NavPoint> getPath(NavPoint from, NavPoint to) {
157 		return clean(sharedMap.getPath(from, to));
158 	}
159 
160 	/**
161 	 * Checks whether the edge is usable.
162 	 * 
163 	 * @param from
164 	 *            Starting nav point.
165 	 * @param edge
166 	 *            NeighNav object representing the edge.
167 	 * @return boolean
168 	 */
169 	public boolean checkLink(NavPointNeighbourLink edge) {
170 		return sharedMap.checkLink(edge);
171 
172 	}
173 
174 	/**
175 	 * Hook where to perform clean up of data structures of the module.
176 	 */
177 	@Override
178 	protected void cleanUp() {	
179 		super.cleanUp();
180 		sharedMap = null;
181 	}
182 
183 	public void refreshPathMatrix() {
184 		List<NavPoint> navPoints = MyCollections.asList(agent.getWorldView().getAll(NavPoint.class).values());
185 		sharedMap.refreshPathMatrix(navPoints);
186 	}
187 }