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