1 package cz.cuni.amis.pogamut.udk.agent.module.logic;
2
3 import java.util.concurrent.TimeUnit;
4 import java.util.logging.Logger;
5
6 import com.google.inject.Inject;
7
8 import cz.cuni.amis.pogamut.base.agent.exceptions.AgentException;
9 import cz.cuni.amis.pogamut.base.agent.module.IAgentLogic;
10 import cz.cuni.amis.pogamut.base.agent.module.LogicModule;
11 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEvent;
12 import cz.cuni.amis.pogamut.base.communication.worldview.react.EventReact;
13 import cz.cuni.amis.pogamut.base.communication.worldview.react.EventReactOnce;
14 import cz.cuni.amis.pogamut.base.communication.worldview.react.ObjectEventReact;
15 import cz.cuni.amis.pogamut.base.communication.worldview.react.ObjectEventReactOnce;
16 import cz.cuni.amis.pogamut.base.component.bus.event.BusAwareCountDownLatch;
17 import cz.cuni.amis.pogamut.base.component.controller.ComponentDependencies;
18 import cz.cuni.amis.pogamut.base.component.controller.ComponentDependencyType;
19 import cz.cuni.amis.pogamut.base.component.exception.ComponentCantStartException;
20 import cz.cuni.amis.pogamut.udk.bot.impl.UDKBot;
21 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.EndMessage;
22 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo;
23 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GamePaused;
24 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameResumed;
25
26 import java.util.logging.Level;
27
28 public class UDKBotLogic<BOT extends UDKBot> extends LogicModule<BOT> {
29
30 private EventReact<GamePaused> pauseReaction;
31 private EventReact<GameResumed> resumeReaction;
32 private ObjectEventReact<GameInfo, ?> gameInfoReaction;
33 private EventReact<EndMessage> endReaction;
34 private BusAwareCountDownLatch latch;
35
36 @Inject
37 public UDKBotLogic(BOT agent, IAgentLogic logic) {
38 this(agent, logic, null, new ComponentDependencies(ComponentDependencyType.STARTS_WITH).add(agent.getWorldView()));
39 }
40
41 public UDKBotLogic(BOT agent, IAgentLogic logic, Logger log) {
42 this(agent, logic, log, new ComponentDependencies(ComponentDependencyType.STARTS_WITH).add(agent.getWorldView()));
43 }
44
45 public UDKBotLogic(BOT agent, IAgentLogic logic, Logger log, ComponentDependencies dependencies) {
46 super(agent, logic, log, dependencies);
47 pauseReaction = new EventReact<GamePaused>(GamePaused.class, agent.getWorldView()) {
48 @Override
49 protected void react(GamePaused event) {
50 controller.manualPause("Game paused.");
51 }
52 };
53 resumeReaction = new EventReact<GameResumed>(GameResumed.class, agent.getWorldView()) {
54 @Override
55 protected void react(GameResumed event) {
56 controller.manualResume("Game resumed.");
57 }
58 };
59 gameInfoReaction = new ObjectEventReactOnce<GameInfo, IWorldObjectEvent<GameInfo>>(GameInfo.GameInfoId, agent.getWorldView()) {
60 @Override
61 protected void react(IWorldObjectEvent<GameInfo> event) {
62 if (event.getObject().isBotsPaused() || event.getObject().isGamePaused()) {
63 controller.manualPause("Bot launched into paused game.");
64 }
65 }
66 };
67 endReaction = new EventReactOnce<EndMessage>(EndMessage.class, agent.getWorldView()) {
68 @Override
69 protected void react(EndMessage event) {
70 latch.countDown();
71 }
72 };
73 }
74
75 @Override
76 protected void logicLatch(String threadName) {
77 super.logicLatch(threadName);
78 if (log.isLoggable(Level.FINE)) log.fine(threadName + ": Waiting for the first End message.");
79 if (!latch.await(60, TimeUnit.SECONDS)) {
80 throw new ComponentCantStartException("End message was not received in 60secs.", this);
81 }
82 if (log.isLoggable(Level.INFO)) log.info(threadName + ": First END message received, starting logic cycles.");
83 }
84
85 @Override
86 protected void start(boolean startPaused) throws AgentException {
87 super.start(startPaused);
88 gameInfoReaction.enable();
89 endReaction.enable();
90 latch = new BusAwareCountDownLatch(1, agent.getEventBus(), agent.getWorldView().getComponentId());
91 }
92
93 }