1 package cz.cuni.amis.pogamut.ut2004.agent.module.logic;
2
3 import java.util.logging.Level;
4 import java.util.logging.Logger;
5
6 import com.google.inject.Inject;
7
8 import cz.cuni.amis.pogamut.base.agent.module.IAgentLogic;
9 import cz.cuni.amis.pogamut.base.communication.command.ICommandListener;
10 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEvent;
11 import cz.cuni.amis.pogamut.base.communication.worldview.react.EventReact;
12 import cz.cuni.amis.pogamut.base.communication.worldview.react.ObjectEventReact;
13 import cz.cuni.amis.pogamut.base.component.controller.ComponentDependencies;
14 import cz.cuni.amis.pogamut.base.component.controller.ComponentDependencyType;
15 import cz.cuni.amis.pogamut.base3d.ILockableVisionWorldView;
16 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
17 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.Respawn;
18 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.ConfigChange;
19 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.EndMessage;
20
21 public class SyncUT2004BotLogic<BOT extends UT2004Bot<? extends ILockableVisionWorldView, ?, ?>> extends UT2004BotLogic<BOT> {
22
23 private ObjectEventReact<ConfigChange, ?> configChangeReaction;
24
25 private EventReact<EndMessage> endReactionAfterRespawn;
26 private int shouldExecuteLogicLatch = 0;
27
28 protected ConfigChange config;
29
30 private ICommandListener<Respawn> respawnListener = new ICommandListener<Respawn>() {
31
32 @Override
33 public void notify(Respawn event) {
34 synchronized(respawnListener) {
35 endReactionAfterRespawn.enable();
36 shouldExecuteLogicLatch = 2;
37 }
38 }
39
40 };
41
42 @Inject
43 public SyncUT2004BotLogic(BOT agent, IAgentLogic logic) {
44 this(agent, logic, null, new ComponentDependencies(ComponentDependencyType.STARTS_AFTER).add(agent.getWorldView()));
45 }
46
47 public SyncUT2004BotLogic(BOT agent, IAgentLogic logic, Logger log) {
48 this(agent, logic, log, new ComponentDependencies(ComponentDependencyType.STARTS_AFTER).add(agent.getWorldView()));
49 }
50
51 public SyncUT2004BotLogic(BOT agent, IAgentLogic logic, Logger log, ComponentDependencies dependencies) {
52 super(agent, logic, log, dependencies);
53 endReactionAfterRespawn = new EventReact<EndMessage>(EndMessage.class, agent.getWorldView()) {
54 @Override
55 protected void react(EndMessage event) {
56 synchronized(respawnListener) {
57 if (shouldExecuteLogicLatch > 0) {
58 --shouldExecuteLogicLatch;
59 }
60 }
61 }
62 };
63 agent.getAct().addCommandListener(Respawn.class, respawnListener);
64
65 configChangeReaction = new ObjectEventReact<ConfigChange, IWorldObjectEvent<ConfigChange>>(ConfigChange.class, agent.getWorldView()) {
66 @Override
67 protected void react(IWorldObjectEvent<ConfigChange> event) {
68 config = event.getObject();
69
70
71 setLogicFrequency(60);
72 }
73 };
74 }
75
76 protected long logicStartMillis = 0;
77
78 @Override
79 protected void beforeLogic(String threadName) {
80 super.beforeLogic(threadName);
81 if (log.isLoggable(Level.FINEST)) log.finest(threadName + ": Locking world view.");
82 agent.getWorldView().lock();
83 if (log.isLoggable(Level.FINER)) log.finer(threadName + ": World view locked.");
84 logicStartMillis = System.currentTimeMillis();
85 }
86
87 @Override
88 protected void afterLogic(String threadName) {
89 super.afterLogic(threadName);
90 long logicTime1 = System.currentTimeMillis() - logicStartMillis;
91
92 if (log.isLoggable(Level.FINEST)) log.finest(threadName + ": Unlocking world view.");
93 agent.getWorldView().unlock();
94 if (log.isLoggable(Level.FINER)) log.finer(threadName + ": World view unlocked.");
95
96 long logicTime2 = System.currentTimeMillis() - logicStartMillis;
97
98 long visionTime = (config == null ? 250 : (long)(config.getVisionTime() * 1000));
99
100 if (logicTime1 > visionTime - 20) {
101 if (log.isLoggable(Level.WARNING)) log.warning("!!! Bot logic takes too long: " + logicTime1 + " ms ~>" + visionTime + " == vision time, you will probably miss next update from GB2004.");
102 } else
103 if (logicTime2 > visionTime - 20) {
104 if (log.isLoggable(Level.WARNING)) log.warning("!!! Bot logic (" + logicTime1 + "ms) + WorldView unlocking (" + (logicTime2 - logicTime1) + "ms) takes too long: " + logicTime2 + " ms ~>" + visionTime + " == vision time, you will probably miss next update from GB2004.");
105 }
106 }
107
108 @Override
109 protected void afterLogicException(String threadName, Throwable e) {
110 super.afterLogicException(threadName, e);
111 if (agent.getWorldView().isLocked()) {
112 if (log.isLoggable(Level.FINEST)) log.finest("Unlocking world view.");
113 agent.getWorldView().unlock();
114 if (log.isLoggable(Level.FINER)) log.finer("World view unlocked.");
115 }
116 }
117
118 @Override
119 protected boolean shouldExecuteLogic() {
120 synchronized(respawnListener) {
121 if (shouldExecuteLogicLatch != 0) {
122 if (log.isLoggable(Level.INFO)) log.info("Respawn command sensed - waiting for the bot respawn to execute logic with correct world view state.");
123 return false;
124 } else {
125 return true;
126 }
127 }
128 }
129
130 }