1 package cz.cuni.amis.pogamut.base3d.worldview;
2
3 import java.util.Collections;
4 import java.util.HashMap;
5 import java.util.Map;
6
7 import com.google.inject.Inject;
8
9 import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView;
10 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObject;
11 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEvent;
12 import cz.cuni.amis.pogamut.base.communication.worldview.object.WorldObjectId;
13 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectListener;
14 import cz.cuni.amis.pogamut.base.utils.guice.AgentScoped;
15 import cz.cuni.amis.pogamut.base.utils.logging.IAgentLogger;
16 import cz.cuni.amis.pogamut.base3d.worldview.object.IViewable;
17 import cz.cuni.amis.utils.ClassUtils;
18
19
20
21
22
23
24
25 @AgentScoped
26 public class Vision implements IWorldObjectListener<IViewable> {
27
28
29
30
31
32
33
34
35
36
37
38
39
40 private Map seeObjects =
41 Collections.synchronizedMap(
42 new HashMap()
43 );
44
45
46
47
48 private Map immutableSeeObjects =
49 Collections.unmodifiableMap(
50 seeObjects
51 );
52
53
54
55
56 private Map<WorldObjectId, IWorldObject> seeObjectsId =
57 Collections.synchronizedMap(
58 new HashMap<WorldObjectId, IWorldObject>()
59 );
60
61 @Inject
62 public Vision(IWorldView worldView, IAgentLogger logger) {
63
64 worldView.addObjectListener(IViewable.class, IWorldObjectEvent.class, this);
65 }
66
67 @Override
68 public void notify(IWorldObjectEvent<IViewable> event) {
69 IWorldObject obj = seeObjectsId.get(event.getId());
70 if (obj != null) {
71 if (((IViewable)obj).isVisible()) {
72 if (seeObjects.get(event.getId()) == null) {
73 addSeeObject(obj);
74 }
75 } else {
76 if (seeObjects.get(event.getId()) != null) {
77 removeSeeObject(obj);
78 }
79 }
80 } else {
81 IViewable object = event.getObject();
82 if (object.isVisible()) {
83 if (seeObjects.get(event.getId()) == null) {
84 addSeeObject(obj);
85 }
86 } else {
87 if (seeObjects.get(event.getId()) != null) {
88 removeSeeObject(obj);
89 }
90 }
91 }
92 }
93
94
95
96
97
98
99
100
101
102
103
104
105
106 protected synchronized <T> Map<WorldObjectId, T> addNewObjectCategory(Class<T> cls) {
107 Map<WorldObjectId, T> objects = Collections.synchronizedMap(new HashMap<WorldObjectId, T>());
108 seeObjects.put(cls, objects);
109 immutableSeeObjects.put(cls, Collections.unmodifiableMap(objects));
110 return objects;
111 }
112
113
114
115
116
117
118 protected void addSeeObject(IWorldObject seeObject) {
119 seeObjectsId.put(seeObject.getId(), seeObject);
120 for (Class cls : ClassUtils.getSubclasses(seeObject.getClass())) {
121 Map objects;
122 synchronized(seeObjects) {
123 objects = (Map) seeObjects.get(cls);
124 if (objects == null) objects = addNewObjectCategory(cls);
125 }
126 objects.put(seeObject.getId(), seeObject);
127 }
128 }
129
130
131
132
133
134
135 protected IWorldObject getSeeObject(WorldObjectId objectId) {
136 return seeObjectsId.get(objectId);
137 }
138
139
140
141
142
143
144 protected void removeSeeObject(IWorldObject worldObject) {
145 seeObjectsId.remove(worldObject.getId());
146 for (Class cls : ClassUtils.getSubclasses(worldObject.getClass())) {
147 Map objects = (Map) seeObjects.get(cls);
148 if (objects != null) {
149 objects.remove(worldObject.getId());
150 }
151 }
152 }
153
154
155
156
157
158
159
160 public Map<Class, Map<WorldObjectId, IWorldObject>> getSee() {
161 return immutableSeeObjects;
162 }
163
164
165
166
167
168
169
170
171
172 public <T> Map<WorldObjectId, T> getSee(Class<T> type) {
173
174
175
176 synchronized(seeObjects) {
177 Map<WorldObjectId, T> objects = (Map<WorldObjectId, T>) immutableSeeObjects.get(type);
178 if (objects == null) {
179 addNewObjectCategory(type);
180 return (Map<WorldObjectId, T>) immutableSeeObjects.get(type);
181 } else {
182 return objects;
183 }
184 }
185 }
186
187
188
189
190
191
192 public IWorldObject getSee(WorldObjectId id) {
193 return seeObjectsId.get(id);
194 }
195
196 }