1 package cz.cuni.amis.pogamut.multi.communication.worldview.impl;
2
3 import java.util.LinkedList;
4 import java.util.Queue;
5 import java.util.logging.Level;
6
7 import cz.cuni.amis.pogamut.base.communication.translator.event.IWorldChangeEvent;
8 import cz.cuni.amis.pogamut.base.communication.translator.event.IWorldEventWrapper;
9 import cz.cuni.amis.pogamut.base.communication.translator.event.IWorldObjectUpdateResult;
10 import cz.cuni.amis.pogamut.base.communication.translator.event.IWorldObjectUpdatedEvent;
11 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEvent;
12 import cz.cuni.amis.pogamut.base.communication.worldview.impl.EventDrivenWorldView;
13 import cz.cuni.amis.pogamut.base.communication.worldview.object.event.WorldObjectDestroyedEvent;
14 import cz.cuni.amis.pogamut.base.communication.worldview.object.event.WorldObjectFirstEncounteredEvent;
15 import cz.cuni.amis.pogamut.base.communication.worldview.object.event.WorldObjectUpdatedEvent;
16 import cz.cuni.amis.pogamut.base.component.bus.exception.ComponentNotRunningException;
17 import cz.cuni.amis.pogamut.base.component.bus.exception.ComponentPausedException;
18 import cz.cuni.amis.pogamut.base.component.controller.ComponentController;
19 import cz.cuni.amis.pogamut.base.component.controller.ComponentDependencies;
20 import cz.cuni.amis.pogamut.base.component.lifecyclebus.ILifecycleBus;
21 import cz.cuni.amis.pogamut.base.utils.logging.IAgentLogger;
22 import cz.cuni.amis.pogamut.multi.agent.ITeamedAgentId;
23 import cz.cuni.amis.pogamut.multi.communication.translator.event.ICompositeWorldObjectUpdatedEvent;
24 import cz.cuni.amis.pogamut.multi.communication.translator.event.ILocalWorldObjectUpdatedEvent;
25 import cz.cuni.amis.pogamut.multi.communication.translator.event.ISharedWorldObjectUpdatedEvent;
26 import cz.cuni.amis.pogamut.multi.communication.translator.event.IStaticWorldObjectUpdatedEvent;
27 import cz.cuni.amis.pogamut.multi.communication.worldview.ISharedWorldView;
28 import cz.cuni.amis.pogamut.multi.communication.worldview.object.ICompositeWorldObject;
29 import cz.cuni.amis.pogamut.multi.communication.worldview.object.ILocalWorldObject;
30 import cz.cuni.amis.utils.NullCheck;
31 import cz.cuni.amis.utils.exception.PogamutException;
32
33 public abstract class EventDrivenLocalWorldView extends AbstractLocalWorldView {
34
35 public EventDrivenLocalWorldView(ComponentDependencies dependencies, ILifecycleBus bus, IAgentLogger logger, ISharedWorldView sharedWV, ITeamedAgentId agentId)
36 {
37 super(dependencies, bus, logger, sharedWV, agentId);
38 }
39
40 public static final String WORLDVIEW_DEPENDENCY = "EventDrivenWorldViewDependency";
41
42
43
44
45
46
47 protected boolean receiveEventProcessing = false;
48
49
50
51
52
53
54 protected LinkedList<IWorldChangeEvent> notifyEventsList =
55 new LinkedList<IWorldChangeEvent>();
56
57
58 @Override
59 public synchronized void notify(IWorldChangeEvent event) throws ComponentNotRunningException, ComponentPausedException {
60
61 if (log.isLoggable(Level.FINE)){log.fine("LocalWorldView notify( " + event.toString() + ")");};
62
63 if (isPaused()) {
64 throw new ComponentPausedException(controller.getState().getFlag(), this);
65 }
66 if (!isRunning()) {
67 throw new ComponentNotRunningException(controller.getState().getFlag(), this);
68 }
69
70 if (!( event instanceof ILocalWorldObjectUpdatedEvent))
71 {
72 if ( event instanceof ICompositeWorldObjectUpdatedEvent)
73 {
74 IWorldChangeEvent partEvent = ((ICompositeWorldObjectUpdatedEvent)event).getSharedEvent();
75 if (partEvent != null)
76 {
77 log.finest("Notyfying sharedWV " + event.toString() + ")");
78 sharedWorldView.notify(partEvent);
79 }
80 partEvent = ((ICompositeWorldObjectUpdatedEvent)event).getStaticEvent();
81 if ( partEvent != null)
82 {
83 log.finest("Notyfying sharedWV " + event.toString() + ")");
84 sharedWorldView.notify(partEvent);
85
86 }
87 }
88
89 else if ( (event instanceof ISharedWorldObjectUpdatedEvent) || (event instanceof IStaticWorldObjectUpdatedEvent) )
90 {
91 log.finest("Notyfying sharedWV " + event.toString() + ")");
92 sharedWorldView.notify(event);
93 return;
94 }
95 }
96
97
98
99 if (receiveEventProcessing) {
100
101
102
103 notifyEventsList.add(event);
104
105 return;
106 } else {
107
108 receiveEventProcessing = true;
109 }
110
111 try {
112 innerNotify(event);
113
114 while (notifyEventsList.size() != 0) {
115
116 innerNotify(notifyEventsList.poll());
117 }
118 } finally {
119
120 receiveEventProcessing = false;
121 }
122 }
123
124 @Override
125 public synchronized void notifyAfterPropagation(IWorldChangeEvent event) throws ComponentNotRunningException, ComponentPausedException {
126 notifyEventsList.addFirst(event);
127 }
128
129 @Override
130 public synchronized void notifyImmediately(IWorldChangeEvent event) throws ComponentNotRunningException, ComponentPausedException {
131
132 log.finest("LocalWorldView notify( " + event.toString() + ")");
133
134 if (isPaused()) {
135 throw new ComponentPausedException(controller.getState().getFlag(), this);
136 }
137 if (!isRunning()) {
138 throw new ComponentNotRunningException(controller.getState().getFlag(), this);
139 }
140
141 if (!( event instanceof ILocalWorldObjectUpdatedEvent))
142 {
143 if ( event instanceof ICompositeWorldObjectUpdatedEvent)
144 {
145 IWorldChangeEvent partEvent = ((ICompositeWorldObjectUpdatedEvent)event).getSharedEvent();
146 if (partEvent != null)
147 {
148 log.finest("Notyfying sharedWV " + event.toString() + ")");
149 sharedWorldView.notify(partEvent);
150 }
151 partEvent = ((ICompositeWorldObjectUpdatedEvent)event).getStaticEvent();
152 if ( partEvent != null)
153 {
154 log.finest("Notyfying sharedWV " + event.toString() + ")");
155 sharedWorldView.notify(partEvent);
156
157 }
158 }
159
160 else if ( (event instanceof ISharedWorldObjectUpdatedEvent) || (event instanceof IStaticWorldObjectUpdatedEvent) )
161 {
162 log.finest("Notyfying sharedWV " + event.toString() + ")");
163 sharedWorldView.notify(event);
164 return;
165 }
166 }
167
168
169
170 if (receiveEventProcessing) {
171
172
173
174 notifyEventsList.add(event);
175
176 return;
177 } else {
178
179 receiveEventProcessing = true;
180 }
181
182 try {
183 innerNotify(event);
184
185 while (notifyEventsList.size() != 0) {
186
187 innerNotify(notifyEventsList.poll());
188 }
189 } finally {
190
191 receiveEventProcessing = false;
192 }
193 }
194
195
196
197
198
199
200 @Override
201 protected void raiseEvent(IWorldEvent event) {
202 try {
203
204 super.raiseEvent(event);
205 } catch (Exception e) {
206 this.controller.fatalError("Exception raising event " + event, e);
207 this.kill();
208 }
209 }
210
211
212
213
214
215
216
217
218
219
220 protected void innerNotify(IWorldChangeEvent event) {
221
222 NullCheck.check(event, "event");
223 if (log.isLoggable(Level.FINEST)) log.finest("processing " + event);
224
225 if (event instanceof ILocalWorldObjectUpdatedEvent)
226 {
227 objectUpdatedEvent((ILocalWorldObjectUpdatedEvent)event);
228 }
229 else if ( event instanceof ICompositeWorldObjectUpdatedEvent )
230 {
231
232 ILocalWorldObjectUpdatedEvent locEvent = ((ICompositeWorldObjectUpdatedEvent)event).getLocalEvent();
233 if ( locEvent != null )
234 {
235 objectUpdatedEvent(locEvent);
236 }
237 }
238 else
239 {
240 if (event instanceof IWorldEventWrapper)
241 {
242 raiseEvent(((IWorldEventWrapper) event).getWorldEvent());
243 }
244 else if (event instanceof IWorldEvent)
245 {
246 raiseEvent((IWorldEvent)event);
247 }
248 else
249 {
250 throw new PogamutException("Unsupported event type received (" + event.getClass() + ").", this);
251 }
252 }
253 }
254
255
256
257
258
259
260
261 protected void objectUpdatedEvent(ILocalWorldObjectUpdatedEvent updateEvent) {
262
263 ILocalWorldObject obj = getMostRecentLocalWorldObject( updateEvent.getId() );
264
265
266 ILocalWorldObject copy = null;
267
268 if ( obj != null)
269 {
270
271 copy = obj.clone();
272 }
273 else
274 {
275 copy = null;
276 }
277
278 IWorldObjectUpdateResult<ILocalWorldObject> updateResult = updateEvent.update(copy);
279 switch (updateResult.getResult()) {
280 case CREATED:
281
282 ((EventDrivenSharedWorldView)sharedWorldView).addMsgClass(updateResult.getObject().getId(), updateResult.getObject().getCompositeClass());
283 objectCreated(updateResult.getObject(), updateEvent.getSimTime());
284 return;
285 case UPDATED:
286
287 if (updateResult.getObject() != copy) {
288 throw new PogamutException("Update event " + updateEvent + " did not return the same instance of the object (result UPDATED).", this);
289 }
290
291
292
293 super.addOldLocalWorldObject( obj, updateEvent.getSimTime() );
294
295 actLocalWorldObjects.put(copy.getId(), copy);
296 objectUpdated(copy, updateEvent.getSimTime());
297
298 return;
299 case SAME:
300 return;
301 case DESTROYED:
302
303 super.addOldLocalWorldObject(obj, updateEvent.getSimTime() );
304 objectDestroyed(copy, updateEvent.getSimTime());
305 return;
306 default:
307 throw new PogamutException("Unhandled object update result " + updateResult.getResult() + " for the object " + obj + ".", this);
308 }
309 }
310
311
312
313
314
315
316
317
318
319 protected void objectCreated(ILocalWorldObject obj, long time) {
320 addLocalWorldObject(obj);
321 }
322
323
324
325
326
327
328
329
330
331 protected void objectUpdated(ILocalWorldObject obj, long time) {
332 }
333
334
335
336
337
338
339
340
341 protected void objectDestroyed(ILocalWorldObject obj, long time) {
342 removeLocalWorldObject(obj);
343 }
344
345
346
347 }