View Javadoc

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  				//setLogicFrequency(1 / (Math.max(0.05, event.getObject().getVisionTime() - 0.049)));
70  				// HOT FIX
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 }