diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/EntityManager.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/EntityManager.cs | 261 |
1 files changed, 41 insertions, 220 deletions
diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs index c246e32..0defa93 100644 --- a/OpenSim/Region/Framework/Scenes/EntityManager.cs +++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs | |||
@@ -34,227 +34,89 @@ using OpenMetaverse; | |||
34 | 34 | ||
35 | namespace OpenSim.Region.Framework.Scenes | 35 | namespace OpenSim.Region.Framework.Scenes |
36 | { | 36 | { |
37 | public class EntityManager : IEnumerable<EntityBase> | 37 | public class EntityManager |
38 | { | 38 | { |
39 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 39 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
40 | private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>(); | 40 | private readonly DoubleDictionary<UUID, uint, EntityBase> m_entities = new DoubleDictionary<UUID, uint, EntityBase>(); |
41 | private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>(); | ||
42 | //private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>(); | ||
43 | private System.Threading.ReaderWriterLockSlim m_lock = new System.Threading.ReaderWriterLockSlim(); | ||
44 | 41 | ||
45 | [Obsolete("Use Add() instead.")] | 42 | public int Count |
46 | public void Add(UUID id, EntityBase eb) | ||
47 | { | 43 | { |
48 | Add(eb); | 44 | get { return m_entities.Count; } |
49 | } | 45 | } |
50 | 46 | ||
51 | public void Add(EntityBase entity) | 47 | public void Add(EntityBase entity) |
52 | { | 48 | { |
53 | m_lock.EnterWriteLock(); | 49 | m_entities.Add(entity.UUID, entity.LocalId, entity); |
54 | try | ||
55 | { | ||
56 | try | ||
57 | { | ||
58 | m_eb_uuid.Add(entity.UUID, entity); | ||
59 | m_eb_localID.Add(entity.LocalId, entity); | ||
60 | } | ||
61 | catch(Exception e) | ||
62 | { | ||
63 | m_log.ErrorFormat("Add Entity failed: {0}", e.Message); | ||
64 | } | ||
65 | } | ||
66 | finally | ||
67 | { | ||
68 | m_lock.ExitWriteLock(); | ||
69 | } | ||
70 | } | ||
71 | |||
72 | public void InsertOrReplace(EntityBase entity) | ||
73 | { | ||
74 | m_lock.EnterWriteLock(); | ||
75 | try | ||
76 | { | ||
77 | try | ||
78 | { | ||
79 | m_eb_uuid[entity.UUID] = entity; | ||
80 | m_eb_localID[entity.LocalId] = entity; | ||
81 | } | ||
82 | catch(Exception e) | ||
83 | { | ||
84 | m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message); | ||
85 | } | ||
86 | } | ||
87 | finally | ||
88 | { | ||
89 | m_lock.ExitWriteLock(); | ||
90 | } | ||
91 | } | 50 | } |
92 | 51 | ||
93 | public void Clear() | 52 | public void Clear() |
94 | { | 53 | { |
95 | m_lock.EnterWriteLock(); | 54 | m_entities.Clear(); |
96 | try | ||
97 | { | ||
98 | m_eb_uuid.Clear(); | ||
99 | m_eb_localID.Clear(); | ||
100 | } | ||
101 | finally | ||
102 | { | ||
103 | m_lock.ExitWriteLock(); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | public int Count | ||
108 | { | ||
109 | get | ||
110 | { | ||
111 | return m_eb_uuid.Count; | ||
112 | } | ||
113 | } | 55 | } |
114 | 56 | ||
115 | public bool ContainsKey(UUID id) | 57 | public bool ContainsKey(UUID id) |
116 | { | 58 | { |
117 | try | 59 | return m_entities.ContainsKey(id); |
118 | { | ||
119 | return m_eb_uuid.ContainsKey(id); | ||
120 | } | ||
121 | catch | ||
122 | { | ||
123 | return false; | ||
124 | } | ||
125 | } | 60 | } |
126 | 61 | ||
127 | public bool ContainsKey(uint localID) | 62 | public bool ContainsKey(uint localID) |
128 | { | 63 | { |
129 | try | 64 | return m_entities.ContainsKey(localID); |
130 | { | ||
131 | return m_eb_localID.ContainsKey(localID); | ||
132 | } | ||
133 | catch | ||
134 | { | ||
135 | return false; | ||
136 | } | ||
137 | } | 65 | } |
138 | 66 | ||
139 | public bool Remove(uint localID) | 67 | public bool Remove(uint localID) |
140 | { | 68 | { |
141 | m_lock.EnterWriteLock(); | 69 | return m_entities.Remove(localID); |
142 | try | ||
143 | { | ||
144 | try | ||
145 | { | ||
146 | bool a = false; | ||
147 | EntityBase entity; | ||
148 | if (m_eb_localID.TryGetValue(localID, out entity)) | ||
149 | a = m_eb_uuid.Remove(entity.UUID); | ||
150 | |||
151 | bool b = m_eb_localID.Remove(localID); | ||
152 | return a && b; | ||
153 | } | ||
154 | catch (Exception e) | ||
155 | { | ||
156 | m_log.ErrorFormat("Remove Entity failed for {0}", localID, e); | ||
157 | return false; | ||
158 | } | ||
159 | } | ||
160 | finally | ||
161 | { | ||
162 | m_lock.ExitWriteLock(); | ||
163 | } | ||
164 | } | 70 | } |
165 | 71 | ||
166 | public bool Remove(UUID id) | 72 | public bool Remove(UUID id) |
167 | { | 73 | { |
168 | m_lock.EnterWriteLock(); | 74 | return m_entities.Remove(id); |
169 | try | ||
170 | { | ||
171 | try | ||
172 | { | ||
173 | bool a = false; | ||
174 | EntityBase entity; | ||
175 | if (m_eb_uuid.TryGetValue(id, out entity)) | ||
176 | a = m_eb_localID.Remove(entity.LocalId); | ||
177 | |||
178 | bool b = m_eb_uuid.Remove(id); | ||
179 | return a && b; | ||
180 | } | ||
181 | catch (Exception e) | ||
182 | { | ||
183 | m_log.ErrorFormat("Remove Entity failed for {0}", id, e); | ||
184 | return false; | ||
185 | } | ||
186 | } | ||
187 | finally | ||
188 | { | ||
189 | m_lock.ExitWriteLock(); | ||
190 | } | ||
191 | } | 75 | } |
192 | 76 | ||
193 | public List<EntityBase> GetAllByType<T>() | 77 | public EntityBase[] GetAllByType<T>() |
194 | { | 78 | { |
195 | List<EntityBase> tmp = new List<EntityBase>(); | 79 | List<EntityBase> tmp = new List<EntityBase>(); |
196 | 80 | ||
197 | m_lock.EnterReadLock(); | 81 | m_entities.ForEach( |
198 | try | 82 | delegate(EntityBase entity) |
199 | { | ||
200 | try | ||
201 | { | ||
202 | foreach (KeyValuePair<UUID, EntityBase> pair in m_eb_uuid) | ||
203 | { | ||
204 | if (pair.Value is T) | ||
205 | { | ||
206 | tmp.Add(pair.Value); | ||
207 | } | ||
208 | } | ||
209 | } | ||
210 | catch (Exception e) | ||
211 | { | 83 | { |
212 | m_log.ErrorFormat("GetAllByType failed for {0}", e); | 84 | if (entity is T) |
213 | tmp = null; | 85 | tmp.Add(entity); |
214 | } | 86 | } |
215 | } | 87 | ); |
216 | finally | ||
217 | { | ||
218 | m_lock.ExitReadLock(); | ||
219 | } | ||
220 | 88 | ||
221 | return tmp; | 89 | return tmp.ToArray(); |
222 | } | 90 | } |
223 | 91 | ||
224 | public List<EntityBase> GetEntities() | 92 | public EntityBase[] GetEntities() |
225 | { | 93 | { |
226 | m_lock.EnterReadLock(); | 94 | List<EntityBase> tmp = new List<EntityBase>(m_entities.Count); |
227 | try | 95 | m_entities.ForEach(delegate(EntityBase entity) { tmp.Add(entity); }); |
228 | { | 96 | return tmp.ToArray(); |
229 | return new List<EntityBase>(m_eb_uuid.Values); | 97 | } |
230 | } | 98 | |
231 | finally | 99 | public void ForEach(Action<EntityBase> action) |
232 | { | 100 | { |
233 | m_lock.ExitReadLock(); | 101 | m_entities.ForEach(action); |
234 | } | 102 | } |
103 | |||
104 | public EntityBase Find(Predicate<EntityBase> predicate) | ||
105 | { | ||
106 | return m_entities.FindValue(predicate); | ||
235 | } | 107 | } |
236 | 108 | ||
237 | public EntityBase this[UUID id] | 109 | public EntityBase this[UUID id] |
238 | { | 110 | { |
239 | get | 111 | get |
240 | { | 112 | { |
241 | m_lock.EnterReadLock(); | 113 | EntityBase entity; |
242 | try | 114 | m_entities.TryGetValue(id, out entity); |
243 | { | 115 | return entity; |
244 | EntityBase entity; | ||
245 | if (m_eb_uuid.TryGetValue(id, out entity)) | ||
246 | return entity; | ||
247 | else | ||
248 | return null; | ||
249 | } | ||
250 | finally | ||
251 | { | ||
252 | m_lock.ExitReadLock(); | ||
253 | } | ||
254 | } | 116 | } |
255 | set | 117 | set |
256 | { | 118 | { |
257 | InsertOrReplace(value); | 119 | Add(value); |
258 | } | 120 | } |
259 | } | 121 | } |
260 | 122 | ||
@@ -262,65 +124,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
262 | { | 124 | { |
263 | get | 125 | get |
264 | { | 126 | { |
265 | m_lock.EnterReadLock(); | 127 | EntityBase entity; |
266 | try | 128 | m_entities.TryGetValue(localID, out entity); |
267 | { | 129 | return entity; |
268 | EntityBase entity; | ||
269 | if (m_eb_localID.TryGetValue(localID, out entity)) | ||
270 | return entity; | ||
271 | else | ||
272 | return null; | ||
273 | } | ||
274 | finally | ||
275 | { | ||
276 | m_lock.ExitReadLock(); | ||
277 | } | ||
278 | } | 130 | } |
279 | set | 131 | set |
280 | { | 132 | { |
281 | InsertOrReplace(value); | 133 | Add(value); |
282 | } | 134 | } |
283 | } | 135 | } |
284 | 136 | ||
285 | public bool TryGetValue(UUID key, out EntityBase obj) | 137 | public bool TryGetValue(UUID key, out EntityBase obj) |
286 | { | 138 | { |
287 | m_lock.EnterReadLock(); | 139 | return m_entities.TryGetValue(key, out obj); |
288 | try | ||
289 | { | ||
290 | return m_eb_uuid.TryGetValue(key, out obj); | ||
291 | } | ||
292 | finally | ||
293 | { | ||
294 | m_lock.ExitReadLock(); | ||
295 | } | ||
296 | } | 140 | } |
297 | 141 | ||
298 | public bool TryGetValue(uint key, out EntityBase obj) | 142 | public bool TryGetValue(uint key, out EntityBase obj) |
299 | { | 143 | { |
300 | m_lock.EnterReadLock(); | 144 | return m_entities.TryGetValue(key, out obj); |
301 | try | ||
302 | { | ||
303 | return m_eb_localID.TryGetValue(key, out obj); | ||
304 | } | ||
305 | finally | ||
306 | { | ||
307 | m_lock.ExitReadLock(); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | /// <summary> | ||
312 | /// This could be optimised to work on the list 'live' rather than making a safe copy and iterating that. | ||
313 | /// </summary> | ||
314 | /// <returns></returns> | ||
315 | public IEnumerator<EntityBase> GetEnumerator() | ||
316 | { | ||
317 | return GetEntities().GetEnumerator(); | ||
318 | } | ||
319 | |||
320 | IEnumerator IEnumerable.GetEnumerator() | ||
321 | { | ||
322 | return GetEnumerator(); | ||
323 | } | 145 | } |
324 | |||
325 | } | 146 | } |
326 | } | 147 | } |