diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs | 98 | ||||
-rw-r--r-- | OpenSim/Framework/MapAndArray.cs | 28 | ||||
-rwxr-xr-x | OpenSim/Region/Framework/Scenes/Scene.cs | 16 | ||||
-rwxr-xr-x | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 797 |
4 files changed, 471 insertions, 468 deletions
diff --git a/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs b/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs index 5b9a45c..73d0d20 100644 --- a/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs +++ b/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs | |||
@@ -42,8 +42,6 @@ namespace OpenSim.Framework | |||
42 | Dictionary<TKey1, TValue> Dictionary1; | 42 | Dictionary<TKey1, TValue> Dictionary1; |
43 | Dictionary<TKey2, TValue> Dictionary2; | 43 | Dictionary<TKey2, TValue> Dictionary2; |
44 | private TValue[] m_array; | 44 | private TValue[] m_array; |
45 | private int m_lastArrayVersion; | ||
46 | private int m_arrayVersion; | ||
47 | 45 | ||
48 | ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim(); | 46 | ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim(); |
49 | 47 | ||
@@ -51,22 +49,20 @@ namespace OpenSim.Framework | |||
51 | { | 49 | { |
52 | Dictionary1 = new Dictionary<TKey1,TValue>(); | 50 | Dictionary1 = new Dictionary<TKey1,TValue>(); |
53 | Dictionary2 = new Dictionary<TKey2,TValue>(); | 51 | Dictionary2 = new Dictionary<TKey2,TValue>(); |
54 | m_array = new TValue[0]; | 52 | m_array = null; |
55 | m_lastArrayVersion = 0; | ||
56 | m_arrayVersion = 0; | ||
57 | } | 53 | } |
58 | 54 | ||
59 | public DoubleDictionaryThreadAbortSafe(int capacity) | 55 | public DoubleDictionaryThreadAbortSafe(int capacity) |
60 | { | 56 | { |
61 | Dictionary1 = new Dictionary<TKey1, TValue>(capacity); | 57 | Dictionary1 = new Dictionary<TKey1, TValue>(capacity); |
62 | Dictionary2 = new Dictionary<TKey2, TValue>(capacity); | 58 | Dictionary2 = new Dictionary<TKey2, TValue>(capacity); |
63 | m_lastArrayVersion = 0; | 59 | m_array = null; |
64 | m_arrayVersion = 0; | ||
65 | } | 60 | } |
66 | 61 | ||
67 | ~DoubleDictionaryThreadAbortSafe() | 62 | ~DoubleDictionaryThreadAbortSafe() |
68 | { | 63 | { |
69 | rwLock.Dispose(); | 64 | if(rwLock != null) |
65 | rwLock.Dispose(); | ||
70 | } | 66 | } |
71 | 67 | ||
72 | public void Add(TKey1 key1, TKey2 key2, TValue value) | 68 | public void Add(TKey1 key1, TKey2 key2, TValue value) |
@@ -83,6 +79,8 @@ namespace OpenSim.Framework | |||
83 | { | 79 | { |
84 | rwLock.EnterWriteLock(); | 80 | rwLock.EnterWriteLock(); |
85 | gotLock = true; | 81 | gotLock = true; |
82 | } | ||
83 | /* | ||
86 | if (Dictionary1.ContainsKey(key1)) | 84 | if (Dictionary1.ContainsKey(key1)) |
87 | { | 85 | { |
88 | if (!Dictionary2.ContainsKey(key2)) | 86 | if (!Dictionary2.ContainsKey(key2)) |
@@ -93,10 +91,10 @@ namespace OpenSim.Framework | |||
93 | if (!Dictionary1.ContainsKey(key1)) | 91 | if (!Dictionary1.ContainsKey(key1)) |
94 | throw new ArgumentException("key2 exists in the dictionary but not key1"); | 92 | throw new ArgumentException("key2 exists in the dictionary but not key1"); |
95 | } | 93 | } |
94 | */ | ||
96 | Dictionary1[key1] = value; | 95 | Dictionary1[key1] = value; |
97 | Dictionary2[key2] = value; | 96 | Dictionary2[key2] = value; |
98 | ++m_arrayVersion; | 97 | m_array = null; |
99 | } | ||
100 | } | 98 | } |
101 | finally | 99 | finally |
102 | { | 100 | { |
@@ -120,10 +118,10 @@ namespace OpenSim.Framework | |||
120 | { | 118 | { |
121 | rwLock.EnterWriteLock(); | 119 | rwLock.EnterWriteLock(); |
122 | gotLock = true; | 120 | gotLock = true; |
123 | Dictionary1.Remove(key1); | ||
124 | success = Dictionary2.Remove(key2); | ||
125 | ++m_arrayVersion; | ||
126 | } | 121 | } |
122 | success = Dictionary1.Remove(key1); | ||
123 | success &= Dictionary2.Remove(key2); | ||
124 | m_array = null; | ||
127 | } | 125 | } |
128 | finally | 126 | finally |
129 | { | 127 | { |
@@ -164,7 +162,7 @@ namespace OpenSim.Framework | |||
164 | { | 162 | { |
165 | Dictionary1.Remove(key1); | 163 | Dictionary1.Remove(key1); |
166 | Dictionary2.Remove(kvp.Key); | 164 | Dictionary2.Remove(kvp.Key); |
167 | ++m_arrayVersion; | 165 | m_array = null; |
168 | } | 166 | } |
169 | found = true; | 167 | found = true; |
170 | break; | 168 | break; |
@@ -211,7 +209,7 @@ namespace OpenSim.Framework | |||
211 | { | 209 | { |
212 | Dictionary2.Remove(key2); | 210 | Dictionary2.Remove(key2); |
213 | Dictionary1.Remove(kvp.Key); | 211 | Dictionary1.Remove(kvp.Key); |
214 | ++m_arrayVersion; | 212 | m_array = null; |
215 | } | 213 | } |
216 | found = true; | 214 | found = true; |
217 | break; | 215 | break; |
@@ -244,9 +242,7 @@ namespace OpenSim.Framework | |||
244 | gotLock = true; | 242 | gotLock = true; |
245 | Dictionary1.Clear(); | 243 | Dictionary1.Clear(); |
246 | Dictionary2.Clear(); | 244 | Dictionary2.Clear(); |
247 | m_array = new TValue[0]; | 245 | m_array = null; |
248 | m_arrayVersion = 0; | ||
249 | m_lastArrayVersion = 0; | ||
250 | } | 246 | } |
251 | } | 247 | } |
252 | finally | 248 | finally |
@@ -391,30 +387,12 @@ namespace OpenSim.Framework | |||
391 | 387 | ||
392 | public TValue FindValue(Predicate<TValue> predicate) | 388 | public TValue FindValue(Predicate<TValue> predicate) |
393 | { | 389 | { |
394 | bool gotLock = false; | 390 | TValue[] values = GetArray(); |
395 | 391 | int len = values.Length; | |
396 | try | 392 | for (int i = 0; i < len; ++i) |
397 | { | 393 | { |
398 | // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing | 394 | if (predicate(values[i])) |
399 | // the acquision inside the main try. The inner finally block is needed because thread aborts cannot | 395 | return values[i]; |
400 | // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). | ||
401 | try {} | ||
402 | finally | ||
403 | { | ||
404 | rwLock.EnterReadLock(); | ||
405 | gotLock = true; | ||
406 | } | ||
407 | |||
408 | foreach (TValue value in Dictionary1.Values) | ||
409 | { | ||
410 | if (predicate(value)) | ||
411 | return value; | ||
412 | } | ||
413 | } | ||
414 | finally | ||
415 | { | ||
416 | if (gotLock) | ||
417 | rwLock.ExitReadLock(); | ||
418 | } | 396 | } |
419 | 397 | ||
420 | return default(TValue); | 398 | return default(TValue); |
@@ -423,32 +401,14 @@ namespace OpenSim.Framework | |||
423 | public IList<TValue> FindAll(Predicate<TValue> predicate) | 401 | public IList<TValue> FindAll(Predicate<TValue> predicate) |
424 | { | 402 | { |
425 | IList<TValue> list = new List<TValue>(); | 403 | IList<TValue> list = new List<TValue>(); |
426 | bool gotLock = false; | 404 | TValue[] values = GetArray(); |
427 | |||
428 | try | ||
429 | { | ||
430 | // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing | ||
431 | // the acquision inside the main try. The inner finally block is needed because thread aborts cannot | ||
432 | // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). | ||
433 | try {} | ||
434 | finally | ||
435 | { | ||
436 | rwLock.EnterReadLock(); | ||
437 | gotLock = true; | ||
438 | } | ||
439 | 405 | ||
440 | foreach (TValue value in Dictionary1.Values) | 406 | int len = values.Length; |
441 | { | 407 | for (int i = 0; i < len; ++i) |
442 | if (predicate(value)) | ||
443 | list.Add(value); | ||
444 | } | ||
445 | } | ||
446 | finally | ||
447 | { | 408 | { |
448 | if (gotLock) | 409 | if (predicate(values[i])) |
449 | rwLock.ExitReadLock(); | 410 | list.Add(values[i]); |
450 | } | 411 | } |
451 | |||
452 | return list; | 412 | return list; |
453 | } | 413 | } |
454 | 414 | ||
@@ -497,7 +457,7 @@ namespace OpenSim.Framework | |||
497 | 457 | ||
498 | for (int i = 0; i < list2.Count; i++) | 458 | for (int i = 0; i < list2.Count; i++) |
499 | Dictionary2.Remove(list2[i]); | 459 | Dictionary2.Remove(list2[i]); |
500 | ++m_arrayVersion; | 460 | m_array = null; |
501 | } | 461 | } |
502 | } | 462 | } |
503 | finally | 463 | finally |
@@ -527,12 +487,10 @@ namespace OpenSim.Framework | |||
527 | rwLock.EnterWriteLock(); | 487 | rwLock.EnterWriteLock(); |
528 | gotLock = true; | 488 | gotLock = true; |
529 | 489 | ||
530 | if (m_lastArrayVersion != m_arrayVersion) | 490 | if (m_array == null) |
531 | { | 491 | { |
532 | TValue[] array = new TValue[Dictionary1.Count]; | 492 | m_array = new TValue[Dictionary1.Count]; |
533 | Dictionary1.Values.CopyTo(array, 0); | 493 | Dictionary1.Values.CopyTo(m_array, 0); |
534 | m_array = array; | ||
535 | m_lastArrayVersion = m_arrayVersion; | ||
536 | } | 494 | } |
537 | ret = m_array; | 495 | ret = m_array; |
538 | } | 496 | } |
diff --git a/OpenSim/Framework/MapAndArray.cs b/OpenSim/Framework/MapAndArray.cs index a3ce55e..41874d0 100644 --- a/OpenSim/Framework/MapAndArray.cs +++ b/OpenSim/Framework/MapAndArray.cs | |||
@@ -41,8 +41,6 @@ namespace OpenSim.Framework | |||
41 | { | 41 | { |
42 | private Dictionary<TKey, TValue> m_dict; | 42 | private Dictionary<TKey, TValue> m_dict; |
43 | private TValue[] m_array; | 43 | private TValue[] m_array; |
44 | private int m_lastArrayVersion; | ||
45 | private int m_arrayVersion; | ||
46 | 44 | ||
47 | /// <summary>Number of values currently stored in the collection</summary> | 45 | /// <summary>Number of values currently stored in the collection</summary> |
48 | public int Count { get { return m_dict.Count; } } | 46 | public int Count { get { return m_dict.Count; } } |
@@ -59,9 +57,7 @@ namespace OpenSim.Framework | |||
59 | public MapAndArray() | 57 | public MapAndArray() |
60 | { | 58 | { |
61 | m_dict = new Dictionary<TKey, TValue>(); | 59 | m_dict = new Dictionary<TKey, TValue>(); |
62 | m_array = new TValue[0]; | 60 | m_array = null; |
63 | m_lastArrayVersion = 0; | ||
64 | m_arrayVersion = 0; | ||
65 | } | 61 | } |
66 | 62 | ||
67 | /// <summary> | 63 | /// <summary> |
@@ -71,9 +67,7 @@ namespace OpenSim.Framework | |||
71 | public MapAndArray(int capacity) | 67 | public MapAndArray(int capacity) |
72 | { | 68 | { |
73 | m_dict = new Dictionary<TKey, TValue>(capacity); | 69 | m_dict = new Dictionary<TKey, TValue>(capacity); |
74 | m_array = new TValue[0]; | 70 | m_array = null; |
75 | m_lastArrayVersion = 0; | ||
76 | m_arrayVersion = 0; | ||
77 | } | 71 | } |
78 | 72 | ||
79 | /// <summary> | 73 | /// <summary> |
@@ -91,7 +85,7 @@ namespace OpenSim.Framework | |||
91 | bool containedKey = m_dict.ContainsKey(key); | 85 | bool containedKey = m_dict.ContainsKey(key); |
92 | 86 | ||
93 | m_dict[key] = value; | 87 | m_dict[key] = value; |
94 | ++m_arrayVersion; | 88 | m_array = null; |
95 | 89 | ||
96 | return !containedKey; | 90 | return !containedKey; |
97 | } | 91 | } |
@@ -109,7 +103,7 @@ namespace OpenSim.Framework | |||
109 | lock (m_syncRoot) | 103 | lock (m_syncRoot) |
110 | { | 104 | { |
111 | m_dict.Add(key, value); | 105 | m_dict.Add(key, value); |
112 | ++m_arrayVersion; | 106 | m_array = null; |
113 | return m_dict.Count; | 107 | return m_dict.Count; |
114 | } | 108 | } |
115 | } | 109 | } |
@@ -124,7 +118,7 @@ namespace OpenSim.Framework | |||
124 | lock (m_syncRoot) | 118 | lock (m_syncRoot) |
125 | { | 119 | { |
126 | bool removed = m_dict.Remove(key); | 120 | bool removed = m_dict.Remove(key); |
127 | ++m_arrayVersion; | 121 | m_array = null; |
128 | return removed; | 122 | return removed; |
129 | } | 123 | } |
130 | } | 124 | } |
@@ -163,9 +157,7 @@ namespace OpenSim.Framework | |||
163 | lock (m_syncRoot) | 157 | lock (m_syncRoot) |
164 | { | 158 | { |
165 | m_dict = new Dictionary<TKey, TValue>(); | 159 | m_dict = new Dictionary<TKey, TValue>(); |
166 | m_array = new TValue[0]; | 160 | m_array = null; |
167 | m_lastArrayVersion = 0; | ||
168 | m_arrayVersion = 0; | ||
169 | } | 161 | } |
170 | } | 162 | } |
171 | 163 | ||
@@ -179,12 +171,10 @@ namespace OpenSim.Framework | |||
179 | { | 171 | { |
180 | lock (m_syncRoot) | 172 | lock (m_syncRoot) |
181 | { | 173 | { |
182 | if(m_lastArrayVersion != m_arrayVersion) | 174 | if (m_array == null) |
183 | { | 175 | { |
184 | TValue[] array = new TValue[m_dict.Count]; | 176 | m_array = new TValue[m_dict.Count]; |
185 | m_dict.Values.CopyTo(array, 0); | 177 | m_dict.Values.CopyTo(m_array, 0); |
186 | m_array = array; | ||
187 | m_lastArrayVersion = m_arrayVersion; | ||
188 | } | 178 | } |
189 | return m_array; | 179 | return m_array; |
190 | } | 180 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 252ae21..aac791d 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -2796,12 +2796,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2796 | return false; | 2796 | return false; |
2797 | } | 2797 | } |
2798 | 2798 | ||
2799 | |||
2800 | public void updateScenePartGroup(SceneObjectPart part, SceneObjectGroup grp) | ||
2801 | { | ||
2802 | m_sceneGraph.updateScenePartGroup(part, grp); | ||
2803 | } | ||
2804 | |||
2805 | /* not in use, outdate by async method | 2799 | /* not in use, outdate by async method |
2806 | /// <summary> | 2800 | /// <summary> |
2807 | /// Move the given scene object into a new region depending on which region its absolute position has moved | 2801 | /// Move the given scene object into a new region depending on which region its absolute position has moved |
@@ -5065,16 +5059,6 @@ Label_GroupsDone: | |||
5065 | 5059 | ||
5066 | #region SceneGraph wrapper methods | 5060 | #region SceneGraph wrapper methods |
5067 | 5061 | ||
5068 | /// <summary> | ||
5069 | /// | ||
5070 | /// </summary> | ||
5071 | /// <param name="localID"></param> | ||
5072 | /// <returns></returns> | ||
5073 | public UUID ConvertLocalIDToFullID(uint localID) | ||
5074 | { | ||
5075 | return m_sceneGraph.ConvertLocalIDToFullID(localID); | ||
5076 | } | ||
5077 | |||
5078 | public void SwapRootAgentCount(bool rootChildChildRootTF) | 5062 | public void SwapRootAgentCount(bool rootChildChildRootTF) |
5079 | { | 5063 | { |
5080 | m_sceneGraph.SwapRootChildAgent(rootChildChildRootTF); | 5064 | m_sceneGraph.SwapRootChildAgent(rootChildChildRootTF); |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index e37841f..17efcc5 100755 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -41,7 +41,6 @@ using OpenSim.Region.Framework.Interfaces; | |||
41 | namespace OpenSim.Region.Framework.Scenes | 41 | namespace OpenSim.Region.Framework.Scenes |
42 | { | 42 | { |
43 | public delegate void PhysicsCrash(); | 43 | public delegate void PhysicsCrash(); |
44 | |||
45 | public delegate void AttachToBackupDelegate(SceneObjectGroup sog); | 44 | public delegate void AttachToBackupDelegate(SceneObjectGroup sog); |
46 | public delegate void DetachFromBackupDelegate(SceneObjectGroup sog); | 45 | public delegate void DetachFromBackupDelegate(SceneObjectGroup sog); |
47 | public delegate void ChangedBackupDelegate(SceneObjectGroup sog); | 46 | public delegate void ChangedBackupDelegate(SceneObjectGroup sog); |
@@ -58,7 +57,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
58 | 57 | ||
59 | protected internal event PhysicsCrash UnRecoverableError; | 58 | protected internal event PhysicsCrash UnRecoverableError; |
60 | private PhysicsCrash handlerPhysicsCrash = null; | 59 | private PhysicsCrash handlerPhysicsCrash = null; |
61 | |||
62 | public event AttachToBackupDelegate OnAttachToBackup; | 60 | public event AttachToBackupDelegate OnAttachToBackup; |
63 | public event DetachFromBackupDelegate OnDetachFromBackup; | 61 | public event DetachFromBackupDelegate OnDetachFromBackup; |
64 | public event ChangedBackupDelegate OnChangeBackup; | 62 | public event ChangedBackupDelegate OnChangeBackup; |
@@ -67,44 +65,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
67 | 65 | ||
68 | #region Fields | 66 | #region Fields |
69 | 67 | ||
70 | protected System.Threading.ReaderWriterLockSlim m_scenePresencesLock; | ||
71 | |||
72 | protected ConcurrentDictionary<UUID, ScenePresence> m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>(); | ||
73 | protected ConcurrentDictionary<uint, ScenePresence> m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>(); | ||
74 | protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); | ||
75 | private int m_spArrayLastVersion; | ||
76 | private int m_spArrayVersion; | ||
77 | 68 | ||
78 | protected internal EntityManager Entities = new EntityManager(); | 69 | protected internal EntityManager Entities = new EntityManager(); |
79 | 70 | ||
80 | protected Scene m_parentScene; | 71 | private Dictionary<UUID, SceneObjectPart> m_scenePartsByID = new Dictionary<UUID, SceneObjectPart>(1024); |
81 | protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>(); | 72 | private Dictionary<uint, SceneObjectPart> m_scenePartsByLocalID = new Dictionary<uint, SceneObjectPart>(1024); |
82 | protected int m_numRootAgents = 0; | 73 | private SceneObjectPart[] m_scenePartsArray; |
83 | protected int m_numTotalPrim = 0; | 74 | private Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); |
84 | protected int m_numPrim = 0; | 75 | private Dictionary<uint, ScenePresence> m_scenePresenceLocalIDMap = new Dictionary<uint, ScenePresence>(); |
85 | protected int m_numMesh = 0; | 76 | private Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>(); |
86 | protected int m_numChildAgents = 0; | 77 | private List<ScenePresence> m_scenePresenceList; |
87 | protected int m_physicalPrim = 0; | ||
88 | 78 | ||
89 | protected int m_activeScripts = 0; | 79 | private Scene m_parentScene; |
90 | protected int m_scriptLPS = 0; | 80 | private PhysicsScene _PhyScene; |
91 | 81 | ||
92 | protected internal PhysicsScene _PhyScene; | 82 | private int m_numRootAgents = 0; |
93 | 83 | private int m_numTotalPrim = 0; | |
94 | /// <summary> | 84 | private int m_numPrim = 0; |
95 | /// Index the SceneObjectGroup for each part by the root part's UUID. | 85 | private int m_numMesh = 0; |
96 | /// </summary> | 86 | private int m_numChildAgents = 0; |
97 | protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID = new Dictionary<UUID, SceneObjectGroup>(); | 87 | private int m_physicalPrim = 0; |
98 | 88 | ||
99 | /// <summary> | 89 | private int m_activeScripts = 0; |
100 | /// Index the SceneObjectGroup for each part by that part's UUID. | 90 | private int m_scriptLPS = 0; |
101 | /// </summary> | ||
102 | protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullPartID = new Dictionary<UUID, SceneObjectGroup>(); | ||
103 | |||
104 | /// <summary> | ||
105 | /// Index the SceneObjectGroup for each part by that part's local ID. | ||
106 | /// </summary> | ||
107 | protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalPartID = new Dictionary<uint, SceneObjectGroup>(); | ||
108 | 91 | ||
109 | /// <summary> | 92 | /// <summary> |
110 | /// Lock to prevent object group update, linking, delinking and duplication operations from running concurrently. | 93 | /// Lock to prevent object group update, linking, delinking and duplication operations from running concurrently. |
@@ -114,15 +97,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
114 | /// conditions can occur. | 97 | /// conditions can occur. |
115 | /// </remarks> | 98 | /// </remarks> |
116 | private Object m_updateLock = new Object(); | 99 | private Object m_updateLock = new Object(); |
100 | private System.Threading.ReaderWriterLockSlim m_scenePresencesLock; | ||
101 | private System.Threading.ReaderWriterLockSlim m_scenePartsLock; | ||
117 | 102 | ||
118 | #endregion | 103 | #endregion |
119 | 104 | ||
120 | protected internal SceneGraph(Scene parent) | 105 | protected internal SceneGraph(Scene parent) |
121 | { | 106 | { |
122 | m_scenePresencesLock = new System.Threading.ReaderWriterLockSlim(); | 107 | m_scenePresencesLock = new System.Threading.ReaderWriterLockSlim(); |
108 | m_scenePartsLock = new System.Threading.ReaderWriterLockSlim(); | ||
123 | m_parentScene = parent; | 109 | m_parentScene = parent; |
124 | m_spArrayLastVersion = 0; | 110 | m_scenePresenceList = null; |
125 | m_spArrayVersion = 0; | 111 | m_scenePartsArray = null; |
112 | } | ||
113 | |||
114 | ~SceneGraph() | ||
115 | { | ||
116 | m_scenePartsLock.Dispose(); | ||
117 | m_scenePresencesLock.Dispose(); | ||
126 | } | 118 | } |
127 | 119 | ||
128 | public PhysicsScene PhysicsScene | 120 | public PhysicsScene PhysicsScene |
@@ -158,32 +150,40 @@ namespace OpenSim.Region.Framework.Scenes | |||
158 | { | 150 | { |
159 | m_scenePresencesLock.EnterWriteLock(); | 151 | m_scenePresencesLock.EnterWriteLock(); |
160 | entered = true; | 152 | entered = true; |
161 | m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>(); | ||
162 | m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>(); | ||
163 | m_scenePresenceArray = new List<ScenePresence>(); | ||
164 | m_spArrayLastVersion = 0; | ||
165 | m_spArrayVersion = 0; | ||
166 | if (_PhyScene != null) | ||
167 | _PhyScene.OnPhysicsCrash -= physicsBasedCrash; | ||
168 | _PhyScene = null; | ||
169 | } | 153 | } |
154 | m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); | ||
155 | m_scenePresenceLocalIDMap = new Dictionary<uint, ScenePresence>(); | ||
156 | m_scenePresenceList = null; | ||
170 | } | 157 | } |
171 | finally | 158 | finally |
172 | { | 159 | { |
173 | if(entered) | 160 | if (entered) |
174 | m_scenePresencesLock.ExitWriteLock(); | 161 | m_scenePresencesLock.ExitWriteLock(); |
175 | } | 162 | } |
176 | 163 | ||
177 | lock (SceneObjectGroupsByFullID) | 164 | entered = false; |
178 | SceneObjectGroupsByFullID.Clear(); | 165 | try |
179 | lock (SceneObjectGroupsByFullPartID) | 166 | { |
180 | SceneObjectGroupsByFullPartID.Clear(); | 167 | try { } |
181 | lock (SceneObjectGroupsByLocalPartID) | 168 | finally |
182 | SceneObjectGroupsByLocalPartID.Clear(); | 169 | { |
170 | m_scenePartsLock.EnterWriteLock(); | ||
171 | entered = true; | ||
172 | } | ||
183 | 173 | ||
184 | Entities.Clear(); | 174 | Entities.Clear(); |
185 | m_scenePresencesLock.Dispose(); | 175 | m_scenePartsArray = null; |
186 | m_scenePresencesLock = null; | 176 | m_scenePartsByID = new Dictionary<UUID, SceneObjectPart>(); |
177 | m_scenePartsByLocalID = new Dictionary<uint, SceneObjectPart>(); | ||
178 | if (_PhyScene != null) | ||
179 | _PhyScene.OnPhysicsCrash -= physicsBasedCrash; | ||
180 | _PhyScene = null; | ||
181 | } | ||
182 | finally | ||
183 | { | ||
184 | if (entered) | ||
185 | m_scenePartsLock.ExitWriteLock(); | ||
186 | } | ||
187 | } | 187 | } |
188 | 188 | ||
189 | #region Update Methods | 189 | #region Update Methods |
@@ -251,9 +251,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
251 | scaleY = 1.0f / scaleY; | 251 | scaleY = 1.0f / scaleY; |
252 | 252 | ||
253 | List<ScenePresence> presences = GetScenePresences(); | 253 | List<ScenePresence> presences = GetScenePresences(); |
254 | for (int i = 0; i < Math.Min(presences.Count, maxLocations); ++i) | 254 | int len = presences.Count; |
255 | if(len > maxLocations) | ||
256 | len = (int)maxLocations; | ||
257 | |||
258 | ScenePresence sp; | ||
259 | for (int i = 0; i < len; ++i) | ||
255 | { | 260 | { |
256 | ScenePresence sp = presences[i]; | 261 | sp = presences[i]; |
257 | 262 | ||
258 | // If this presence is a child agent, we don't want its coarse locations | 263 | // If this presence is a child agent, we don't want its coarse locations |
259 | if (sp.IsChildAgent) | 264 | if (sp.IsChildAgent) |
@@ -295,16 +300,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
295 | { | 300 | { |
296 | // temporary checks to remove after varsize suport | 301 | // temporary checks to remove after varsize suport |
297 | float regionSizeX = m_parentScene.RegionInfo.RegionSizeX; | 302 | float regionSizeX = m_parentScene.RegionInfo.RegionSizeX; |
298 | if (regionSizeX == 0) | ||
299 | regionSizeX = Constants.RegionSize; | ||
300 | float regionSizeY = m_parentScene.RegionInfo.RegionSizeY; | 303 | float regionSizeY = m_parentScene.RegionInfo.RegionSizeY; |
301 | if (regionSizeY == 0) | ||
302 | regionSizeY = Constants.RegionSize; | ||
303 | 304 | ||
304 | // KF: Check for out-of-region, move inside and make static. | 305 | // KF: Check for out-of-region, move inside and make static. |
305 | Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, | 306 | Vector3 npos = sceneObject.RootPart.GroupPosition; |
306 | sceneObject.RootPart.GroupPosition.Y, | ||
307 | sceneObject.RootPart.GroupPosition.Z); | ||
308 | bool clampZ = m_parentScene.ClampNegativeZ; | 307 | bool clampZ = m_parentScene.ClampNegativeZ; |
309 | 308 | ||
310 | if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || (npos.Z < 0.0 && clampZ) || | 309 | if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || (npos.Z < 0.0 && clampZ) || |
@@ -454,13 +453,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
454 | // sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName); | 453 | // sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName); |
455 | 454 | ||
456 | SceneObjectPart[] parts = sceneObject.Parts; | 455 | SceneObjectPart[] parts = sceneObject.Parts; |
456 | int partsLength = parts.Length; | ||
457 | SceneObjectPart part; | ||
457 | 458 | ||
458 | // Clamp the sizes (scales) of the child prims and add the child prims to the count of all primitives | 459 | // Clamp the sizes (scales) of the child prims and add the child prims to the count of all primitives |
459 | // (meshes and geometric primitives) in the scene; add child prims to m_numTotalPrim count | 460 | // (meshes and geometric primitives) in the scene; add child prims to m_numTotalPrim count |
460 | if (m_parentScene.m_clampPrimSize) | 461 | if (m_parentScene.m_clampPrimSize) |
461 | { | 462 | { |
462 | foreach (SceneObjectPart part in parts) | 463 | for (int i = 0; i< partsLength; ++i) |
463 | { | 464 | { |
465 | part = parts[i]; | ||
464 | Vector3 scale = part.Shape.Scale; | 466 | Vector3 scale = part.Shape.Scale; |
465 | 467 | ||
466 | scale.X = Util.Clamp(scale.X, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys); | 468 | scale.X = Util.Clamp(scale.X, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys); |
@@ -470,34 +472,38 @@ namespace OpenSim.Region.Framework.Scenes | |||
470 | part.Shape.Scale = scale; | 472 | part.Shape.Scale = scale; |
471 | } | 473 | } |
472 | } | 474 | } |
473 | m_numTotalPrim += parts.Length; | ||
474 | |||
475 | // Go through all parts (geometric primitives and meshes) of this Scene Object | ||
476 | foreach (SceneObjectPart part in parts) | ||
477 | { | ||
478 | // Keep track of the total number of meshes or geometric primitives now in the scene; | ||
479 | // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to | ||
480 | // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives | ||
481 | if (part.GetPrimType() == PrimType.SCULPT) | ||
482 | m_numMesh++; | ||
483 | else | ||
484 | m_numPrim++; | ||
485 | } | ||
486 | 475 | ||
487 | sceneObject.AttachToScene(m_parentScene); | 476 | sceneObject.AttachToScene(m_parentScene); |
488 | 477 | ||
489 | Entities.Add(sceneObject); | 478 | bool entered = false; |
479 | try | ||
480 | { | ||
481 | try { } | ||
482 | finally | ||
483 | { | ||
484 | m_scenePartsLock.EnterWriteLock(); | ||
485 | entered = true; | ||
486 | } | ||
490 | 487 | ||
491 | lock (SceneObjectGroupsByFullID) | 488 | m_numTotalPrim += partsLength; |
492 | SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; | ||
493 | 489 | ||
494 | foreach (SceneObjectPart part in parts) | 490 | Entities.Add(sceneObject); |
491 | m_scenePartsArray = null; | ||
492 | for (int i = 0; i < partsLength; ++i) | ||
493 | { | ||
494 | part = parts[i]; | ||
495 | m_scenePartsByID[part.UUID] = part; | ||
496 | m_scenePartsByLocalID[part.LocalId] = part; | ||
497 | if (part.GetPrimType() == PrimType.SCULPT) | ||
498 | ++m_numMesh; | ||
499 | else | ||
500 | ++m_numPrim; | ||
501 | } | ||
502 | } | ||
503 | finally | ||
495 | { | 504 | { |
496 | lock (SceneObjectGroupsByFullPartID) | 505 | if(entered) |
497 | SceneObjectGroupsByFullPartID[part.UUID] = sceneObject; | 506 | m_scenePartsLock.ExitWriteLock(); |
498 | |||
499 | lock (SceneObjectGroupsByLocalPartID) | ||
500 | SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject; | ||
501 | } | 507 | } |
502 | 508 | ||
503 | if (sendClientUpdates) | 509 | if (sendClientUpdates) |
@@ -509,16 +515,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
509 | return true; | 515 | return true; |
510 | } | 516 | } |
511 | 517 | ||
512 | public void updateScenePartGroup(SceneObjectPart part, SceneObjectGroup grp) | ||
513 | { | ||
514 | // no tests, caller has responsability... | ||
515 | lock (SceneObjectGroupsByFullPartID) | ||
516 | SceneObjectGroupsByFullPartID[part.UUID] = grp; | ||
517 | |||
518 | lock (SceneObjectGroupsByLocalPartID) | ||
519 | SceneObjectGroupsByLocalPartID[part.LocalId] = grp; | ||
520 | } | ||
521 | |||
522 | /// <summary> | 518 | /// <summary> |
523 | /// Delete an object from the scene | 519 | /// Delete an object from the scene |
524 | /// </summary> | 520 | /// </summary> |
@@ -534,9 +530,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
534 | return false; | 530 | return false; |
535 | 531 | ||
536 | SceneObjectGroup grp = (SceneObjectGroup)entity; | 532 | SceneObjectGroup grp = (SceneObjectGroup)entity; |
537 | 533 | SceneObjectPart[] parts = grp.Parts; | |
538 | if (entity == null) | 534 | int partsLength = parts.Length; |
539 | return false; | 535 | SceneObjectPart part; |
540 | 536 | ||
541 | if (!resultOfObjectLinked) | 537 | if (!resultOfObjectLinked) |
542 | { | 538 | { |
@@ -546,9 +542,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
546 | 542 | ||
547 | bool isPh = (grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics; | 543 | bool isPh = (grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics; |
548 | int nphysparts = 0; | 544 | int nphysparts = 0; |
545 | |||
549 | // Go through all parts (primitives and meshes) of this Scene Object | 546 | // Go through all parts (primitives and meshes) of this Scene Object |
550 | foreach (SceneObjectPart part in grp.Parts) | 547 | for (int i= 0; i < partsLength; ++i) |
551 | { | 548 | { |
549 | part = parts[i]; | ||
552 | // Keep track of the total number of meshes or geometric primitives left in the scene; | 550 | // Keep track of the total number of meshes or geometric primitives left in the scene; |
553 | // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to | 551 | // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to |
554 | // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives | 552 | // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives |
@@ -565,21 +563,31 @@ namespace OpenSim.Region.Framework.Scenes | |||
565 | RemovePhysicalPrim(nphysparts); | 563 | RemovePhysicalPrim(nphysparts); |
566 | } | 564 | } |
567 | 565 | ||
568 | bool ret = Entities.Remove(uuid); | 566 | bool ret = false; |
569 | 567 | bool entered = false; | |
570 | lock (SceneObjectGroupsByFullID) | 568 | try |
571 | SceneObjectGroupsByFullID.Remove(grp.UUID); | ||
572 | |||
573 | SceneObjectPart[] parts = grp.Parts; | ||
574 | for (int i = 0; i < parts.Length; i++) | ||
575 | { | 569 | { |
576 | lock (SceneObjectGroupsByFullPartID) | 570 | try { } |
577 | SceneObjectGroupsByFullPartID.Remove(parts[i].UUID); | 571 | finally |
572 | { | ||
573 | m_scenePartsLock.EnterWriteLock(); | ||
574 | entered = true; | ||
575 | } | ||
578 | 576 | ||
579 | lock (SceneObjectGroupsByLocalPartID) | 577 | for (int i = 0; i < parts.Length; ++i) |
580 | SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId); | 578 | { |
579 | part = parts[i]; | ||
580 | m_scenePartsByID.Remove(part.UUID); | ||
581 | m_scenePartsByLocalID.Remove(part.LocalId); | ||
582 | } | ||
583 | m_scenePartsArray = null; | ||
584 | ret = Entities.Remove(uuid); | ||
585 | } | ||
586 | finally | ||
587 | { | ||
588 | if(entered) | ||
589 | m_scenePartsLock.ExitWriteLock(); | ||
581 | } | 590 | } |
582 | |||
583 | return ret; | 591 | return ret; |
584 | } | 592 | } |
585 | 593 | ||
@@ -591,7 +599,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
591 | /// </param> | 599 | /// </param> |
592 | protected internal void AddToUpdateList(SceneObjectGroup obj) | 600 | protected internal void AddToUpdateList(SceneObjectGroup obj) |
593 | { | 601 | { |
594 | lock (m_updateList) | 602 | lock(m_updateLock) |
595 | m_updateList[obj.UUID] = obj; | 603 | m_updateList[obj.UUID] = obj; |
596 | } | 604 | } |
597 | 605 | ||
@@ -628,20 +636,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
628 | return; | 636 | return; |
629 | try | 637 | try |
630 | { | 638 | { |
631 | List<SceneObjectGroup> updates; | 639 | Dictionary<UUID, SceneObjectGroup> updates; |
632 | |||
633 | // Some updates add more updates to the updateList. | ||
634 | // Get the current list of updates and clear the list before iterating | 640 | // Get the current list of updates and clear the list before iterating |
635 | lock (m_updateList) | 641 | lock (m_updateLock) |
636 | { | 642 | { |
637 | updates = new List<SceneObjectGroup>(m_updateList.Values); | 643 | updates = m_updateList; |
638 | m_updateList = new Dictionary<UUID, SceneObjectGroup>(); | 644 | m_updateList = new Dictionary<UUID, SceneObjectGroup>(); |
639 | } | 645 | } |
640 | 646 | ||
641 | // Go through all updates | 647 | // Go through all updates |
642 | for (int i = 0; i < updates.Count; i++) | 648 | foreach (SceneObjectGroup sog in updates.Values) |
643 | { | 649 | { |
644 | SceneObjectGroup sog = updates[i]; | ||
645 | if (sog.IsDeleted) | 650 | if (sog.IsDeleted) |
646 | continue; | 651 | continue; |
647 | 652 | ||
@@ -656,6 +661,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
656 | "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e); | 661 | "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e); |
657 | } | 662 | } |
658 | } | 663 | } |
664 | updates = null; | ||
659 | } | 665 | } |
660 | finally | 666 | finally |
661 | { | 667 | { |
@@ -705,14 +711,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
705 | } | 711 | } |
706 | 712 | ||
707 | protected internal ScenePresence CreateAndAddChildScenePresence( | 713 | protected internal ScenePresence CreateAndAddChildScenePresence( |
708 | IClientAPI client, AvatarAppearance appearance, PresenceType type) | 714 | IClientAPI client, AvatarAppearance appearance, PresenceType type) |
709 | { | 715 | { |
710 | // ScenePresence always defaults to child agent | ||
711 | ScenePresence presence = new ScenePresence(client, m_parentScene, appearance, type); | 716 | ScenePresence presence = new ScenePresence(client, m_parentScene, appearance, type); |
712 | 717 | ||
713 | Entities[presence.UUID] = presence; | ||
714 | bool entered = false; | 718 | bool entered = false; |
715 | |||
716 | try | 719 | try |
717 | { | 720 | { |
718 | try{ } | 721 | try{ } |
@@ -720,31 +723,31 @@ namespace OpenSim.Region.Framework.Scenes | |||
720 | { | 723 | { |
721 | m_scenePresencesLock.EnterWriteLock(); | 724 | m_scenePresencesLock.EnterWriteLock(); |
722 | entered = true; | 725 | entered = true; |
726 | } | ||
723 | 727 | ||
724 | m_numChildAgents++; | 728 | UUID id = presence.UUID; |
725 | 729 | Entities[id] = presence; | |
726 | if (!m_scenePresenceMap.ContainsKey(presence.UUID)) | 730 | // ScenePresence always defaults to child agent |
727 | { | 731 | ++m_numChildAgents; |
728 | m_scenePresenceMap[presence.UUID] = presence; | ||
729 | m_scenePresenceLocalIDMap[presence.LocalId] = presence; | ||
730 | } | ||
731 | else | ||
732 | { | ||
733 | // Remember the old presence reference from the dictionary | ||
734 | ScenePresence oldref = m_scenePresenceMap[presence.UUID]; | ||
735 | uint oldLocalID = oldref.LocalId; | ||
736 | // Replace the presence reference in the dictionary with the new value | ||
737 | m_scenePresenceMap[presence.UUID] = presence; | ||
738 | if(presence.LocalId != oldLocalID) | ||
739 | { | ||
740 | m_scenePresenceLocalIDMap.TryRemove(oldLocalID, out oldref); | ||
741 | m_scenePresenceLocalIDMap[presence.LocalId] = presence; | ||
742 | } | ||
743 | // Find the index in the list where the old ref was stored and update the reference | ||
744 | } | ||
745 | 732 | ||
746 | ++m_spArrayVersion; | 733 | uint localid = presence.LocalId; |
734 | ScenePresence oldref; | ||
735 | if (m_scenePresenceMap.TryGetValue(id, out oldref)) | ||
736 | { | ||
737 | // Remember the old presence reference from the dictionary | ||
738 | uint oldLocalID = oldref.LocalId; | ||
739 | // Replace the presence reference in the dictionary with the new value | ||
740 | m_scenePresenceMap[id] = presence; | ||
741 | if (localid != oldLocalID) | ||
742 | m_scenePresenceLocalIDMap.Remove(oldLocalID); | ||
743 | m_scenePresenceLocalIDMap[localid] = presence; | ||
744 | } | ||
745 | else | ||
746 | { | ||
747 | m_scenePresenceMap[id] = presence; | ||
748 | m_scenePresenceLocalIDMap[localid] = presence; | ||
747 | } | 749 | } |
750 | m_scenePresenceList = null; | ||
748 | } | 751 | } |
749 | finally | 752 | finally |
750 | { | 753 | { |
@@ -775,18 +778,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
775 | { | 778 | { |
776 | m_scenePresencesLock.EnterWriteLock(); | 779 | m_scenePresencesLock.EnterWriteLock(); |
777 | entered = true; | 780 | entered = true; |
778 | // Remove the presence reference from the dictionary | 781 | } |
779 | ScenePresence oldref; | 782 | // Remove the presence reference from the dictionary |
780 | if(m_scenePresenceMap.TryRemove(agentID, out oldref)) | 783 | ScenePresence oldref; |
781 | { | 784 | if(m_scenePresenceMap.TryGetValue(agentID, out oldref)) |
782 | // Find the index in the list where the old ref was stored and remove the reference | 785 | { |
783 | m_scenePresenceLocalIDMap.TryRemove(oldref.LocalId, out oldref); | 786 | m_scenePresenceMap.Remove(agentID); |
784 | ++m_spArrayVersion; | 787 | // Find the index in the list where the old ref was stored and remove the reference |
785 | } | 788 | m_scenePresenceLocalIDMap.Remove(oldref.LocalId); |
786 | else | 789 | m_scenePresenceList = null; |
787 | { | 790 | } |
788 | m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); | 791 | else |
789 | } | 792 | { |
793 | m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); | ||
790 | } | 794 | } |
791 | } | 795 | } |
792 | finally | 796 | finally |
@@ -900,14 +904,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
900 | /// prevents CapabilitiesModule from accessing it</remarks> | 904 | /// prevents CapabilitiesModule from accessing it</remarks> |
901 | public IClientAPI GetControllingClient(UUID agentId) | 905 | public IClientAPI GetControllingClient(UUID agentId) |
902 | { | 906 | { |
903 | ScenePresence presence = GetScenePresence(agentId); | 907 | bool entered = false; |
904 | 908 | try | |
905 | if (presence != null) | 909 | { |
910 | try { } | ||
911 | finally | ||
912 | { | ||
913 | m_scenePresencesLock.EnterReadLock(); | ||
914 | entered = true; | ||
915 | } | ||
916 | ScenePresence presence; | ||
917 | if (m_scenePresenceMap.TryGetValue(agentId, out presence)) | ||
918 | return presence.ControllingClient; | ||
919 | return null; | ||
920 | } | ||
921 | catch | ||
906 | { | 922 | { |
907 | return presence.ControllingClient; | 923 | return null; |
924 | } | ||
925 | finally | ||
926 | { | ||
927 | if (entered) | ||
928 | m_scenePresencesLock.ExitReadLock(); | ||
908 | } | 929 | } |
909 | |||
910 | return null; | ||
911 | } | 930 | } |
912 | 931 | ||
913 | /// <summary> | 932 | /// <summary> |
@@ -920,7 +939,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
920 | protected internal List<ScenePresence> GetScenePresences() | 939 | protected internal List<ScenePresence> GetScenePresences() |
921 | { | 940 | { |
922 | bool entered = false; | 941 | bool entered = false; |
923 | List<ScenePresence> ret = new List<ScenePresence>(); | ||
924 | try | 942 | try |
925 | { | 943 | { |
926 | try{ } | 944 | try{ } |
@@ -928,20 +946,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
928 | { | 946 | { |
929 | m_scenePresencesLock.EnterWriteLock(); | 947 | m_scenePresencesLock.EnterWriteLock(); |
930 | entered = true; | 948 | entered = true; |
931 | if(m_spArrayLastVersion != m_spArrayVersion) | ||
932 | { | ||
933 | m_scenePresenceArray = new List<ScenePresence>(m_scenePresenceMap.Values); | ||
934 | m_spArrayLastVersion = m_spArrayVersion; | ||
935 | } | ||
936 | ret = m_scenePresenceArray; | ||
937 | } | 949 | } |
950 | |||
951 | if(m_scenePresenceList == null) | ||
952 | m_scenePresenceList = new List<ScenePresence>(m_scenePresenceMap.Values); | ||
953 | |||
954 | return m_scenePresenceList; | ||
955 | } | ||
956 | catch | ||
957 | { | ||
958 | return new List<ScenePresence>(); | ||
938 | } | 959 | } |
939 | finally | 960 | finally |
940 | { | 961 | { |
941 | if(entered) | 962 | if(entered) |
942 | m_scenePresencesLock.ExitWriteLock(); | 963 | m_scenePresencesLock.ExitWriteLock(); |
943 | } | 964 | } |
944 | return ret; | ||
945 | } | 965 | } |
946 | 966 | ||
947 | /// <summary> | 967 | /// <summary> |
@@ -951,9 +971,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
951 | /// <returns>null if the presence was not found</returns> | 971 | /// <returns>null if the presence was not found</returns> |
952 | protected internal ScenePresence GetScenePresence(UUID agentID) | 972 | protected internal ScenePresence GetScenePresence(UUID agentID) |
953 | { | 973 | { |
954 | ScenePresence presence; | 974 | bool entered = false; |
955 | m_scenePresenceMap.TryGetValue(agentID, out presence); | 975 | try |
956 | return presence; | 976 | { |
977 | try { } | ||
978 | finally | ||
979 | { | ||
980 | m_scenePresencesLock.EnterReadLock(); | ||
981 | entered = true; | ||
982 | } | ||
983 | ScenePresence presence; | ||
984 | m_scenePresenceMap.TryGetValue(agentID, out presence); | ||
985 | return presence; | ||
986 | } | ||
987 | catch | ||
988 | { | ||
989 | return null; | ||
990 | } | ||
991 | finally | ||
992 | { | ||
993 | if (entered) | ||
994 | m_scenePresencesLock.ExitReadLock(); | ||
995 | } | ||
957 | } | 996 | } |
958 | 997 | ||
959 | /// <summary> | 998 | /// <summary> |
@@ -981,21 +1020,50 @@ namespace OpenSim.Region.Framework.Scenes | |||
981 | /// <returns>null if the presence was not found</returns> | 1020 | /// <returns>null if the presence was not found</returns> |
982 | protected internal ScenePresence GetScenePresence(uint localID) | 1021 | protected internal ScenePresence GetScenePresence(uint localID) |
983 | { | 1022 | { |
984 | ScenePresence sp = null; | 1023 | bool entered = false; |
985 | if(m_scenePresenceLocalIDMap.TryGetValue(localID, out sp)) | 1024 | try |
986 | return sp; | 1025 | { |
987 | /* | 1026 | try { } |
988 | List<ScenePresence> presences = GetScenePresences(); | 1027 | finally |
989 | foreach (ScenePresence presence in presences) | 1028 | { |
990 | if (presence.LocalId == localID) | 1029 | m_scenePresencesLock.EnterReadLock(); |
991 | return presence; | 1030 | entered = true; |
992 | */ | 1031 | } |
1032 | ScenePresence sp; | ||
1033 | if (m_scenePresenceLocalIDMap.TryGetValue(localID, out sp)) | ||
1034 | return sp; | ||
1035 | } | ||
1036 | finally | ||
1037 | { | ||
1038 | if (entered) | ||
1039 | m_scenePresencesLock.ExitReadLock(); | ||
1040 | } | ||
993 | return null; | 1041 | return null; |
994 | } | 1042 | } |
995 | 1043 | ||
996 | protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) | 1044 | protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) |
997 | { | 1045 | { |
998 | return m_scenePresenceMap.TryGetValue(agentID, out avatar); | 1046 | bool entered = false; |
1047 | try | ||
1048 | { | ||
1049 | try { } | ||
1050 | finally | ||
1051 | { | ||
1052 | m_scenePresencesLock.EnterReadLock(); | ||
1053 | entered = true; | ||
1054 | } | ||
1055 | return m_scenePresenceMap.TryGetValue(agentID, out avatar); | ||
1056 | } | ||
1057 | catch | ||
1058 | { | ||
1059 | avatar = null; | ||
1060 | return false; | ||
1061 | } | ||
1062 | finally | ||
1063 | { | ||
1064 | if (entered) | ||
1065 | m_scenePresencesLock.ExitReadLock(); | ||
1066 | } | ||
999 | } | 1067 | } |
1000 | 1068 | ||
1001 | protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar) | 1069 | protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar) |
@@ -1020,56 +1088,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
1020 | /// <returns>null if no scene object group containing that prim is found</returns> | 1088 | /// <returns>null if no scene object group containing that prim is found</returns> |
1021 | public SceneObjectGroup GetGroupByPrim(uint localID) | 1089 | public SceneObjectGroup GetGroupByPrim(uint localID) |
1022 | { | 1090 | { |
1023 | EntityBase entity; | 1091 | bool entered = false; |
1024 | if (Entities.TryGetValue(localID, out entity)) | 1092 | try |
1025 | return entity as SceneObjectGroup; | ||
1026 | |||
1027 | // m_log.DebugFormat("[SCENE GRAPH]: Entered GetGroupByPrim with localID {0}", localID); | ||
1028 | |||
1029 | SceneObjectGroup sog; | ||
1030 | lock (SceneObjectGroupsByLocalPartID) | ||
1031 | SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog); | ||
1032 | |||
1033 | if (sog != null) | ||
1034 | { | 1093 | { |
1035 | if (sog.ContainsPart(localID)) | 1094 | try { } |
1036 | { | 1095 | finally |
1037 | // m_log.DebugFormat( | ||
1038 | // "[SCENE GRAPH]: Found scene object {0} {1} {2} containing part with local id {3} in {4}. Returning.", | ||
1039 | // sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName); | ||
1040 | |||
1041 | return sog; | ||
1042 | } | ||
1043 | else | ||
1044 | { | 1096 | { |
1045 | lock (SceneObjectGroupsByLocalPartID) | 1097 | m_scenePartsLock.EnterReadLock(); |
1046 | { | 1098 | entered = true; |
1047 | m_log.WarnFormat( | ||
1048 | "[SCENE GRAPH]: Found scene object {0} {1} {2} via SceneObjectGroupsByLocalPartID index but it doesn't contain part with local id {3}. Removing from entry from index in {4}.", | ||
1049 | sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName); | ||
1050 | m_log.WarnFormat("stack: {0}", Environment.StackTrace); | ||
1051 | SceneObjectGroupsByLocalPartID.Remove(localID); | ||
1052 | } | ||
1053 | } | 1099 | } |
1100 | SceneObjectPart sop; | ||
1101 | if(m_scenePartsByLocalID.TryGetValue(localID, out sop)) | ||
1102 | return sop.ParentGroup; | ||
1103 | return null; | ||
1054 | } | 1104 | } |
1055 | 1105 | finally | |
1056 | EntityBase[] entityList = GetEntities(); | ||
1057 | foreach (EntityBase ent in entityList) | ||
1058 | { | 1106 | { |
1059 | //m_log.DebugFormat("Looking at entity {0}", ent.UUID); | 1107 | if(entered) |
1060 | if (ent is SceneObjectGroup) | 1108 | m_scenePartsLock.ExitReadLock(); |
1061 | { | ||
1062 | sog = (SceneObjectGroup)ent; | ||
1063 | if (sog.ContainsPart(localID)) | ||
1064 | { | ||
1065 | lock (SceneObjectGroupsByLocalPartID) | ||
1066 | SceneObjectGroupsByLocalPartID[localID] = sog; | ||
1067 | return sog; | ||
1068 | } | ||
1069 | } | ||
1070 | } | 1109 | } |
1071 | |||
1072 | return null; | ||
1073 | } | 1110 | } |
1074 | 1111 | ||
1075 | /// <summary> | 1112 | /// <summary> |
@@ -1079,35 +1116,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
1079 | /// <returns>null if no scene object group containing that prim is found</returns> | 1116 | /// <returns>null if no scene object group containing that prim is found</returns> |
1080 | public SceneObjectGroup GetGroupByPrim(UUID fullID) | 1117 | public SceneObjectGroup GetGroupByPrim(UUID fullID) |
1081 | { | 1118 | { |
1082 | SceneObjectGroup sog; | 1119 | bool entered = false; |
1083 | lock (SceneObjectGroupsByFullPartID) | 1120 | try |
1084 | SceneObjectGroupsByFullPartID.TryGetValue(fullID, out sog); | ||
1085 | |||
1086 | if (sog != null) | ||
1087 | { | ||
1088 | if (sog.ContainsPart(fullID)) | ||
1089 | return sog; | ||
1090 | |||
1091 | lock (SceneObjectGroupsByFullPartID) | ||
1092 | SceneObjectGroupsByFullPartID.Remove(fullID); | ||
1093 | } | ||
1094 | |||
1095 | EntityBase[] entityList = GetEntities(); | ||
1096 | foreach (EntityBase ent in entityList) | ||
1097 | { | 1121 | { |
1098 | if (ent is SceneObjectGroup) | 1122 | try { } |
1123 | finally | ||
1099 | { | 1124 | { |
1100 | sog = (SceneObjectGroup)ent; | 1125 | m_scenePartsLock.EnterReadLock(); |
1101 | if (sog.ContainsPart(fullID)) | 1126 | entered = true; |
1102 | { | ||
1103 | lock (SceneObjectGroupsByFullPartID) | ||
1104 | SceneObjectGroupsByFullPartID[fullID] = sog; | ||
1105 | return sog; | ||
1106 | } | ||
1107 | } | 1127 | } |
1128 | SceneObjectPart sop; | ||
1129 | if (m_scenePartsByID.TryGetValue(fullID, out sop)) | ||
1130 | return sop.ParentGroup; | ||
1131 | return null; | ||
1132 | } | ||
1133 | finally | ||
1134 | { | ||
1135 | if (entered) | ||
1136 | m_scenePartsLock.ExitReadLock(); | ||
1108 | } | 1137 | } |
1109 | |||
1110 | return null; | ||
1111 | } | 1138 | } |
1112 | 1139 | ||
1113 | protected internal EntityIntersection GetClosestIntersectingPrim(Ray hray, bool frontFacesOnly, bool faceCenters) | 1140 | protected internal EntityIntersection GetClosestIntersectingPrim(Ray hray, bool frontFacesOnly, bool faceCenters) |
@@ -1140,8 +1167,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1140 | /// </returns> | 1167 | /// </returns> |
1141 | protected internal List<SceneObjectGroup> GetSceneObjectGroups() | 1168 | protected internal List<SceneObjectGroup> GetSceneObjectGroups() |
1142 | { | 1169 | { |
1143 | lock (SceneObjectGroupsByFullID) | 1170 | EntityBase[] entities = Entities.GetEntities(); |
1144 | return new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); | 1171 | List<SceneObjectGroup> ret = new List<SceneObjectGroup>(256); |
1172 | int len = entities.Length; | ||
1173 | for (int i = 0; i < len; ++i) | ||
1174 | { | ||
1175 | if(entities[i] is SceneObjectGroup) | ||
1176 | ret.Add((SceneObjectGroup)entities[i]); | ||
1177 | } | ||
1178 | return ret; | ||
1145 | } | 1179 | } |
1146 | 1180 | ||
1147 | /// <summary> | 1181 | /// <summary> |
@@ -1151,36 +1185,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1151 | /// <returns>null if no such group was found</returns> | 1185 | /// <returns>null if no such group was found</returns> |
1152 | protected internal SceneObjectGroup GetSceneObjectGroup(UUID fullID) | 1186 | protected internal SceneObjectGroup GetSceneObjectGroup(UUID fullID) |
1153 | { | 1187 | { |
1154 | lock (SceneObjectGroupsByFullID) | 1188 | EntityBase entity; |
1155 | { | 1189 | if (Entities.TryGetValue(fullID, out entity) && (entity is SceneObjectGroup)) |
1156 | if (SceneObjectGroupsByFullID.ContainsKey(fullID)) | 1190 | return (SceneObjectGroup)entity; |
1157 | return SceneObjectGroupsByFullID[fullID]; | ||
1158 | } | ||
1159 | |||
1160 | return null; | 1191 | return null; |
1161 | } | 1192 | } |
1162 | 1193 | ||
1163 | /// <summary> | 1194 | /// <summary> |
1164 | /// Get a group in the scene | 1195 | /// Get a group in the scene |
1165 | /// </summary> | ||
1166 | /// <remarks> | ||
1167 | /// This will only return a group if the local ID matches the root part, not other parts. | ||
1168 | /// </remarks> | ||
1169 | /// <param name="localID">Local id of the root part of the group</param> | 1196 | /// <param name="localID">Local id of the root part of the group</param> |
1170 | /// <returns>null if no such group was found</returns> | 1197 | /// <returns>null if no such group was found</returns> |
1171 | protected internal SceneObjectGroup GetSceneObjectGroup(uint localID) | 1198 | protected internal SceneObjectGroup GetSceneObjectGroup(uint localID) |
1172 | { | 1199 | { |
1173 | lock (SceneObjectGroupsByLocalPartID) | 1200 | EntityBase entity; |
1174 | { | 1201 | if (Entities.TryGetValue(localID, out entity) && (entity is SceneObjectGroup)) |
1175 | if (SceneObjectGroupsByLocalPartID.ContainsKey(localID)) | 1202 | return (SceneObjectGroup)entity; |
1176 | { | ||
1177 | SceneObjectGroup so = SceneObjectGroupsByLocalPartID[localID]; | ||
1178 | |||
1179 | if (so.LocalId == localID) | ||
1180 | return so; | ||
1181 | } | ||
1182 | } | ||
1183 | |||
1184 | return null; | 1203 | return null; |
1185 | } | 1204 | } |
1186 | 1205 | ||
@@ -1192,25 +1211,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1192 | /// <returns>null if the part was not found</returns> | 1211 | /// <returns>null if the part was not found</returns> |
1193 | protected internal SceneObjectGroup GetSceneObjectGroup(string name) | 1212 | protected internal SceneObjectGroup GetSceneObjectGroup(string name) |
1194 | { | 1213 | { |
1195 | SceneObjectGroup so = null; | 1214 | EntityBase entity = null; |
1196 | 1215 | EntityBase[] entities = Entities.GetEntities(); | |
1197 | Entities.Find( | 1216 | int len = entities.Length; |
1198 | delegate(EntityBase entity) | 1217 | for (int i = 0; i < len; ++i) |
1199 | { | 1218 | { |
1200 | if (entity is SceneObjectGroup) | 1219 | entity = entities[i]; |
1201 | { | 1220 | if (entity is SceneObjectGroup && entity.Name == name) |
1202 | if (entity.Name == name) | 1221 | return (SceneObjectGroup)entity; |
1203 | { | 1222 | } |
1204 | so = (SceneObjectGroup)entity; | 1223 | return null; |
1205 | return true; | ||
1206 | } | ||
1207 | } | ||
1208 | |||
1209 | return false; | ||
1210 | } | ||
1211 | ); | ||
1212 | |||
1213 | return so; | ||
1214 | } | 1224 | } |
1215 | 1225 | ||
1216 | /// <summary> | 1226 | /// <summary> |
@@ -1220,57 +1230,108 @@ namespace OpenSim.Region.Framework.Scenes | |||
1220 | /// <returns>null if the part was not found</returns> | 1230 | /// <returns>null if the part was not found</returns> |
1221 | protected internal SceneObjectPart GetSceneObjectPart(uint localID) | 1231 | protected internal SceneObjectPart GetSceneObjectPart(uint localID) |
1222 | { | 1232 | { |
1223 | SceneObjectGroup group = GetGroupByPrim(localID); | 1233 | bool entered = false; |
1224 | if (group == null || group.IsDeleted) | 1234 | try |
1235 | { | ||
1236 | try { } | ||
1237 | finally | ||
1238 | { | ||
1239 | m_scenePartsLock.EnterReadLock(); | ||
1240 | entered = true; | ||
1241 | } | ||
1242 | SceneObjectPart sop; | ||
1243 | if (m_scenePartsByLocalID.TryGetValue(localID, out sop)) | ||
1244 | { | ||
1245 | if (sop.ParentGroup == null || sop.ParentGroup.IsDeleted) | ||
1246 | return null; | ||
1247 | return sop; | ||
1248 | } | ||
1225 | return null; | 1249 | return null; |
1226 | return group.GetPart(localID); | 1250 | } |
1251 | finally | ||
1252 | { | ||
1253 | if (entered) | ||
1254 | m_scenePartsLock.ExitReadLock(); | ||
1255 | } | ||
1227 | } | 1256 | } |
1228 | |||
1229 | /// <summary> | 1257 | /// <summary> |
1230 | /// Get a prim by name from the scene (will return the first | 1258 | /// Get a part contained in this scene. |
1231 | /// found, if there are more than one prim with the same name) | ||
1232 | /// </summary> | 1259 | /// </summary> |
1233 | /// <param name="name"></param> | 1260 | /// <param name="fullID"></param> |
1234 | /// <returns>null if the part was not found</returns> | 1261 | /// <returns>null if the part was not found</returns> |
1235 | protected internal SceneObjectPart GetSceneObjectPart(string name) | 1262 | protected internal SceneObjectPart GetSceneObjectPart(UUID fullID) |
1236 | { | 1263 | { |
1237 | SceneObjectPart sop = null; | 1264 | bool entered = false; |
1238 | 1265 | try | |
1239 | Entities.Find( | 1266 | { |
1240 | delegate(EntityBase entity) | 1267 | try { } |
1268 | finally | ||
1241 | { | 1269 | { |
1242 | if (entity is SceneObjectGroup) | 1270 | m_scenePartsLock.EnterReadLock(); |
1243 | { | 1271 | entered = true; |
1244 | foreach (SceneObjectPart p in ((SceneObjectGroup)entity).Parts) | ||
1245 | { | ||
1246 | if (p.Name == name) | ||
1247 | { | ||
1248 | sop = p; | ||
1249 | return true; | ||
1250 | } | ||
1251 | } | ||
1252 | } | ||
1253 | |||
1254 | return false; | ||
1255 | } | 1272 | } |
1256 | ); | 1273 | SceneObjectPart sop; |
1257 | 1274 | if (m_scenePartsByID.TryGetValue(fullID, out sop)) | |
1258 | return sop; | 1275 | { |
1276 | if (sop.ParentGroup == null || sop.ParentGroup.IsDeleted) | ||
1277 | return null; | ||
1278 | return sop; | ||
1279 | } | ||
1280 | return null; | ||
1281 | } | ||
1282 | finally | ||
1283 | { | ||
1284 | if (entered) | ||
1285 | m_scenePartsLock.ExitReadLock(); | ||
1286 | } | ||
1259 | } | 1287 | } |
1260 | 1288 | ||
1261 | /// <summary> | 1289 | /// <summary> |
1262 | /// Get a part contained in this scene. | 1290 | /// Get a prim by name from the scene (will return the first |
1291 | /// found, if there are more than one prim with the same name) | ||
1263 | /// </summary> | 1292 | /// </summary> |
1264 | /// <param name="fullID"></param> | 1293 | /// <param name="name"></param> |
1265 | /// <returns>null if the part was not found</returns> | 1294 | /// <returns>null if the part was not found</returns> |
1266 | protected internal SceneObjectPart GetSceneObjectPart(UUID fullID) | 1295 | protected internal SceneObjectPart GetSceneObjectPart(string name) |
1267 | { | 1296 | { |
1268 | SceneObjectGroup group = GetGroupByPrim(fullID); | 1297 | SceneObjectPart[] parts = GetPartsArray(); |
1269 | if (group == null) | 1298 | int len = parts.Length; |
1270 | return null; | 1299 | SceneObjectPart sop; |
1271 | return group.GetPart(fullID); | 1300 | for (int i = 0; i < len; ++i) |
1301 | { | ||
1302 | sop = parts[i]; | ||
1303 | if (sop.ParentGroup == null || sop.ParentGroup.IsDeleted) | ||
1304 | continue; | ||
1305 | if (sop.Name == name) | ||
1306 | return sop; | ||
1307 | } | ||
1308 | return null; | ||
1272 | } | 1309 | } |
1273 | 1310 | ||
1311 | protected internal SceneObjectPart[] GetPartsArray() | ||
1312 | { | ||
1313 | bool entered = false; | ||
1314 | try | ||
1315 | { | ||
1316 | try { } | ||
1317 | finally | ||
1318 | { | ||
1319 | m_scenePartsLock.EnterWriteLock(); | ||
1320 | entered = true; | ||
1321 | } | ||
1322 | if(m_scenePartsArray == null) | ||
1323 | { | ||
1324 | m_scenePartsArray = new SceneObjectPart[m_scenePartsByID.Count]; | ||
1325 | m_scenePartsByID.Values.CopyTo(m_scenePartsArray, 0); | ||
1326 | } | ||
1327 | return m_scenePartsArray; | ||
1328 | } | ||
1329 | finally | ||
1330 | { | ||
1331 | if(entered) | ||
1332 | m_scenePartsLock.ExitWriteLock(); | ||
1333 | } | ||
1334 | } | ||
1274 | /// <summary> | 1335 | /// <summary> |
1275 | /// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over | 1336 | /// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over |
1276 | /// it | 1337 | /// it |
@@ -1294,32 +1355,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
1294 | } | 1355 | } |
1295 | } | 1356 | } |
1296 | 1357 | ||
1297 | protected internal UUID ConvertLocalIDToFullID(uint localID) | ||
1298 | { | ||
1299 | SceneObjectGroup group = GetGroupByPrim(localID); | ||
1300 | if (group != null) | ||
1301 | return group.GetPartsFullID(localID); | ||
1302 | else | ||
1303 | return UUID.Zero; | ||
1304 | } | ||
1305 | |||
1306 | /// <summary> | 1358 | /// <summary> |
1307 | /// Performs action once on all scene object groups. | 1359 | /// Performs action once on all scene object groups. |
1308 | /// </summary> | 1360 | /// </summary> |
1309 | /// <param name="action"></param> | 1361 | /// <param name="action"></param> |
1310 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) | 1362 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) |
1311 | { | 1363 | { |
1312 | foreach (SceneObjectGroup obj in GetSceneObjectGroups()) | 1364 | EntityBase[] entities = Entities.GetEntities(); |
1365 | int len = entities.Length; | ||
1366 | EntityBase entity; | ||
1367 | for (int i = 0; i < len; ++i) | ||
1313 | { | 1368 | { |
1314 | try | 1369 | entity = entities[i]; |
1315 | { | 1370 | if (entity is SceneObjectGroup) |
1316 | action(obj); | ||
1317 | } | ||
1318 | catch (Exception e) | ||
1319 | { | 1371 | { |
1320 | // Catch it and move on. This includes situations where objlist has inconsistent info | 1372 | try |
1321 | m_log.WarnFormat( | 1373 | { |
1322 | "[SCENEGRAPH]: Problem processing action in ForEachSOG: {0} {1}", e.Message, e.StackTrace); | 1374 | action((SceneObjectGroup)entity); |
1375 | } | ||
1376 | catch (Exception e) | ||
1377 | { | ||
1378 | // Catch it and move on. This includes situations where objlist has inconsistent info | ||
1379 | m_log.WarnFormat( | ||
1380 | "[SCENEGRAPH]: Problem processing action in ForEachSOG: {0} {1}", e.Message, e.StackTrace); | ||
1381 | } | ||
1323 | } | 1382 | } |
1324 | } | 1383 | } |
1325 | } | 1384 | } |
@@ -1664,7 +1723,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1664 | } | 1723 | } |
1665 | else | 1724 | else |
1666 | { | 1725 | { |
1667 | SceneObjectPart part = GetSceneObjectPart(localID); | 1726 | SceneObjectPart part = group.GetPart(localID); |
1668 | if (part != null) | 1727 | if (part != null) |
1669 | { | 1728 | { |
1670 | part.UpdateExtraPhysics(PhysData); | 1729 | part.UpdateExtraPhysics(PhysData); |
@@ -2113,24 +2172,36 @@ namespace OpenSim.Region.Framework.Scenes | |||
2113 | } | 2172 | } |
2114 | 2173 | ||
2115 | // FIXME: This section needs to be refactored so that it just calls AddSceneObject() | 2174 | // FIXME: This section needs to be refactored so that it just calls AddSceneObject() |
2116 | Entities.Add(copy); | 2175 | bool entered = false; |
2176 | try | ||
2177 | { | ||
2178 | try { } | ||
2179 | finally | ||
2180 | { | ||
2181 | m_scenePartsLock.EnterWriteLock(); | ||
2182 | entered = true; | ||
2183 | } | ||
2117 | 2184 | ||
2118 | lock (SceneObjectGroupsByFullID) | 2185 | Entities.Add(copy); |
2119 | SceneObjectGroupsByFullID[copy.UUID] = copy; | 2186 | m_scenePartsArray = null; |
2187 | foreach (SceneObjectPart part in parts) | ||
2188 | { | ||
2189 | if (part.GetPrimType() == PrimType.SCULPT) | ||
2190 | m_numMesh++; | ||
2191 | else | ||
2192 | m_numPrim++; | ||
2120 | 2193 | ||
2121 | foreach (SceneObjectPart part in parts) | 2194 | m_scenePartsByID[part.UUID] = part; |
2195 | m_scenePartsByLocalID[part.LocalId] = part; | ||
2196 | } | ||
2197 | } | ||
2198 | finally | ||
2122 | { | 2199 | { |
2123 | if (part.GetPrimType() == PrimType.SCULPT) | 2200 | if(entered) |
2124 | m_numMesh++; | 2201 | m_scenePartsLock.ExitWriteLock(); |
2125 | else | ||
2126 | m_numPrim++; | ||
2127 | |||
2128 | lock (SceneObjectGroupsByFullPartID) | ||
2129 | SceneObjectGroupsByFullPartID[part.UUID] = copy; | ||
2130 | lock (SceneObjectGroupsByLocalPartID) | ||
2131 | SceneObjectGroupsByLocalPartID[part.LocalId] = copy; | ||
2132 | } | 2202 | } |
2133 | 2203 | ||
2204 | |||
2134 | // PROBABLE END OF FIXME | 2205 | // PROBABLE END OF FIXME |
2135 | 2206 | ||
2136 | copy.IsSelected = createSelected; | 2207 | copy.IsSelected = createSelected; |