aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
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
parent* Run SimianGrid session updates asynchronously instead of from the main hear... (diff)
downloadopensim-SC-dd277a0d02f1aa79f4fcb5d108cbc696e90500c2.zip
opensim-SC-dd277a0d02f1aa79f4fcb5d108cbc696e90500c2.tar.gz
opensim-SC-dd277a0d02f1aa79f4fcb5d108cbc696e90500c2.tar.bz2
opensim-SC-dd277a0d02f1aa79f4fcb5d108cbc696e90500c2.tar.xz
First pass at cleaning up thread safety in EntityManager and SceneGraph
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRegionSerialiserModule.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityManager.cs210
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs45
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs263
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs23
8 files changed, 221 insertions, 346 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionSerialiserModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionSerialiserModule.cs
index e7562a5..18758c8 100644
--- a/OpenSim/Region/Framework/Interfaces/IRegionSerialiserModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IRegionSerialiserModule.cs
@@ -90,7 +90,7 @@ namespace OpenSim.Region.Framework.Interfaces
90 /// </summary> 90 /// </summary>
91 /// <param name="entityList"></param> 91 /// <param name="entityList"></param>
92 /// <param name="fileName"></param> 92 /// <param name="fileName"></param>
93 void SavePrimListToXml2(List<EntityBase> entityList, string fileName); 93 void SavePrimListToXml2(EntityBase[] entityList, string fileName);
94 94
95 /// <summary> 95 /// <summary>
96 /// Save a set of prims in the xml2 format, optionally specifying a bounding box for which 96 /// Save a set of prims in the xml2 format, optionally specifying a bounding box for which
@@ -101,7 +101,7 @@ namespace OpenSim.Region.Framework.Interfaces
101 /// <param name="stream"></param> 101 /// <param name="stream"></param>
102 /// <param name="min"></param> 102 /// <param name="min"></param>
103 /// <param name="max"></param> 103 /// <param name="max"></param>
104 void SavePrimListToXml2(List<EntityBase> entityList, TextWriter stream, Vector3 min, Vector3 max); 104 void SavePrimListToXml2(EntityBase[] entityList, TextWriter stream, Vector3 min, Vector3 max);
105 105
106 void SaveNamedPrimsToXml2(Scene scene, string primName, string fileName); 106 void SaveNamedPrimsToXml2(Scene scene, string primName, string fileName);
107 107
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}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index c49386a..a439eb9 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -58,7 +58,8 @@ namespace OpenSim.Region.Framework.Scenes
58 { 58 {
59 m_log.Info("[PRIM INVENTORY]: Starting scripts in scene"); 59 m_log.Info("[PRIM INVENTORY]: Starting scripts in scene");
60 60
61 foreach (EntityBase group in Entities) 61 EntityBase[] entities = Entities.GetEntities();
62 foreach (EntityBase group in entities)
62 { 63 {
63 if (group is SceneObjectGroup) 64 if (group is SceneObjectGroup)
64 { 65 {
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index c511774..2f69476 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -116,9 +116,8 @@ namespace OpenSim.Region.Framework.Scenes
116 /// <param name="remoteClient"></param> 116 /// <param name="remoteClient"></param>
117 public void RequestPrim(uint primLocalID, IClientAPI remoteClient) 117 public void RequestPrim(uint primLocalID, IClientAPI remoteClient)
118 { 118 {
119 List<EntityBase> EntityList = GetEntities(); 119 EntityBase[] entityList = GetEntities();
120 120 foreach (EntityBase ent in entityList)
121 foreach (EntityBase ent in EntityList)
122 { 121 {
123 if (ent is SceneObjectGroup) 122 if (ent is SceneObjectGroup)
124 { 123 {
@@ -138,9 +137,8 @@ namespace OpenSim.Region.Framework.Scenes
138 /// <param name="remoteClient"></param> 137 /// <param name="remoteClient"></param>
139 public void SelectPrim(uint primLocalID, IClientAPI remoteClient) 138 public void SelectPrim(uint primLocalID, IClientAPI remoteClient)
140 { 139 {
141 List<EntityBase> EntityList = GetEntities(); 140 EntityBase[] entityList = GetEntities();
142 141 foreach (EntityBase ent in entityList)
143 foreach (EntityBase ent in EntityList)
144 { 142 {
145 if (ent is SceneObjectGroup) 143 if (ent is SceneObjectGroup)
146 { 144 {
@@ -259,7 +257,7 @@ namespace OpenSim.Region.Framework.Scenes
259 257
260 public virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) 258 public virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
261 { 259 {
262 List<EntityBase> EntityList = GetEntities(); 260 EntityBase[] EntityList = GetEntities();
263 261
264 SurfaceTouchEventArgs surfaceArg = null; 262 SurfaceTouchEventArgs surfaceArg = null;
265 if (surfaceArgs != null && surfaceArgs.Count > 0) 263 if (surfaceArgs != null && surfaceArgs.Count > 0)
@@ -303,7 +301,7 @@ namespace OpenSim.Region.Framework.Scenes
303 301
304 public virtual void ProcessObjectGrabUpdate(UUID objectID, Vector3 offset, Vector3 pos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) 302 public virtual void ProcessObjectGrabUpdate(UUID objectID, Vector3 offset, Vector3 pos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
305 { 303 {
306 List<EntityBase> EntityList = GetEntities(); 304 EntityBase[] EntityList = GetEntities();
307 305
308 SurfaceTouchEventArgs surfaceArg = null; 306 SurfaceTouchEventArgs surfaceArg = null;
309 if (surfaceArgs != null && surfaceArgs.Count > 0) 307 if (surfaceArgs != null && surfaceArgs.Count > 0)
@@ -343,7 +341,7 @@ namespace OpenSim.Region.Framework.Scenes
343 341
344 public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) 342 public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
345 { 343 {
346 List<EntityBase> EntityList = GetEntities(); 344 EntityBase[] EntityList = GetEntities();
347 345
348 SurfaceTouchEventArgs surfaceArg = null; 346 SurfaceTouchEventArgs surfaceArg = null;
349 if (surfaceArgs != null && surfaceArgs.Count > 0) 347 if (surfaceArgs != null && surfaceArgs.Count > 0)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 82e7d76..7ce95a7 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1029,29 +1029,30 @@ namespace OpenSim.Region.Framework.Scenes
1029 if (ScriptEngine) 1029 if (ScriptEngine)
1030 { 1030 {
1031 m_log.Info("Stopping all Scripts in Scene"); 1031 m_log.Info("Stopping all Scripts in Scene");
1032 foreach (EntityBase ent in Entities) 1032
1033 EntityBase[] entities = Entities.GetEntities();
1034 foreach (EntityBase ent in entities)
1033 { 1035 {
1034 if (ent is SceneObjectGroup) 1036 if (ent is SceneObjectGroup)
1035 { 1037 ((SceneObjectGroup)ent).RemoveScriptInstances(false);
1036 ((SceneObjectGroup) ent).RemoveScriptInstances(false);
1037 }
1038 } 1038 }
1039 } 1039 }
1040 else 1040 else
1041 { 1041 {
1042 m_log.Info("Starting all Scripts in Scene"); 1042 m_log.Info("Starting all Scripts in Scene");
1043 lock (Entities) 1043
1044 EntityBase[] entities = Entities.GetEntities();
1045 foreach (EntityBase ent in entities)
1044 { 1046 {
1045 foreach (EntityBase ent in Entities) 1047 if (ent is SceneObjectGroup)
1046 { 1048 {
1047 if (ent is SceneObjectGroup) 1049 SceneObjectGroup sog = (SceneObjectGroup)ent;
1048 { 1050 sog.CreateScriptInstances(0, false, DefaultScriptEngine, 0);
1049 ((SceneObjectGroup)ent).CreateScriptInstances(0, false, DefaultScriptEngine, 0); 1051 sog.ResumeScripts();
1050 ((SceneObjectGroup)ent).ResumeScripts();
1051 }
1052 } 1052 }
1053 } 1053 }
1054 } 1054 }
1055
1055 m_scripts_enabled = !ScriptEngine; 1056 m_scripts_enabled = !ScriptEngine;
1056 m_log.Info("[TOTEDD]: Here is the method to trigger disabling of the scripting engine"); 1057 m_log.Info("[TOTEDD]: Here is the method to trigger disabling of the scripting engine");
1057 } 1058 }
@@ -1098,7 +1099,7 @@ namespace OpenSim.Region.Framework.Scenes
1098 shuttingdown = true; 1099 shuttingdown = true;
1099 1100
1100 m_log.Debug("[SCENE]: Persisting changed objects"); 1101 m_log.Debug("[SCENE]: Persisting changed objects");
1101 List<EntityBase> entities = GetEntities(); 1102 EntityBase[] entities = GetEntities();
1102 foreach (EntityBase entity in entities) 1103 foreach (EntityBase entity in entities)
1103 { 1104 {
1104 if (!entity.IsDeleted && entity is SceneObjectGroup && ((SceneObjectGroup)entity).HasGroupChanged) 1105 if (!entity.IsDeleted && entity is SceneObjectGroup && ((SceneObjectGroup)entity).HasGroupChanged)
@@ -2037,8 +2038,7 @@ namespace OpenSim.Region.Framework.Scenes
2037 { 2038 {
2038 lock (Entities) 2039 lock (Entities)
2039 { 2040 {
2040 ICollection<EntityBase> entities = new List<EntityBase>(Entities); 2041 EntityBase[] entities = Entities.GetEntities();
2041
2042 foreach (EntityBase e in entities) 2042 foreach (EntityBase e in entities)
2043 { 2043 {
2044 if (e is SceneObjectGroup) 2044 if (e is SceneObjectGroup)
@@ -3977,9 +3977,8 @@ namespace OpenSim.Region.Framework.Scenes
3977 /// </summary> 3977 /// </summary>
3978 public void ForceClientUpdate() 3978 public void ForceClientUpdate()
3979 { 3979 {
3980 List<EntityBase> EntityList = GetEntities(); 3980 EntityBase[] entityList = GetEntities();
3981 3981 foreach (EntityBase ent in entityList)
3982 foreach (EntityBase ent in EntityList)
3983 { 3982 {
3984 if (ent is SceneObjectGroup) 3983 if (ent is SceneObjectGroup)
3985 { 3984 {
@@ -3997,9 +3996,8 @@ namespace OpenSim.Region.Framework.Scenes
3997 { 3996 {
3998 m_log.Debug("Searching for Primitive: '" + cmdparams[2] + "'"); 3997 m_log.Debug("Searching for Primitive: '" + cmdparams[2] + "'");
3999 3998
4000 List<EntityBase> EntityList = GetEntities(); 3999 EntityBase[] entityList = GetEntities();
4001 4000 foreach (EntityBase ent in entityList)
4002 foreach (EntityBase ent in EntityList)
4003 { 4001 {
4004 if (ent is SceneObjectGroup) 4002 if (ent is SceneObjectGroup)
4005 { 4003 {
@@ -4368,7 +4366,7 @@ namespace OpenSim.Region.Framework.Scenes
4368 /// will not affect the original list of objects in the scene. 4366 /// will not affect the original list of objects in the scene.
4369 /// </summary> 4367 /// </summary>
4370 /// <returns></returns> 4368 /// <returns></returns>
4371 public List<EntityBase> GetEntities() 4369 public EntityBase[] GetEntities()
4372 { 4370 {
4373 return m_sceneGraph.GetEntities(); 4371 return m_sceneGraph.GetEntities();
4374 } 4372 }
@@ -4402,9 +4400,8 @@ namespace OpenSim.Region.Framework.Scenes
4402 4400
4403 public void CleanTempObjects() 4401 public void CleanTempObjects()
4404 { 4402 {
4405 List<EntityBase> objs = GetEntities(); 4403 EntityBase[] entities = GetEntities();
4406 4404 foreach (EntityBase obj in entities)
4407 foreach (EntityBase obj in objs)
4408 { 4405 {
4409 if (obj is SceneObjectGroup) 4406 if (obj is SceneObjectGroup)
4410 { 4407 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index dfb26b9..3d3e822 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -348,68 +348,57 @@ namespace OpenSim.Region.Framework.Scenes
348 if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) 348 if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero)
349 return false; 349 return false;
350 350
351 lock (sceneObject) 351 if (Entities.ContainsKey(sceneObject.UUID))
352 { 352 return false;
353 if (Entities.ContainsKey(sceneObject.UUID)) 353
354 { 354 // Clamp child prim sizes and add child prims to the m_numPrim count
355// m_log.WarnFormat( 355 lock (sceneObject.Children)
356// "[SCENE GRAPH]: Scene object {0} {1} was already in region {2} on add request", 356 {
357// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); 357 if (m_parentScene.m_clampPrimSize)
358 return false;
359 }
360
361// m_log.DebugFormat(
362// "[SCENE GRAPH]: Adding object {0} {1} to region {2}",
363// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
364
365 lock (sceneObject.Children)
366 { 358 {
367 if (m_parentScene.m_clampPrimSize) 359 foreach (SceneObjectPart part in sceneObject.Children.Values)
368 { 360 {
369 foreach (SceneObjectPart part in sceneObject.Children.Values) 361 Vector3 scale = part.Shape.Scale;
370 { 362
371 Vector3 scale = part.Shape.Scale; 363 if (scale.X > m_parentScene.m_maxNonphys)
372 364 scale.X = m_parentScene.m_maxNonphys;
373 if (scale.X > m_parentScene.m_maxNonphys) 365 if (scale.Y > m_parentScene.m_maxNonphys)
374 scale.X = m_parentScene.m_maxNonphys; 366 scale.Y = m_parentScene.m_maxNonphys;
375 if (scale.Y > m_parentScene.m_maxNonphys) 367 if (scale.Z > m_parentScene.m_maxNonphys)
376 scale.Y = m_parentScene.m_maxNonphys; 368 scale.Z = m_parentScene.m_maxNonphys;
377 if (scale.Z > m_parentScene.m_maxNonphys) 369
378 scale.Z = m_parentScene.m_maxNonphys; 370 part.Shape.Scale = scale;
379
380 part.Shape.Scale = scale;
381 }
382 } 371 }
383
384 m_numPrim += sceneObject.Children.Count;
385 } 372 }
386
387 sceneObject.AttachToScene(m_parentScene);
388 373
389 if (sendClientUpdates) 374 m_numPrim += sceneObject.Children.Count;
390 sceneObject.ScheduleGroupForFullUpdate(); 375 }
391
392 Entities.Add(sceneObject);
393 376
394 if (attachToBackup) 377 sceneObject.AttachToScene(m_parentScene);
395 sceneObject.AttachToBackup();
396 378
397 if (OnObjectCreate != null) 379 if (sendClientUpdates)
398 OnObjectCreate(sceneObject); 380 sceneObject.ScheduleGroupForFullUpdate();
399 381
400 lock (SceneObjectGroupsByFullID) 382 Entities.Add(sceneObject);
401 { 383
402 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; 384 if (attachToBackup)
403 foreach (SceneObjectPart part in sceneObject.Children.Values) 385 sceneObject.AttachToBackup();
404 SceneObjectGroupsByFullID[part.UUID] = sceneObject; 386
405 } 387 if (OnObjectCreate != null)
406 388 OnObjectCreate(sceneObject);
407 lock (SceneObjectGroupsByLocalID) 389
408 { 390 lock (SceneObjectGroupsByFullID)
409 SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; 391 {
410 foreach (SceneObjectPart part in sceneObject.Children.Values) 392 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
411 SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; 393 foreach (SceneObjectPart part in sceneObject.Children.Values)
412 } 394 SceneObjectGroupsByFullID[part.UUID] = sceneObject;
395 }
396
397 lock (SceneObjectGroupsByLocalID)
398 {
399 SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
400 foreach (SceneObjectPart part in sceneObject.Children.Values)
401 SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
413 } 402 }
414 403
415 return true; 404 return true;
@@ -421,42 +410,38 @@ namespace OpenSim.Region.Framework.Scenes
421 /// <returns>true if the object was deleted, false if there was no object to delete</returns> 410 /// <returns>true if the object was deleted, false if there was no object to delete</returns>
422 public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked) 411 public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked)
423 { 412 {
424 if (Entities.ContainsKey(uuid)) 413 EntityBase entity;
425 { 414 if (!Entities.TryGetValue(uuid, out entity) && entity is SceneObjectGroup)
426 SceneObjectGroup grp = (SceneObjectGroup)Entities[uuid]; 415 return false;
427 416
428 if (!resultOfObjectLinked) 417 SceneObjectGroup grp = (SceneObjectGroup)entity;
429 {
430 m_numPrim -= grp.PrimCount;
431 418
432 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) 419 if (!resultOfObjectLinked)
433 RemovePhysicalPrim(grp.PrimCount); 420 {
434 } 421 m_numPrim -= grp.PrimCount;
435 422
436 if (OnObjectRemove != null) 423 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
437 OnObjectRemove(Entities[uuid]); 424 RemovePhysicalPrim(grp.PrimCount);
425 }
438 426
439 lock (SceneObjectGroupsByFullID) 427 if (OnObjectRemove != null)
440 { 428 OnObjectRemove(Entities[uuid]);
441 foreach (SceneObjectPart part in grp.Children.Values)
442 SceneObjectGroupsByFullID.Remove(part.UUID);
443 SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID);
444 }
445 lock (SceneObjectGroupsByLocalID)
446 {
447 foreach (SceneObjectPart part in grp.Children.Values)
448 SceneObjectGroupsByLocalID.Remove(part.LocalId);
449 SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId);
450 }
451 429
452 Entities.Remove(uuid); 430 lock (SceneObjectGroupsByFullID)
453 //SceneObjectGroup part; 431 {
454 //((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) 432 foreach (SceneObjectPart part in grp.Children.Values)
433 SceneObjectGroupsByFullID.Remove(part.UUID);
434 SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID);
435 }
455 436
456 return true; 437 lock (SceneObjectGroupsByLocalID)
438 {
439 foreach (SceneObjectPart part in grp.Children.Values)
440 SceneObjectGroupsByLocalID.Remove(part.LocalId);
441 SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId);
457 } 442 }
458 443
459 return false; 444 return Entities.Remove(uuid);
460 } 445 }
461 446
462 /// <summary> 447 /// <summary>
@@ -468,9 +453,7 @@ namespace OpenSim.Region.Framework.Scenes
468 protected internal void AddToUpdateList(SceneObjectGroup obj) 453 protected internal void AddToUpdateList(SceneObjectGroup obj)
469 { 454 {
470 lock (m_updateList) 455 lock (m_updateList)
471 {
472 m_updateList[obj.UUID] = obj; 456 m_updateList[obj.UUID] = obj;
473 }
474 } 457 }
475 458
476 /// <summary> 459 /// <summary>
@@ -480,34 +463,39 @@ namespace OpenSim.Region.Framework.Scenes
480 { 463 {
481 if (!Monitor.TryEnter(m_updateLock)) 464 if (!Monitor.TryEnter(m_updateLock))
482 return; 465 return;
483 466 try
484 List<SceneObjectGroup> updates;
485
486 // Some updates add more updates to the updateList.
487 // Get the current list of updates and clear the list before iterating
488 lock (m_updateList)
489 {
490 updates = new List<SceneObjectGroup>(m_updateList.Values);
491 m_updateList.Clear();
492 }
493
494 // Go through all updates
495 for (int i = 0; i < updates.Count; i++)
496 { 467 {
497 SceneObjectGroup sog = updates[i]; 468 List<SceneObjectGroup> updates;
498 469
499 // Don't abort the whole update if one entity happens to give us an exception. 470 // Some updates add more updates to the updateList.
500 try 471 // Get the current list of updates and clear the list before iterating
472 lock (m_updateList)
501 { 473 {
502 sog.Update(); 474 updates = new List<SceneObjectGroup>(m_updateList.Values);
475 m_updateList.Clear();
503 } 476 }
504 catch (Exception e) 477
478 // Go through all updates
479 for (int i = 0; i < updates.Count; i++)
505 { 480 {
506 m_log.ErrorFormat( 481 SceneObjectGroup sog = updates[i];
507 "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e); 482
483 // Don't abort the whole update if one entity happens to give us an exception.
484 try
485 {
486 sog.Update();
487 }
488 catch (Exception e)
489 {
490 m_log.ErrorFormat(
491 "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e);
492 }
508 } 493 }
509 } 494 }
510 Monitor.Exit(m_updateLock); 495 finally
496 {
497 Monitor.Exit(m_updateLock);
498 }
511 } 499 }
512 500
513 protected internal void AddPhysicalPrim(int number) 501 protected internal void AddPhysicalPrim(int number)
@@ -864,8 +852,9 @@ namespace OpenSim.Region.Framework.Scenes
864 /// <returns>null if no scene object group containing that prim is found</returns> 852 /// <returns>null if no scene object group containing that prim is found</returns>
865 public SceneObjectGroup GetGroupByPrim(uint localID) 853 public SceneObjectGroup GetGroupByPrim(uint localID)
866 { 854 {
867 if (Entities.ContainsKey(localID)) 855 EntityBase entity;
868 return Entities[localID] as SceneObjectGroup; 856 if (Entities.TryGetValue(localID, out entity))
857 return entity as SceneObjectGroup;
869 858
870 //m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID); 859 //m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID);
871 SceneObjectGroup sog; 860 SceneObjectGroup sog;
@@ -879,23 +868,22 @@ namespace OpenSim.Region.Framework.Scenes
879 } 868 }
880 } 869 }
881 870
882 List<EntityBase> EntityList = GetEntities(); 871 EntityBase[] entityList = GetEntities();
883 foreach (EntityBase ent in EntityList) 872 foreach (EntityBase ent in entityList)
884 { 873 {
885 //m_log.DebugFormat("Looking at entity {0}", ent.UUID); 874 //m_log.DebugFormat("Looking at entity {0}", ent.UUID);
886 if (ent is SceneObjectGroup) 875 if (ent is SceneObjectGroup)
887 { 876 {
888 if (((SceneObjectGroup)ent).HasChildPrim(localID)) 877 sog = (SceneObjectGroup)ent;
878 if (sog.HasChildPrim(localID))
889 { 879 {
890 sog = (SceneObjectGroup)ent;
891 lock (SceneObjectGroupsByLocalID) 880 lock (SceneObjectGroupsByLocalID)
892 {
893 SceneObjectGroupsByLocalID[localID] = sog; 881 SceneObjectGroupsByLocalID[localID] = sog;
894 }
895 return sog; 882 return sog;
896 } 883 }
897 } 884 }
898 } 885 }
886
899 return null; 887 return null;
900 } 888 }
901 889
@@ -921,23 +909,21 @@ namespace OpenSim.Region.Framework.Scenes
921 } 909 }
922 } 910 }
923 911
924 List<EntityBase> EntityList = GetEntities(); 912 EntityBase[] entityList = GetEntities();
925 913 foreach (EntityBase ent in entityList)
926 foreach (EntityBase ent in EntityList)
927 { 914 {
928 if (ent is SceneObjectGroup) 915 if (ent is SceneObjectGroup)
929 { 916 {
930 if (((SceneObjectGroup)ent).HasChildPrim(fullID)) 917 sog = (SceneObjectGroup)ent;
918 if (sog.HasChildPrim(fullID))
931 { 919 {
932 sog = (SceneObjectGroup)ent;
933 lock (SceneObjectGroupsByFullID) 920 lock (SceneObjectGroupsByFullID)
934 {
935 SceneObjectGroupsByFullID[fullID] = sog; 921 SceneObjectGroupsByFullID[fullID] = sog;
936 }
937 return sog; 922 return sog;
938 } 923 }
939 } 924 }
940 } 925 }
926
941 return null; 927 return null;
942 } 928 }
943 929
@@ -946,7 +932,7 @@ namespace OpenSim.Region.Framework.Scenes
946 // Primitive Ray Tracing 932 // Primitive Ray Tracing
947 float closestDistance = 280f; 933 float closestDistance = 280f;
948 EntityIntersection result = new EntityIntersection(); 934 EntityIntersection result = new EntityIntersection();
949 List<EntityBase> EntityList = GetEntities(); 935 EntityBase[] EntityList = GetEntities();
950 foreach (EntityBase ent in EntityList) 936 foreach (EntityBase ent in EntityList)
951 { 937 {
952 if (ent is SceneObjectGroup) 938 if (ent is SceneObjectGroup)
@@ -984,23 +970,28 @@ namespace OpenSim.Region.Framework.Scenes
984 /// <returns>null if the part was not found</returns> 970 /// <returns>null if the part was not found</returns>
985 protected internal SceneObjectPart GetSceneObjectPart(string name) 971 protected internal SceneObjectPart GetSceneObjectPart(string name)
986 { 972 {
987 List<EntityBase> EntityList = GetEntities(); 973 SceneObjectPart sop = null;
988 974
989 // FIXME: use a dictionary here 975 Entities.Find(
990 foreach (EntityBase ent in EntityList) 976 delegate(EntityBase entity)
991 {
992 if (ent is SceneObjectGroup)
993 { 977 {
994 foreach (SceneObjectPart p in ((SceneObjectGroup) ent).GetParts()) 978 if (entity is SceneObjectGroup)
995 { 979 {
996 if (p.Name == name) 980 foreach (SceneObjectPart p in ((SceneObjectGroup)entity).GetParts())
997 { 981 {
998 return p; 982 if (p.Name == name)
983 {
984 sop = p;
985 return true;
986 }
999 } 987 }
1000 } 988 }
989
990 return false;
1001 } 991 }
1002 } 992 );
1003 return null; 993
994 return sop;
1004 } 995 }
1005 996
1006 /// <summary> 997 /// <summary>
@@ -1021,7 +1012,7 @@ namespace OpenSim.Region.Framework.Scenes
1021 /// it 1012 /// it
1022 /// </summary> 1013 /// </summary>
1023 /// <returns></returns> 1014 /// <returns></returns>
1024 protected internal List<EntityBase> GetEntities() 1015 protected internal EntityBase[] GetEntities()
1025 { 1016 {
1026 return Entities.GetEntities(); 1017 return Entities.GetEntities();
1027 } 1018 }
@@ -1030,7 +1021,7 @@ namespace OpenSim.Region.Framework.Scenes
1030 { 1021 {
1031 Dictionary<uint, float> topScripts = new Dictionary<uint, float>(); 1022 Dictionary<uint, float> topScripts = new Dictionary<uint, float>();
1032 1023
1033 List<EntityBase> EntityList = GetEntities(); 1024 EntityBase[] EntityList = GetEntities();
1034 int limit = 0; 1025 int limit = 0;
1035 foreach (EntityBase ent in EntityList) 1026 foreach (EntityBase ent in EntityList)
1036 { 1027 {
@@ -1726,8 +1717,8 @@ namespace OpenSim.Region.Framework.Scenes
1726 UUID objid = UUID.Zero; 1717 UUID objid = UUID.Zero;
1727 SceneObjectPart obj = null; 1718 SceneObjectPart obj = null;
1728 1719
1729 List<EntityBase> EntityList = GetEntities(); 1720 EntityBase[] entityList = GetEntities();
1730 foreach (EntityBase ent in EntityList) 1721 foreach (EntityBase ent in entityList)
1731 { 1722 {
1732 if (ent is SceneObjectGroup) 1723 if (ent is SceneObjectGroup)
1733 { 1724 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index f478a4a..7aa5a93 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -75,7 +75,8 @@ namespace OpenSim.Region.Framework.Scenes
75 75
76 lock(m_pendingObjects) 76 lock(m_pendingObjects)
77 { 77 {
78 foreach (EntityBase e in m_presence.Scene.Entities) 78 EntityBase[] entities = m_presence.Scene.Entities.GetEntities();
79 foreach (EntityBase e in entities)
79 { 80 {
80 if (e != null && e is SceneObjectGroup) 81 if (e != null && e is SceneObjectGroup)
81 m_pendingObjects.Enqueue((SceneObjectGroup)e); 82 m_pendingObjects.Enqueue((SceneObjectGroup)e);
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs
index b6677f0..5494549 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs
@@ -84,9 +84,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
84 int primCount = 0; 84 int primCount = 0;
85 stream.WriteLine("<scene>\n"); 85 stream.WriteLine("<scene>\n");
86 86
87 List<EntityBase> EntityList = scene.GetEntities(); 87 EntityBase[] entityList = scene.GetEntities();
88 88 foreach (EntityBase ent in entityList)
89 foreach (EntityBase ent in EntityList)
90 { 89 {
91 if (ent is SceneObjectGroup) 90 if (ent is SceneObjectGroup)
92 { 91 {
@@ -204,16 +203,14 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
204 203
205 public static void SavePrimsToXml2(Scene scene, string fileName) 204 public static void SavePrimsToXml2(Scene scene, string fileName)
206 { 205 {
207 List<EntityBase> EntityList = scene.GetEntities(); 206 EntityBase[] entityList = scene.GetEntities();
208 207 SavePrimListToXml2(entityList, fileName);
209 SavePrimListToXml2(EntityList, fileName);
210 } 208 }
211 209
212 public static void SavePrimsToXml2(Scene scene, TextWriter stream, Vector3 min, Vector3 max) 210 public static void SavePrimsToXml2(Scene scene, TextWriter stream, Vector3 min, Vector3 max)
213 { 211 {
214 List<EntityBase> EntityList = scene.GetEntities(); 212 EntityBase[] entityList = scene.GetEntities();
215 213 SavePrimListToXml2(entityList, stream, min, max);
216 SavePrimListToXml2(EntityList, stream, min, max);
217 } 214 }
218 215
219 public static void SaveNamedPrimsToXml2(Scene scene, string primName, string fileName) 216 public static void SaveNamedPrimsToXml2(Scene scene, string primName, string fileName)
@@ -222,7 +219,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
222 "[SERIALISER]: Saving prims with name {0} in xml2 format for region {1} to {2}", 219 "[SERIALISER]: Saving prims with name {0} in xml2 format for region {1} to {2}",
223 primName, scene.RegionInfo.RegionName, fileName); 220 primName, scene.RegionInfo.RegionName, fileName);
224 221
225 List<EntityBase> entityList = scene.GetEntities(); 222 EntityBase[] entityList = scene.GetEntities();
226 List<EntityBase> primList = new List<EntityBase>(); 223 List<EntityBase> primList = new List<EntityBase>();
227 224
228 foreach (EntityBase ent in entityList) 225 foreach (EntityBase ent in entityList)
@@ -236,10 +233,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
236 } 233 }
237 } 234 }
238 235
239 SavePrimListToXml2(primList, fileName); 236 SavePrimListToXml2(primList.ToArray(), fileName);
240 } 237 }
241 238
242 public static void SavePrimListToXml2(List<EntityBase> entityList, string fileName) 239 public static void SavePrimListToXml2(EntityBase[] entityList, string fileName)
243 { 240 {
244 FileStream file = new FileStream(fileName, FileMode.Create); 241 FileStream file = new FileStream(fileName, FileMode.Create);
245 try 242 try
@@ -260,7 +257,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
260 } 257 }
261 } 258 }
262 259
263 public static void SavePrimListToXml2(List<EntityBase> entityList, TextWriter stream, Vector3 min, Vector3 max) 260 public static void SavePrimListToXml2(EntityBase[] entityList, TextWriter stream, Vector3 min, Vector3 max)
264 { 261 {
265 int primCount = 0; 262 int primCount = 0;
266 stream.WriteLine("<scene>\n"); 263 stream.WriteLine("<scene>\n");