aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/EntityManager.cs
diff options
context:
space:
mode:
authorJohn Hurliman2010-09-10 12:04:12 -0700
committerJohn Hurliman2010-09-10 12:04:12 -0700
commitdd277a0d02f1aa79f4fcb5d108cbc696e90500c2 (patch)
tree7e396d347e43504ec23c59c3749f995f15c2e254 /OpenSim/Region/Framework/Scenes/EntityManager.cs
parent* Run SimianGrid session updates asynchronously instead of from the main hear... (diff)
downloadopensim-SC_OLD-dd277a0d02f1aa79f4fcb5d108cbc696e90500c2.zip
opensim-SC_OLD-dd277a0d02f1aa79f4fcb5d108cbc696e90500c2.tar.gz
opensim-SC_OLD-dd277a0d02f1aa79f4fcb5d108cbc696e90500c2.tar.bz2
opensim-SC_OLD-dd277a0d02f1aa79f4fcb5d108cbc696e90500c2.tar.xz
First pass at cleaning up thread safety in EntityManager and SceneGraph
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/EntityManager.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityManager.cs210
1 files changed, 50 insertions, 160 deletions
diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs
index 099fcce..85d0a4f 100644
--- a/OpenSim/Region/Framework/Scenes/EntityManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs
@@ -34,187 +34,89 @@ using OpenMetaverse;
34 34
35namespace OpenSim.Region.Framework.Scenes 35namespace OpenSim.Region.Framework.Scenes
36{ 36{
37 public class EntityManager : IEnumerable<EntityBase> 37 public class EntityManager //: IEnumerable<EntityBase>
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 readonly Object m_lock = new Object();
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 lock (m_lock) 49 m_entities.Add(entity.UUID, entity.LocalId, entity);
54 {
55 try
56 {
57 m_eb_uuid.Add(entity.UUID, entity);
58 m_eb_localID.Add(entity.LocalId, entity);
59 }
60 catch(Exception e)
61 {
62 m_log.ErrorFormat("Add Entity failed: {0}", e.Message);
63 }
64 }
65 }
66
67 public void InsertOrReplace(EntityBase entity)
68 {
69 lock (m_lock)
70 {
71 try
72 {
73 m_eb_uuid[entity.UUID] = entity;
74 m_eb_localID[entity.LocalId] = entity;
75 }
76 catch(Exception e)
77 {
78 m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message);
79 }
80 }
81 } 50 }
82 51
83 public void Clear() 52 public void Clear()
84 { 53 {
85 lock (m_lock) 54 m_entities.Clear();
86 {
87 m_eb_uuid.Clear();
88 m_eb_localID.Clear();
89 }
90 }
91
92 public int Count
93 {
94 get
95 {
96 return m_eb_uuid.Count;
97 }
98 } 55 }
99 56
100 public bool ContainsKey(UUID id) 57 public bool ContainsKey(UUID id)
101 { 58 {
102 try 59 return m_entities.ContainsKey(id);
103 {
104 return m_eb_uuid.ContainsKey(id);
105 }
106 catch
107 {
108 return false;
109 }
110 } 60 }
111 61
112 public bool ContainsKey(uint localID) 62 public bool ContainsKey(uint localID)
113 { 63 {
114 try 64 return m_entities.ContainsKey(localID);
115 {
116 return m_eb_localID.ContainsKey(localID);
117 }
118 catch
119 {
120 return false;
121 }
122 } 65 }
123 66
124 public bool Remove(uint localID) 67 public bool Remove(uint localID)
125 { 68 {
126 lock (m_lock) 69 return m_entities.Remove(localID);
127 {
128 try
129 {
130 bool a = false;
131 EntityBase entity;
132 if (m_eb_localID.TryGetValue(localID, out entity))
133 a = m_eb_uuid.Remove(entity.UUID);
134
135 bool b = m_eb_localID.Remove(localID);
136 return a && b;
137 }
138 catch (Exception e)
139 {
140 m_log.ErrorFormat("Remove Entity failed for {0}", localID, e);
141 return false;
142 }
143 }
144 } 70 }
145 71
146 public bool Remove(UUID id) 72 public bool Remove(UUID id)
147 { 73 {
148 lock (m_lock) 74 return m_entities.Remove(id);
149 {
150 try
151 {
152 bool a = false;
153 EntityBase entity;
154 if (m_eb_uuid.TryGetValue(id, out entity))
155 a = m_eb_localID.Remove(entity.LocalId);
156
157 bool b = m_eb_uuid.Remove(id);
158 return a && b;
159 }
160 catch (Exception e)
161 {
162 m_log.ErrorFormat("Remove Entity failed for {0}", id, e);
163 return false;
164 }
165 }
166 } 75 }
167 76
168 public List<EntityBase> GetAllByType<T>() 77 public EntityBase[] GetAllByType<T>()
169 { 78 {
170 List<EntityBase> tmp = new List<EntityBase>(); 79 List<EntityBase> tmp = new List<EntityBase>();
171 80
172 lock (m_lock) 81 m_entities.ForEach(
173 { 82 delegate(EntityBase entity)
174 try
175 { 83 {
176 foreach (KeyValuePair<UUID, EntityBase> pair in m_eb_uuid) 84 if (entity is T)
177 { 85 tmp.Add(entity);
178 if (pair.Value is T)
179 {
180 tmp.Add(pair.Value);
181 }
182 }
183 } 86 }
184 catch (Exception e) 87 );
185 {
186 m_log.ErrorFormat("GetAllByType failed for {0}", e);
187 tmp = null;
188 }
189 }
190 88
191 return tmp; 89 return tmp.ToArray();
192 } 90 }
193 91
194 public List<EntityBase> GetEntities() 92 public EntityBase[] GetEntities()
195 { 93 {
196 lock (m_lock) 94 List<EntityBase> tmp = new List<EntityBase>(m_entities.Count);
197 { 95 m_entities.ForEach(delegate(EntityBase entity) { tmp.Add(entity); });
198 return new List<EntityBase>(m_eb_uuid.Values); 96 return tmp.ToArray();
199 } 97 }
98
99 public void ForEach(Action<EntityBase> action)
100 {
101 m_entities.ForEach(action);
102 }
103
104 public EntityBase Find(Predicate<EntityBase> predicate)
105 {
106 return m_entities.FindValue(predicate);
200 } 107 }
201 108
202 public EntityBase this[UUID id] 109 public EntityBase this[UUID id]
203 { 110 {
204 get 111 get
205 { 112 {
206 lock (m_lock) 113 EntityBase entity;
207 { 114 m_entities.TryGetValue(id, out entity);
208 EntityBase entity; 115 return entity;
209 if (m_eb_uuid.TryGetValue(id, out entity))
210 return entity;
211 else
212 return null;
213 }
214 } 116 }
215 set 117 set
216 { 118 {
217 InsertOrReplace(value); 119 Add(value);
218 } 120 }
219 } 121 }
220 122
@@ -222,50 +124,38 @@ namespace OpenSim.Region.Framework.Scenes
222 { 124 {
223 get 125 get
224 { 126 {
225 lock (m_lock) 127 EntityBase entity;
226 { 128 m_entities.TryGetValue(localID, out entity);
227 EntityBase entity; 129 return entity;
228 if (m_eb_localID.TryGetValue(localID, out entity))
229 return entity;
230 else
231 return null;
232 }
233 } 130 }
234 set 131 set
235 { 132 {
236 InsertOrReplace(value); 133 Add(value);
237 } 134 }
238 } 135 }
239 136
240 public bool TryGetValue(UUID key, out EntityBase obj) 137 public bool TryGetValue(UUID key, out EntityBase obj)
241 { 138 {
242 lock (m_lock) 139 return m_entities.TryGetValue(key, out obj);
243 {
244 return m_eb_uuid.TryGetValue(key, out obj);
245 }
246 } 140 }
247 141
248 public bool TryGetValue(uint key, out EntityBase obj) 142 public bool TryGetValue(uint key, out EntityBase obj)
249 { 143 {
250 lock (m_lock) 144 return m_entities.TryGetValue(key, out obj);
251 {
252 return m_eb_localID.TryGetValue(key, out obj);
253 }
254 } 145 }
255 146
256 /// <summary> 147 /// <summary>
257 /// This could be optimised to work on the list 'live' rather than making a safe copy and iterating that. 148 /// This could be optimised to work on the list 'live' rather than making a safe copy and iterating that.
258 /// </summary> 149 /// </summary>
259 /// <returns></returns> 150 /// <returns></returns>
260 public IEnumerator<EntityBase> GetEnumerator() 151 //public IEnumerator<EntityBase> GetEnumerator()
261 { 152 //{
262 return GetEntities().GetEnumerator(); 153 // return GetEntities().GetEnumerator();
263 } 154 //}
264 155
265 IEnumerator IEnumerable.GetEnumerator() 156 //IEnumerator IEnumerable.GetEnumerator()
266 { 157 //{
267 return GetEnumerator(); 158 // return GetEnumerator();
268 } 159 //}
269
270 } 160 }
271} 161}