1 package cz.cuni.amis.pogamut.ut2004.observer.impl;
2
3 import java.util.concurrent.TimeUnit;
4 import java.util.logging.Level;
5
6 import com.google.inject.Inject;
7
8 import cz.cuni.amis.pogamut.base.agent.IAgentId;
9 import cz.cuni.amis.pogamut.base.agent.impl.AbstractGhostAgent;
10 import cz.cuni.amis.pogamut.base.agent.state.impl.AgentStateStarting;
11 import cz.cuni.amis.pogamut.base.communication.command.IAct;
12 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
13 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEvent;
14 import cz.cuni.amis.pogamut.base.communication.worldview.react.ObjectEventReactOnce;
15 import cz.cuni.amis.pogamut.base.component.bus.IComponentBus;
16 import cz.cuni.amis.pogamut.base.component.bus.event.BusAwareCountDownLatch;
17 import cz.cuni.amis.pogamut.base.component.exception.ComponentCantStartException;
18 import cz.cuni.amis.pogamut.base.utils.guice.AgentScoped;
19 import cz.cuni.amis.pogamut.base.utils.logging.IAgentLogger;
20 import cz.cuni.amis.pogamut.base3d.worldview.IVisionWorldView;
21 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.PasswordReply;
22 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.Ready;
23 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo;
24 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Password;
25 import cz.cuni.amis.pogamut.ut2004.communication.translator.shared.events.ReadyCommandRequest;
26 import cz.cuni.amis.pogamut.ut2004.observer.IUT2004Observer;
27 import cz.cuni.amis.utils.exception.PogamutInterruptedException;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 @AgentScoped
48 public abstract class AbstractUT2004Observer<WORLD_VIEW extends IVisionWorldView, ACT extends IAct> extends AbstractGhostAgent<WORLD_VIEW, ACT> implements IUT2004Observer {
49
50
51
52
53
54 private String desiredPassword = null;
55
56 private ObjectEventReactOnce<GameInfo, IWorldObjectEvent<GameInfo>> latchRaiseReact;
57
58 private BusAwareCountDownLatch latch;
59
60 @Inject
61 public AbstractUT2004Observer(IAgentId agentId, IComponentBus bus, IAgentLogger agentLogger, WORLD_VIEW worldView, ACT act) {
62 super(agentId, bus, agentLogger, worldView, act);
63
64 getWorldView().addEventListener(ReadyCommandRequest.class, readyCommandRequestListener);
65 getWorldView().addEventListener(Password.class, passwordRequestedListener);
66
67 latch = new BusAwareCountDownLatch(1, bus, getWorldView());
68
69 latchRaiseReact = new ObjectEventReactOnce<GameInfo, IWorldObjectEvent<GameInfo>>(
70 GameInfo.class, getWorldView()
71 ) {
72 @Override
73 protected void react(IWorldObjectEvent<GameInfo> event) {
74 latch.countDown();
75 }
76 };
77
78
79 }
80
81
82
83
84
85
86 public void setPassword(String password) {
87 this.desiredPassword = password;
88 }
89
90
91
92
93
94
95
96
97
98
99
100 protected void readyCommandRequested() {
101 getAct().act(new Ready());
102 }
103
104
105
106
107
108
109 private IWorldEventListener<ReadyCommandRequest> readyCommandRequestListener = new IWorldEventListener<ReadyCommandRequest>() {
110
111 @Override
112 public void notify(ReadyCommandRequest event) {
113 setState(new AgentStateStarting("GameBots2004 greeted us, sending READY."));
114 readyCommandRequested();
115 setState(new AgentStateStarting("READY sent."));
116 }
117 };
118
119
120
121
122
123
124
125
126
127
128
129
130
131 private PasswordReply passwordReply = null;
132
133
134
135
136
137
138
139
140
141
142
143 public PasswordReply getPasswordReply() {
144 return passwordReply;
145 }
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165 protected PasswordReply createPasswordReply() {
166 return desiredPassword != null ? new PasswordReply(desiredPassword)
167 : null;
168 }
169
170
171
172
173
174 private IWorldEventListener<Password> passwordRequestedListener = new IWorldEventListener<Password>() {
175
176 @Override
177 public void notify(Password event) {
178 setState(new AgentStateStarting("Password requested by the world."));
179 passwordReply = createPasswordReply();
180 if (passwordReply == null) {
181 passwordReply = new PasswordReply("");
182 }
183 if (log.isLoggable(Level.INFO)) log.info("Password required for the world, replying with '"
184 + passwordReply.getPassword() + "'.");
185 getAct().act(passwordReply);
186 }
187 };
188
189 @Override
190 public WORLD_VIEW getWorldView() {
191 return super.getWorldView();
192 }
193
194
195
196
197
198
199
200
201
202
203 protected void reset() {
204 latch.countDown();
205 latch = new BusAwareCountDownLatch(1, getEventBus(), getWorldView());
206 latchRaiseReact.enable();
207 }
208
209 @Override
210 protected void startAgent() {
211 super.startAgent();
212 if (!latch.await(60000, TimeUnit.MILLISECONDS)) {
213 throw new ComponentCantStartException("GameInfo message was not received in 60 secs.", this);
214 }
215 try {
216 Thread.sleep(1000);
217 } catch (InterruptedException e) {
218 throw new PogamutInterruptedException(e, this);
219 }
220 }
221
222 @Override
223 protected void startPausedAgent() {
224 super.startPausedAgent();
225 if (!latch.await(60000, TimeUnit.MILLISECONDS)) {
226 throw new ComponentCantStartException("GameInfo message was not received in 60 secs.", this);
227 }
228 try {
229 Thread.sleep(1000);
230 } catch (InterruptedException e) {
231 throw new PogamutInterruptedException(e, this);
232 }
233 }
234
235 @Override
236 protected void resetAgent() {
237 super.resetAgent();
238 reset();
239 }
240
241 @Override
242 protected void stopAgent() {
243 super.stopAgent();
244 reset();
245 }
246
247 @Override
248 protected void killAgent() {
249 super.killAgent();
250 reset();
251 }
252 }