1 package cz.cuni.amis.pogamut.udk.agent.navigation;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.logging.Logger;
6
7 import cz.cuni.amis.pogamut.base.agent.navigation.IPathFuture;
8 import cz.cuni.amis.pogamut.base.agent.navigation.impl.PathFuture;
9 import cz.cuni.amis.pogamut.base.communication.worldview.react.EventReact;
10 import cz.cuni.amis.pogamut.base.communication.worldview.react.EventReactOnce;
11 import cz.cuni.amis.pogamut.base3d.worldview.IVisionWorldView;
12 import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
13 import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
14 import cz.cuni.amis.pogamut.udk.bot.impl.UDKBot;
15 import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
16 import cz.cuni.amis.pogamut.udk.communication.messages.gbcommands.GetPath;
17 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.EndMessage;
18 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.NavPoint;
19 import cz.cuni.amis.pogamut.udk.communication.translator.shared.events.Path;
20 import cz.cuni.amis.utils.future.FutureStatus;
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 public class UDKAStarPathFuture extends PathFuture<ILocated> {
36
37 private static final int PATH_TIMEOUT = 10;
38
39 private static Object idMutex = new Object();
40
41 private static long lastId = 0;
42
43 private String pathId;
44
45 private EventReactOnce<Path> pathReaction;
46
47 private EventReact<EndMessage> endReaction;
48
49 private IVisionWorldView worldView;
50
51 private Logger log;
52
53 private Double startTime;
54
55 public UDKAStarPathFuture(UDKBot bot, ILocated pathFrom, ILocated pathTo) {
56 super(pathFrom, pathTo, bot.getEventBus(), bot.getWorldView());
57 log = bot.getLogger().getCategory(this.getClass().getSimpleName());
58 synchronized(idMutex) {
59 pathId = "UDKAStarPathFuture_" + (++lastId);
60 }
61 pathReaction = new EventReactOnce<Path>(Path.class, bot.getWorldView()){
62 @Override
63 protected void react(Path event) {
64 if (pathId.equals(event.getPathId())) {
65 eventPath(event);
66 }
67 }
68 };
69 endReaction = new EventReact<EndMessage>(EndMessage.class, bot.getWorldView()) {
70 @Override
71 protected void react(EndMessage event) {
72 eventEndMessage(event);
73 }
74 };
75 log.finer("Requesting path from '" + pathFrom + "' to '" + pathTo + "' under id '" + pathId + "'.");
76 bot.getAct().act(new GetPath().setLocation(pathTo.getLocation()).setId(pathId));
77 log.fine("Path requested, listening for the result (timeout " + PATH_TIMEOUT + "s)");
78 worldView = bot.getWorldView();
79 }
80
81 @Override
82 protected boolean cancelComputation(boolean mayInterruptIfRunning) {
83 pathReaction.disable();
84 endReaction.disable();
85 return getStatus() == FutureStatus.FUTURE_IS_BEING_COMPUTED;
86 }
87
88 protected void eventEndMessage(EndMessage event) {
89 if (startTime == null) startTime = event.getTime();
90 if (event.getTime() - startTime > PATH_TIMEOUT) {
91 pathReaction.disable();
92 endReaction.disable();
93 if (getStatus() == FutureStatus.FUTURE_IS_BEING_COMPUTED) {
94 computationException(new UDKAStarPathTimeoutException("Path did not came from GB2004 in " + PATH_TIMEOUT + "s.", log, this));
95 }
96 }
97 }
98
99 protected void eventPath(Path event) {
100 endReaction.disable();
101 List<ILocated> result = new ArrayList<ILocated>(event.getPath().size());
102 for (int i = 0; i < event.getPath().size(); ++i) {
103 UnrealId routeId = event.getPath().get(i).getRouteId();
104 NavPoint nav = (NavPoint) worldView.get(routeId);
105 if (nav == null) {
106 result.add(event.getPath().get(i).getLocation());
107 } else {
108 result.add(nav);
109 }
110 }
111 setResult(result);
112 }
113
114 }