1 package cz.cuni.amis.pogamut.ut2004.agent.module.logic;
2
3 import java.util.concurrent.TimeUnit;
4 import java.util.logging.Level;
5 import java.util.logging.Logger;
6
7 import com.google.inject.Inject;
8
9 import cz.cuni.amis.pogamut.base.agent.exceptions.AgentException;
10 import cz.cuni.amis.pogamut.base.agent.module.IAgentLogic;
11 import cz.cuni.amis.pogamut.base.agent.module.LogicModule;
12 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEvent;
13 import cz.cuni.amis.pogamut.base.communication.worldview.react.EventReact;
14 import cz.cuni.amis.pogamut.base.communication.worldview.react.EventReactOnce;
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.ut2004.bot.impl.UT2004Bot;
21 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.EndMessage;
22 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo;
23 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GamePaused;
24 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameResumed;
25 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Self;
26 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.SelfLocal;
27 import cz.cuni.amis.utils.flag.Flag;
28
29 public class UT2004BotLogic<BOT extends UT2004Bot> extends LogicModule<BOT> {
30
31 private EventReact<GamePaused> pauseReaction;
32 private EventReact<GameResumed> resumeReaction;
33 private ObjectEventReactOnce<Self, ?> selfReaction;
34 private ObjectEventReactOnce<GameInfo, ?> gameInfoReaction;
35 private EventReact<EndMessage> endReaction;
36 private BusAwareCountDownLatch latch;
37
38 private Flag<Boolean> gameInfoCame = new Flag<Boolean>(false);
39 private Flag<Boolean> selfCame = new Flag<Boolean>(false);
40 private Flag<Boolean> endCame = new Flag<Boolean>(false);
41
42 @Inject
43 public UT2004BotLogic(BOT agent, IAgentLogic logic) {
44 this(agent, logic, null, new ComponentDependencies(ComponentDependencyType.STARTS_WITH).add(agent.getWorldView()));
45 }
46
47 public UT2004BotLogic(BOT agent, IAgentLogic logic, Logger log) {
48 this(agent, logic, log, new ComponentDependencies(ComponentDependencyType.STARTS_WITH).add(agent.getWorldView()));
49 }
50
51 public UT2004BotLogic(BOT agent, IAgentLogic logic, Logger log, ComponentDependencies dependencies) {
52 super(agent, logic, log, dependencies);
53 pauseReaction = new EventReact<GamePaused>(GamePaused.class, agent.getWorldView()) {
54 @Override
55 protected void react(GamePaused event) {
56 controller.manualPause("Game paused.");
57 }
58 };
59 resumeReaction = new EventReact<GameResumed>(GameResumed.class, agent.getWorldView()) {
60 @Override
61 protected void react(GameResumed event) {
62 controller.manualResume("Game resumed.");
63 }
64 };
65 gameInfoReaction = new ObjectEventReactOnce<GameInfo, IWorldObjectEvent<GameInfo>>(GameInfo.class, agent.getWorldView()) {
66 @Override
67 protected void react(IWorldObjectEvent<GameInfo> event) {
68 if (event.getObject().isBotsPaused() || event.getObject().isGamePaused()) {
69 controller.manualPause("Bot launched into paused game.");
70 }
71 gameInfoCame.setFlag(true);
72 }
73 };
74 selfReaction = new ObjectEventReactOnce<Self, IWorldObjectEvent<Self>>(Self.class, agent.getWorldView()) {
75 @Override
76 protected void react(IWorldObjectEvent<Self> event) {
77 selfCame.setFlag(true);
78 }
79 };
80
81 endReaction = new EventReactOnce<EndMessage>(EndMessage.class, agent.getWorldView()) {
82 @Override
83 protected void react(EndMessage event) {
84 synchronized(endCame) {
85 endCame.setFlag(true);
86 latch.countDown();
87 }
88 }
89 };
90 cleanUp();
91 }
92
93 @Override
94 protected void logicLatch(String threadName) {
95 super.logicLatch(threadName);
96 if (log.isLoggable(Level.FINE)) log.fine(threadName + ": Waiting for the first End message.");
97 if (!latch.await(120, TimeUnit.SECONDS)) {
98 throw new ComponentCantStartException("End message was not received in 120secs.", this);
99 }
100 if (log.isLoggable(Level.INFO)) log.info(threadName + ": First END message received, starting logic cycles.");
101 boolean came = selfCame.waitFor(60000, true);
102 if (!came) {
103 throw new ComponentCantStartException(threadName + ": SELF message DID NOT COME in 60secs! Even though End message has been received.", this);
104 }
105 if (!gameInfoCame.getFlag()) {
106 if (log.isLoggable(Level.WARNING)) log.warning(threadName + ": GAMEINFO message DID NOT COME! Even though End message has been received. Was it disabled in GameBot2004.ini? Or is it a bug... ?");
107 }
108 }
109
110 @Override
111 protected void start(boolean startPaused) throws AgentException {
112 super.start(startPaused);
113
114
115
116
117
118
119
120 synchronized(endCame) {
121 latch = new BusAwareCountDownLatch(1, agent.getEventBus(), agent.getWorldView().getComponentId());
122 if (endCame.getFlag()) {
123 latch.countDown();
124 }
125 }
126 }
127
128 @Override
129 protected void cleanUp() throws AgentException {
130 super.cleanUp();
131 gameInfoCame.setFlag(false);
132 selfCame.setFlag(false);
133 gameInfoReaction.enable();
134 selfReaction.enable();
135 endReaction.enable();
136 endCame.setFlag(false);
137 }
138
139 }