View Javadoc

1   package cz.cuni.amis.pogamut.defcon.communication.translator;
2   
3   import java.util.LinkedList;
4   import java.util.List;
5   
6   import javabot.PogamutJBotSupport;
7   import javabot.events.DefConBasicUpdate;
8   import javabot.events.IDefConBasicEvent;
9   
10  import com.google.inject.Inject;
11  
12  import cz.cuni.amis.pogamut.base.communication.exception.CommunicationException;
13  import cz.cuni.amis.pogamut.base.communication.translator.event.IWorldChangeEvent;
14  import cz.cuni.amis.pogamut.base.communication.translator.event.IWorldChangeEventOutput;
15  import cz.cuni.amis.pogamut.base.component.bus.IComponentBus;
16  import cz.cuni.amis.pogamut.base.component.controller.ComponentControlHelper;
17  import cz.cuni.amis.pogamut.base.component.controller.ComponentController;
18  import cz.cuni.amis.pogamut.base.component.controller.ComponentDependencies;
19  import cz.cuni.amis.pogamut.base.component.controller.IComponentControlHelper;
20  import cz.cuni.amis.pogamut.base.utils.guice.AgentScoped;
21  import cz.cuni.amis.pogamut.base.utils.logging.IAgentLogger;
22  import cz.cuni.amis.pogamut.base.utils.logging.LogCategory;
23  import cz.cuni.amis.pogamut.defcon.agent.module.sensor.GameInfo;
24  import cz.cuni.amis.pogamut.defcon.communication.messages.infos.EventBatchBegin;
25  import cz.cuni.amis.pogamut.defcon.communication.messages.infos.EventBatchEnd;
26  import cz.cuni.amis.pogamut.defcon.communication.worldview.DefConWorldView;
27  import cz.cuni.amis.utils.token.IToken;
28  import cz.cuni.amis.utils.token.Token;
29  import cz.cuni.amis.utils.token.Tokens;
30  
31  /**
32   * This class retrieves events from GameInfo class and prepares them for the next stage of
33   * processing in {@link DefConWorldView}.
34   *  
35   * @author Radek 'Black_Hand' Pibil
36   *
37   */
38  @AgentScoped
39  public class DefConMessageProducer implements IWorldChangeEventOutput {
40  	
41  	public static final Token COMPONENT_ID = Tokens.get("DefConMessageProducer");	
42  
43  	/**
44  	 * Enqueued events ready for processing.
45  	 */
46  	private LinkedList<IWorldChangeEvent> eventQueue = new LinkedList<IWorldChangeEvent>();
47  	
48  	private float startTime;
49  	
50  	private boolean defConStarted = false;
51  	
52  	private IComponentBus eventBus;
53  
54  	private ComponentController controller;	
55  	
56  	private LogCategory log;
57  	
58  	private GameInfo gameInfo;	
59  			
60  	@Inject
61  	public DefConMessageProducer(
62  			IComponentBus eventBus,
63  			IAgentLogger logger) {
64  		
65  		log = logger.getCategory(COMPONENT_ID.getToken());
66  		this.eventBus = eventBus;
67  		this.controller = new ComponentController(this, control, this.eventBus, log,
68  				new ComponentDependencies());
69  		
70  		gameInfo = new GameInfo();
71  	}
72  
73  	private IComponentControlHelper control = new ComponentControlHelper() {
74  	
75  		@Override
76  		public void start() {
77  			eventQueue.clear();
78  			eventQueue.add(new EventBatchBegin(0));		
79  			startTime = gameInfo.getGameTime();
80  			defConStarted = false;
81  		}
82  		
83  		@Override
84  		public void reset() {
85  			start();
86  		}		
87  	};	
88  	
89  	/**
90  	 * Used by worldview to retrieve one enqueued event.
91  	 * Works only if the game has been started.
92  	 * 
93  	 * @return dequeued event
94  	 */
95  	@Override
96  	public IWorldChangeEvent getEvent() throws CommunicationException {
97  		if (!defConStarted) {
98  			if (!gameInfo.getRunning())
99  				return null;
100 
101 			startTime = gameInfo.getGameTime();
102 			defConStarted = true;
103 		}
104 
105 		if (eventQueue.size() != 0)
106 			return eventQueue.poll();
107 		else
108 			return null;
109 	}
110 	
111 	/**
112 	 * Retrieves all events from GameInfo instance and stores them in the eventQueue.
113 	 * Unit updates are retrieved as well by {@link getUnitsUpdate()}.
114 	 * <p><p>
115 	 * It also creates {@link EventBatchEnd} and {@link EventBatchBegin} between each of the retrievals
116 	 * to ensure proper batch processing.
117 	 */
118 	private void populateQueue() {
119 		List<IDefConBasicEvent> events = PogamutJBotSupport.getEvents();
120 		for (IDefConBasicEvent event : events) {
121 			if (event instanceof DefConBasicUpdate) {
122 				// BATCH END
123 				eventQueue.addAll(gameInfo.getEvents());
124 				eventQueue.addAll(getUnitsUpdate());
125 				eventQueue.add(new EventBatchEnd(gameInfo.getGameTime()));
126 				eventQueue.add(new EventBatchBegin(gameInfo.getGameTime()));
127 			} else {
128 				eventQueue.add(event);
129 			}
130 		}
131 	}
132 
133 	/**
134 	 * Collects all updates of all visible units.
135 	 * 
136 	 * @return LinkedList of all collected events.
137 	 */
138 	private List<IWorldChangeEvent> getUnitsUpdate() {
139 		return PogamutJBotSupport.getUnitsUpdate();
140 	}
141 
142 	@Override
143 	public String toString() {
144 		return "DefConMessageProducer[startTime=" + startTime + "]";
145 	}
146 
147 	@Override
148 	public IToken getComponentId() {
149 		return COMPONENT_ID;
150 	}
151 	
152 	/**
153 	 * Since update is called periodically from worldview, we use it to call populateQueue() periodically
154 	 */
155 	public void update() {
156 		populateQueue();
157 	}
158 
159 	public float getStartTime() {
160 		return startTime;
161 	}
162 
163 	public float getCurrentTime() {
164 		return gameInfo.getGameTick();
165 	}
166 	
167 	public GameInfo getGameInfo() {
168 		return gameInfo;
169 	}
170 }