1 package cz.cuni.amis.pogamut.base3d.worldview.impl;
2
3 import java.util.ArrayList;
4 import java.util.LinkedList;
5 import java.util.List;
6 import java.util.Queue;
7
8 import com.google.inject.name.Named;
9
10 import cz.cuni.amis.pogamut.base.communication.translator.event.IWorldChangeEvent;
11 import cz.cuni.amis.pogamut.base.communication.worldview.ILockableWorldView;
12 import cz.cuni.amis.pogamut.base.component.bus.IComponentBus;
13 import cz.cuni.amis.pogamut.base.component.controller.ComponentDependencies;
14 import cz.cuni.amis.pogamut.base.utils.logging.IAgentLogger;
15 import java.util.logging.Level;
16
17 public abstract class LockableBatchAwareWorldView extends BatchAwareWorldView implements ILockableWorldView {
18
19 public static final String WORLDVIEW_DEPENDENCY = "LockableBatchAwareWorldView";
20
21
22
23
24 private Queue<List<IWorldChangeEvent>> batches = new LinkedList<List<IWorldChangeEvent>>();
25
26
27
28
29 private List<IWorldChangeEvent> currentBatch = new ArrayList<IWorldChangeEvent>();
30
31
32
33
34 private boolean locked = false;
35
36
37
38
39 private boolean beginCame = false;
40
41
42
43
44 private final Object objectMutex = new Object();
45
46 public LockableBatchAwareWorldView(@Named(WORLDVIEW_DEPENDENCY) ComponentDependencies dependencies, IComponentBus bus, IAgentLogger log) {
47 super(dependencies, bus, log);
48 }
49
50
51
52
53
54
55 protected abstract boolean isBatchBeginEvent(IWorldChangeEvent evt);
56
57
58
59
60 public void lock() {
61 synchronized(objectMutex ) {
62 if (isLocked()) return;
63 locked = true;
64 if (log.isLoggable(Level.FINER)) log.finer("World view locked.");
65 }
66 }
67
68
69
70
71
72 public void unlock() {
73 synchronized(objectMutex) {
74 if (!isLocked()) return;
75 if (log.isLoggable(Level.FINER)) log.finer("World view is being unlocked.");
76 locked = false;
77 for (List<IWorldChangeEvent> batch : batches) {
78 processBatch(batch);
79 }
80 batches.clear();
81 if (log.isLoggable(Level.FINER)) log.finer("World view unlocked.");
82 }
83 }
84
85 public boolean isLocked() {
86 return locked;
87 }
88
89
90
91
92
93
94
95 private void processBatch(List<IWorldChangeEvent> batch) {
96 for (IWorldChangeEvent event : batch) {
97 super.notify(event);
98 }
99 }
100
101
102
103
104 @Override
105 public void notify(IWorldChangeEvent event) {
106 synchronized(objectMutex) {
107 if (!beginCame ) {
108 if (isBatchBeginEvent(event)) {
109 beginCame = true;
110 } else {
111 super.notify(event);
112 return;
113 }
114 }
115 if (isLocked()) {
116 if (isBatchEndEvent(event)) {
117 currentBatch .add(event);
118 batches.add(currentBatch);
119 currentBatch = new ArrayList<IWorldChangeEvent>(currentBatch.size()+20);
120 } else {
121 currentBatch.add(event);
122 }
123 } else {
124 if (isBatchEndEvent(event)) {
125 currentBatch.add(event);
126 processBatch(currentBatch);
127 currentBatch.clear();
128 } else {
129 currentBatch.add(event);
130 }
131 }
132 }
133 }
134
135 }