1 package cz.cuni.amis.pogamut.multi.communication.worldview.impl;
2
3 import java.lang.ref.WeakReference;
4 import java.util.Collection;
5 import java.util.Collections;
6 import java.util.HashMap;
7 import java.util.Map;
8 import java.util.Queue;
9 import java.util.Set;
10 import java.util.concurrent.ConcurrentLinkedQueue;
11 import java.util.logging.Level;
12
13 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEvent;
14 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
15 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObject;
16 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEvent;
17 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEventListener;
18 import cz.cuni.amis.pogamut.base.communication.worldview.object.WorldObjectId;
19 import cz.cuni.amis.pogamut.base.component.IComponent;
20 import cz.cuni.amis.pogamut.base.component.controller.ComponentControlHelper;
21 import cz.cuni.amis.pogamut.base.component.controller.ComponentController;
22 import cz.cuni.amis.pogamut.base.component.controller.ComponentDependencies;
23 import cz.cuni.amis.pogamut.base.component.controller.IComponentControlHelper;
24 import cz.cuni.amis.pogamut.base.component.lifecyclebus.ILifecycleBus;
25 import cz.cuni.amis.pogamut.base.utils.logging.IAgentLogger;
26 import cz.cuni.amis.pogamut.base.utils.logging.LogCategory;
27 import cz.cuni.amis.pogamut.multi.agent.ITeamedAgentId;
28 import cz.cuni.amis.pogamut.multi.communication.worldview.ILocalWorldView;
29 import cz.cuni.amis.pogamut.multi.communication.worldview.ISharedWorldView;
30 import cz.cuni.amis.pogamut.multi.communication.worldview.object.ICompositeWorldObject;
31 import cz.cuni.amis.pogamut.multi.communication.worldview.object.ILocalWorldObject;
32 import cz.cuni.amis.pogamut.multi.communication.worldview.object.ISharedWorldObject;
33 import cz.cuni.amis.pogamut.multi.communication.worldview.object.IStaticWorldObject;
34 import cz.cuni.amis.pogamut.multi.utils.exception.TimeKeyNotLockedException;
35 import cz.cuni.amis.pogamut.multi.utils.timekey.TimeKey;
36 import cz.cuni.amis.pogamut.multi.utils.timekey.TimeKeyManager;
37 import cz.cuni.amis.utils.ClassUtils;
38 import cz.cuni.amis.utils.exception.PogamutException;
39 import cz.cuni.amis.utils.listener.IListener;
40 import cz.cuni.amis.utils.listener.Listeners;
41 import cz.cuni.amis.utils.listener.ListenersMap;
42 import cz.cuni.amis.utils.maps.AbstractLazyMap;
43 import cz.cuni.amis.utils.maps.HashMapSet;
44 import cz.cuni.amis.utils.maps.LazyMap;
45 import cz.cuni.amis.utils.maps.WeakHashMapMap;
46 import cz.cuni.amis.utils.token.Token;
47 import cz.cuni.amis.utils.token.Tokens;
48
49
50
51
52
53
54
55
56
57 @SuppressWarnings({"rawtypes", "unchecked"})
58 public abstract class AbstractLocalWorldView implements ILocalWorldView {
59
60 public static final Token COMPONENT_ID = Tokens.get("AbstractLocalWorldView");
61
62
63 protected ISharedWorldView sharedWorldView;
64
65 protected ITeamedAgentId agentId;
66
67
68
69
70
71 protected Map<WorldObjectId, ILocalWorldObject> actLocalWorldObjects =
72 Collections.synchronizedMap( new HashMap<WorldObjectId, ILocalWorldObject>() );
73
74
75 protected HashMapSet<Class, WorldObjectId> classMap =
76 new HashMapSet<Class,WorldObjectId>();
77
78 protected Map<Class, Set<WorldObjectId> > syncClassMap =
79 Collections.synchronizedMap( classMap );
80
81
82 WeakHashMapMap<TimeKey, WorldObjectId, ILocalWorldObject> localWorldObjects =
83 new WeakHashMapMap<TimeKey, WorldObjectId, ILocalWorldObject>();
84
85
86
87
88
89
90
91
92 HashMap compositeClassMap =
93 new HashMap<Class<?>, LazyCompositeObjectMap<ICompositeWorldObject>>();
94
95
96
97
98
99 WeakHashMapMap<TimeKey, WorldObjectId, ICompositeWorldObject> cachedCompositeWorldObjects =
100 new WeakHashMapMap<TimeKey, WorldObjectId, ICompositeWorldObject>();
101
102
103 TimeKey currentTimeKey;
104
105
106
107
108 private static class ListenerNotifier<T> implements Listeners.ListenerNotifier<IListener> {
109
110
111
112
113 private T event = null;
114
115 @Override
116 public T getEvent() {
117 return event;
118 }
119
120 public void setEvent(T event) {
121 this.event = event;
122 }
123
124
125
126
127 @Override
128 public void notify(IListener listener) {
129 listener.notify(event);
130 }
131
132 }
133
134
135
136
137 private ListenerNotifier notifier = new ListenerNotifier();
138
139
140
141
142
143
144
145 private ListenersMap<Class> eventListeners = new ListenersMap<Class>();
146
147
148
149
150
151
152 private ListenersMap<Class> objectsListeners = new ListenersMap<Class>();
153
154
155
156
157
158
159
160
161 private Map<Class, ListenersMap<Class>> objectEventListeners =
162 Collections.synchronizedMap(
163 new LazyMap<Class, ListenersMap<Class>>(){
164
165 @Override
166 protected ListenersMap<Class> create(Class key) {
167 ListenersMap<Class> listeners = new ListenersMap<Class>();
168 listeners.setLog(log, "LevelC-" + key.getSimpleName());
169 return listeners;
170 }
171 }
172 );
173
174
175
176
177
178
179 private ListenersMap<WorldObjectId> specificObjectListeners = new ListenersMap<WorldObjectId>();
180
181
182
183
184
185
186
187
188 private Map<WorldObjectId, ListenersMap<Class>> specificObjectEventListeners =
189 Collections.synchronizedMap(
190 new LazyMap<WorldObjectId, ListenersMap<Class>>() {
191
192 @Override
193 protected ListenersMap<Class> create(WorldObjectId key) {
194 ListenersMap<Class> listeners = new ListenersMap<Class>();
195 listeners.setLog(log, "LevelE-" + key.getStringId());
196 return listeners;
197 }
198 }
199 );
200
201
202
203
204
205
206
207 private boolean raiseEventProcessing = false;
208
209
210
211
212
213
214 private Queue<IWorldEvent> raiseEventsList = new ConcurrentLinkedQueue<IWorldEvent>();
215
216 protected LogCategory log;
217
218 protected ILifecycleBus eventBus;
219
220 protected ComponentController<IComponent> controller;
221
222
223 public AbstractLocalWorldView(ComponentDependencies dependencies, ILifecycleBus bus, IAgentLogger logger, ISharedWorldView sharedWV, ITeamedAgentId agentId) {
224 this.log = logger.getCategory(getComponentId().getToken());
225 this.agentId = agentId;
226 this.eventBus = bus;
227 this.controller = new ComponentController(this, control, this.eventBus, this.log, dependencies);
228 this.sharedWorldView = sharedWV;
229 sharedWorldView.registerLocalWorldView(this, bus);
230
231 this.eventListeners.setLog(log, "LevelA");
232 this.objectsListeners.setLog(log, "LevelB");
233 this.specificObjectListeners.setLog(log, "LevelD");
234
235 }
236
237
238
239
240
241
242
243
244 protected IComponentControlHelper control = new ComponentControlHelper() {
245
246 @Override
247 public void start() throws PogamutException {
248 log.finest("LocalWorldView [ " + agentId + " ] Starting...");
249 AbstractLocalWorldView.this.start();
250 }
251
252 @Override
253 public void prePause() throws PogamutException {
254 AbstractLocalWorldView.this.prePause();
255 }
256
257 @Override
258 public void pause() throws PogamutException {
259 AbstractLocalWorldView.this.pause();
260 }
261
262 @Override
263 public void resume() throws PogamutException {
264 AbstractLocalWorldView.this.resume();
265 }
266
267 @Override
268 public void preStop() throws PogamutException {
269 AbstractLocalWorldView.this.preStop();
270 }
271
272 @Override
273 public void stop() throws PogamutException {
274 AbstractLocalWorldView.this.stop();
275 }
276
277 @Override
278 public void kill() {
279 AbstractLocalWorldView.this.kill();
280 }
281
282 @Override
283 public void reset() {
284 AbstractLocalWorldView.this.reset();
285 }
286
287 };
288
289
290
291
292
293
294 protected void cleanUp() {
295 synchronized( this.actLocalWorldObjects ) {
296 actLocalWorldObjects.clear();
297 }
298 synchronized(classMap) {
299 classMap.clear();
300 }
301 synchronized(raiseEventsList) {
302 raiseEventsList.clear();
303 }
304 }
305
306
307
308
309
310
311 protected void start() {
312 cleanUp();
313 }
314
315
316
317
318
319
320 protected void prePause() {
321 }
322
323
324
325
326
327
328 protected void pause() {
329 }
330
331
332
333
334
335
336 protected void resume() {
337 }
338
339
340
341
342
343
344 protected void preStop() {
345 }
346
347
348
349
350
351
352 protected void stop() {
353 cleanUp();
354 }
355
356
357
358
359
360
361 protected void kill() {
362 cleanUp();
363 }
364
365
366
367
368
369
370 protected void reset() {
371 cleanUp();
372 }
373
374 protected boolean isRunning() {
375 return controller.isRunning();
376 }
377
378 protected boolean isPaused() {
379 return controller.isPaused();
380 }
381
382 @Override
383 public Token getComponentId() {
384 return COMPONENT_ID;
385 }
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402 protected abstract ICompositeWorldObject createCompositeObject(ILocalWorldObject localObject, ISharedWorldObject sharedObject, IStaticWorldObject staticObject);
403
404
405
406
407
408
409 public ITeamedAgentId getAgentId()
410 {
411 return this.agentId;
412 }
413
414
415
416
417
418
419
420
421
422
423
424
425 protected class LazyCompositeObjectMap<T extends ICompositeWorldObject> extends AbstractLazyMap<WorldObjectId,T>
426 {
427
428 private long currentTime;
429 private WeakReference<TimeKey> timeKey;
430
431 public LazyCompositeObjectMap( long time)
432 {
433 super();
434 this.currentTime = time;
435 this.timeKey = new WeakReference<TimeKey>(TimeKey.get(currentTime));
436 }
437
438 LazyCompositeObjectMap(Set<WorldObjectId> keySet, long time)
439 {
440 super(keySet);
441 this.currentTime = time;
442 this.timeKey = new WeakReference<TimeKey>(TimeKey.get(currentTime));
443 }
444
445 public boolean setTimeKey( long newTime)
446 {
447 if (currentTimeKey.equals(newTime))
448 {
449 return false;
450 }
451 super.clearCache();
452 this.currentTime = newTime;
453 this.timeKey = new WeakReference<TimeKey>(TimeKey.get(currentTime));
454 return true;
455 }
456
457 @Override
458 protected T create(Object key) {
459 return (T)AbstractLocalWorldView.this.get((WorldObjectId)key, this.timeKey.get());
460 }
461
462 }
463
464
465
466
467
468
469 @Override
470 public ILocalWorldObject getLocal(WorldObjectId objectId) {
471 return getLocal(objectId, getCurrentTimeKey() );
472 }
473
474
475
476
477
478
479
480
481
482 protected ILocalWorldObject getLocal(WorldObjectId objectId, TimeKey time) {
483 ILocalWorldObject value = localWorldObjects.get( time, objectId );
484 if ( value != null) { return value; }
485 return actLocalWorldObjects.get( objectId );
486 }
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501 protected ICompositeWorldObject get(WorldObjectId objectId, TimeKey time) {
502 ICompositeWorldObject obj = cachedCompositeWorldObjects.get( time, objectId);
503 if ( obj != null )
504 {
505 return obj;
506 }
507 else
508 {
509 obj = createCompositeObject(
510 this.getLocal( objectId, time ),
511 sharedWorldView.getShared(agentId.getTeamId(), objectId, time),
512 sharedWorldView.getStatic(objectId));
513 cachedCompositeWorldObjects.put(time,objectId,obj);
514 }
515 return obj;
516 }
517
518 @Override
519 public ICompositeWorldObject get(WorldObjectId objectId) {
520 return this.get(objectId, getCurrentTimeKey() );
521 }
522
523 @Override
524 public <T extends ICompositeWorldObject> T get(WorldObjectId objectId, Class<T> clazz) {
525 IWorldObject obj = get(objectId);
526 if(obj == null){
527 return null;
528 }
529 else if(clazz.isAssignableFrom(obj.getClass())){
530 return (T)obj;
531 } else {
532 throw new ClassCastException("Object with id " + objectId + " is not of class " + clazz);
533 }
534 }
535
536
537
538
539
540
541
542
543
544 protected Map<Class, Map<WorldObjectId, ICompositeWorldObject>> getAll(TimeKey time) {
545 for ( Object oC : compositeClassMap.keySet() )
546 {
547 Class c = (Class)oC;
548 ((LazyCompositeObjectMap)(compositeClassMap.get(c))).setTimeKey( time.getTime() );
549 }
550 return compositeClassMap;
551 }
552
553
554 @Override
555
556
557
558
559 public Map<Class, Map<WorldObjectId, ICompositeWorldObject>> getAll() {
560 return getAll(getCurrentTimeKey());
561 }
562
563
564
565
566
567
568
569
570
571
572 protected <T extends IWorldObject> Map<WorldObjectId, T> getAll(Class<T> type,
573 TimeKey time)
574 {
575 LazyCompositeObjectMap map = (LazyCompositeObjectMap) this.compositeClassMap.get(type);
576 if ( map == null )
577 {
578 map = new LazyCompositeObjectMap(time.getTime());
579 compositeClassMap.put(type, map);
580 return map;
581 }
582
583 map.setTimeKey(time.getTime());
584 return map;
585 }
586
587 @Override
588 public <T extends IWorldObject> Map<WorldObjectId, T> getAll(Class<T> type) {
589 return getAll(type, getCurrentTimeKey());
590 }
591
592 @Override
593 public Map<WorldObjectId, ICompositeWorldObject> get() {
594 return get(getCurrentTimeKey());
595 }
596
597
598
599
600
601
602
603
604
605
606
607 protected Map<WorldObjectId, ICompositeWorldObject> get(TimeKey time)
608 {
609 LazyCompositeObjectMap objects = new LazyCompositeObjectMap(this.actLocalWorldObjects.keySet(),time.getTime());
610 return objects;
611 }
612
613
614
615 @Override
616 public <T extends IWorldObject> T getSingle(Class<T> cls) {
617 return this.getSingle(cls, this.getCurrentTimeKey());
618 }
619
620
621 protected <T extends IWorldObject> T getSingle(Class<T> cls, TimeKey time) {
622 Collection<T> vals = getAll(cls, time).values();
623 if (vals.size() == 1)
624 {
625 return vals.iterator().next();
626 }
627 throw new IllegalArgumentException();
628 }
629
630
631
632
633
634
635
636
637
638
639 protected ILocalWorldObject getMostRecentLocalWorldObject( WorldObjectId id )
640 {
641 return this.actLocalWorldObjects.get( id );
642 }
643
644
645
646
647 protected synchronized void addOldLocalWorldObject( ILocalWorldObject obj, long eventTime)
648 {
649
650 for (Long time : TimeKeyManager.get().getHeldKeys() )
651 {
652 if ( time < eventTime )
653 {
654 synchronized( localWorldObjects )
655 {
656 TimeKey timeKey = TimeKey.get(time);
657 if ( localWorldObjects.get( timeKey, obj.getId() ) == null)
658 {
659
660 localWorldObjects.put( timeKey , obj.getId(),obj);
661 }
662 }
663 }
664 }
665 }
666
667
668
669
670
671 protected synchronized void addLocalWorldObject( ILocalWorldObject obj)
672 {
673 actLocalWorldObjects.put(obj.getId(), obj);
674 for ( Class cls : ClassUtils.getSubclasses(obj.getCompositeClass()) )
675 {
676
677 LazyCompositeObjectMap map = (LazyCompositeObjectMap)compositeClassMap.get(cls);
678 if ( map == null)
679 {
680 map = new LazyCompositeObjectMap( currentTimeKey.getTime() );
681 compositeClassMap.put(cls, map);
682 }
683 map.keySet().add(obj.getId());
684 syncClassMap.get(cls).add( obj.getId() );
685 }
686
687 }
688
689
690
691
692
693 protected synchronized void removeLocalWorldObject( ILocalWorldObject obj)
694 {
695 actLocalWorldObjects.remove(obj.getId());
696 for ( Class cls : ClassUtils.getSubclasses(obj.getCompositeClass()) )
697 {
698 LazyCompositeObjectMap map = (LazyCompositeObjectMap)compositeClassMap.get(cls);
699 if ( map != null )
700 {
701 map.keySet().remove(obj.getId());
702 }
703 syncClassMap.get(cls).remove(obj.getId());
704 }
705
706 }
707
708
709
710
711
712
713
714
715
716
717
718 @Override
719 public boolean setInitialTime( TimeKey key )
720 {
721 if ( currentTimeKey == null )
722 {
723 currentTimeKey = key;
724 return true;
725 }
726 return false;
727 }
728
729 @Override
730 public boolean setCurrentTime( TimeKey key )
731 {
732 currentTimeKey = key;
733 return true;
734 }
735
736 @Override
737 public TimeKey getCurrentTimeKey() {
738 return this.currentTimeKey;
739 }
740
741 @Override
742 public void lockTime(long time) {
743 TimeKeyManager.get().lock(time);
744 }
745
746 @Override
747 public void unlockTime(long time) {
748 try {
749 TimeKeyManager.get().unlock(time);
750 } catch (TimeKeyNotLockedException e) {
751 log.warning("Trying to unlock timeKey : " + time + " which is not locked. ");
752 }
753 }
754
755
756
757
758
759
760 @Override
761 public void addEventListener(Class<?> event, IWorldEventListener<?> listener) {
762 eventListeners.add(event, listener);
763 }
764
765 @Override
766 public void addObjectListener(Class<?> objectClass, IWorldObjectEventListener<?, ?> listener) {
767 objectsListeners.add(objectClass, listener);
768 }
769
770 @Override
771 public void addObjectListener(Class<?> objectClass, Class<?> eventClass, IWorldObjectEventListener<?,?> listener) {
772 ListenersMap<Class> listeners = objectEventListeners.get(eventClass);
773 listeners.add(objectClass, listener);
774 }
775
776 @Override
777 public void addObjectListener(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener) {
778 specificObjectListeners.add(objectId, listener);
779 }
780
781 @Override
782 public void addObjectListener(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener) {
783 ListenersMap<Class> listeners = specificObjectEventListeners.get(objectId);
784 listeners.add(eventClass, listener);
785 }
786
787 @Override
788 public boolean isListening(Class<?> eventClass, IWorldEventListener<?> listener) {
789 return eventListeners.isListening(eventClass, listener);
790 }
791
792 @Override
793 public boolean isListening(Class<?> objectClass, IWorldObjectEventListener<?, ?> listener) {
794 return objectsListeners.isListening(listener);
795 }
796
797
798 @Override
799 public boolean isListening(Class<?> objectClass, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener) {
800 if (objectEventListeners.containsKey(objectClass)) {
801 return objectEventListeners.get(eventClass).isListening(objectClass, listener);
802 } else {
803 return false;
804 }
805 }
806
807 @Override
808 public boolean isListening(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener) {
809 return specificObjectListeners.isListening(objectId, listener);
810 }
811
812 @Override
813 public boolean isListening(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener) {
814 if (specificObjectEventListeners.containsKey(objectId)) {
815 return specificObjectEventListeners.get(objectId).isListening(eventClass, listener);
816 } else {
817 return false;
818 }
819
820 }
821
822 @Override
823 public boolean isListening(IWorldEventListener<?> listener) {
824 if (eventListeners.isListening(listener) ||
825 specificObjectListeners.isListening(listener)) {
826 return true;
827 }
828 synchronized(objectEventListeners) {
829 for (ListenersMap<Class> listeners : objectEventListeners.values()) {
830 if (listeners.isListening(listener)) return true;
831 }
832 }
833 synchronized(specificObjectEventListeners) {
834 for (ListenersMap<Class> listeners : specificObjectEventListeners.values()) {
835 if (listeners.isListening(listener)) return true;
836 }
837 }
838 return false;
839 }
840
841 @Override
842 public void removeEventListener(Class<?> eventClass, IWorldEventListener<?> listener) {
843 eventListeners.remove(eventClass, listener);
844 }
845
846 @Override
847 public void removeObjectListener(Class<?> objectClass, IWorldObjectEventListener<?, ?> listener) {
848 objectsListeners.remove(objectClass, listener);
849 }
850
851 @Override
852 public void removeObjectListener(Class<?> objectClass, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener) {
853 if (objectEventListeners.containsKey(eventClass)) {
854 objectEventListeners.get(eventClass).remove(objectClass, listener);
855 }
856 }
857
858 @Override
859 public void removeObjectListener(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener) {
860 specificObjectListeners.remove(objectId, listener);
861 }
862
863 @Override
864 public void removeObjectListener(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener) {
865 if (specificObjectEventListeners.containsKey(objectId)) {
866 specificObjectEventListeners.get(objectId).remove(eventClass, listener);
867 }
868 }
869
870
871 @Override
872 public void removeListener(IWorldEventListener<?> listener) {
873 eventListeners.remove(listener);
874 synchronized(objectEventListeners) {
875 for (ListenersMap<Class> listeners : objectEventListeners.values()) {
876 listeners.remove(listener);
877 }
878 }
879 specificObjectListeners.remove(listener);
880 specificObjectEventListeners.remove(listener);
881 }
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897 protected synchronized void raiseEvent(IWorldEvent event) {
898
899
900
901 if (raiseEventProcessing) {
902
903
904
905 raiseEventsList.add(event);
906 return;
907 } else {
908
909 raiseEventProcessing = true;
910 }
911
912
913 innerRaiseEvent(event);
914
915
916 while(raiseEventsList.size() != 0) {
917
918 innerRaiseEvent(raiseEventsList.poll());
919 }
920
921 raiseEventProcessing = false;
922 }
923
924
925
926
927
928
929
930
931
932
933
934 private void notifyLevelAListeners(IWorldEvent event) {
935 Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
936 notifier.setEvent(event);
937 for (Class eventClass : eventClasses) {
938 eventListeners.notify(eventClass, notifier);
939 }
940 }
941
942
943
944
945
946 private void notifyLevelBListeners(IWorldObjectEvent event) {
947 IWorldObject object = event.getObject();
948 Collection<Class> objectClasses = ClassUtils.getSubclasses(object.getClass());
949 notifier.setEvent(event);
950 for (Class objectClass : objectClasses) {
951 objectsListeners.notify(objectClass, notifier);
952 }
953 }
954
955
956
957
958
959
960 private void notifyLevelCListeners(IWorldObjectEvent event) {
961 Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
962 Collection<Class> objectClasses = ClassUtils.getSubclasses(event.getObject().getClass());
963 notifier.setEvent(event);
964 for (Class eventClass : eventClasses) {
965 ListenersMap<Class> listeners = objectEventListeners.get(eventClass);
966 if (listeners == null) continue;
967 if (!listeners.hasListeners()) continue;
968 for (Class objectClass : objectClasses) {
969 listeners.notify(objectClass, notifier);
970 }
971 }
972 }
973
974
975
976
977
978 private void notifyLevelDListeners(IWorldObjectEvent event) {
979 notifier.setEvent(event);
980 specificObjectListeners.notify(event.getId(), notifier);
981 }
982
983
984
985
986
987 private void notifyLevelEListeners(IWorldObjectEvent event) {
988 notifier.setEvent(event);
989 WorldObjectId objectId = event.getId();
990 ListenersMap<Class> listeners = specificObjectEventListeners.get(objectId);
991 if (listeners.hasListeners()) {
992 Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
993 notifier.setEvent(event);
994 for (Class eventClass : eventClasses) {
995 listeners.notify(eventClass, notifier);
996 }
997 }
998 }
999
1000
1001
1002
1003
1004
1005
1006
1007 private void innerRaiseEvent(IWorldEvent event) {
1008 if (log.isLoggable(Level.FINEST)) log.finest("notifying " + event);
1009 notifyLevelAListeners(event);
1010 if (event instanceof IWorldObjectEvent) {
1011
1012 IWorldObjectEvent objectEvent = (IWorldObjectEvent)event;
1013 notifyLevelBListeners(objectEvent);
1014 notifyLevelCListeners(objectEvent);
1015 notifyLevelDListeners(objectEvent);
1016 notifyLevelEListeners(objectEvent);
1017 }
1018 }
1019
1020 @Override
1021 public ILifecycleBus getEventBus() {
1022 return this.eventBus;
1023 }
1024
1025 }