aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneGraph.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs94
1 files changed, 79 insertions, 15 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index a02f614..5fbc658 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Region.Framework.Scenes
68 68
69 #region Fields 69 #region Fields
70 70
71 protected object m_presenceLock = new object(); 71 protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock = new OpenMetaverse.ReaderWriterLockSlim();
72 protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); 72 protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>();
73 protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); 73 protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>();
74 74
@@ -133,13 +133,18 @@ namespace OpenSim.Region.Framework.Scenes
133 133
134 protected internal void Close() 134 protected internal void Close()
135 { 135 {
136 lock (m_presenceLock) 136 m_scenePresencesLock.EnterWriteLock();
137 try
137 { 138 {
138 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); 139 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>();
139 List<ScenePresence> newlist = new List<ScenePresence>(); 140 List<ScenePresence> newlist = new List<ScenePresence>();
140 m_scenePresenceMap = newmap; 141 m_scenePresenceMap = newmap;
141 m_scenePresenceArray = newlist; 142 m_scenePresenceArray = newlist;
142 } 143 }
144 finally
145 {
146 m_scenePresencesLock.ExitWriteLock();
147 }
143 148
144 lock (m_dictionary_lock) 149 lock (m_dictionary_lock)
145 { 150 {
@@ -228,6 +233,30 @@ namespace OpenSim.Region.Framework.Scenes
228 protected internal bool AddRestoredSceneObject( 233 protected internal bool AddRestoredSceneObject(
229 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) 234 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
230 { 235 {
236 // KF: Check for out-of-region, move inside and make static.
237 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
238 sceneObject.RootPart.GroupPosition.Y,
239 sceneObject.RootPart.GroupPosition.Z);
240 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 ||
241 npos.X > Constants.RegionSize ||
242 npos.Y > Constants.RegionSize))
243 {
244 if (npos.X < 0.0) npos.X = 1.0f;
245 if (npos.Y < 0.0) npos.Y = 1.0f;
246 if (npos.Z < 0.0) npos.Z = 0.0f;
247 if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
248 if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
249
250 foreach (SceneObjectPart part in sceneObject.Children.Values)
251 {
252 part.GroupPosition = npos;
253 }
254 sceneObject.RootPart.Velocity = Vector3.Zero;
255 sceneObject.RootPart.AngularVelocity = Vector3.Zero;
256 sceneObject.RootPart.Acceleration = Vector3.Zero;
257 sceneObject.RootPart.Velocity = Vector3.Zero;
258 }
259
231 if (!alreadyPersisted) 260 if (!alreadyPersisted)
232 { 261 {
233 sceneObject.ForceInventoryPersistence(); 262 sceneObject.ForceInventoryPersistence();
@@ -524,7 +553,8 @@ namespace OpenSim.Region.Framework.Scenes
524 553
525 Entities[presence.UUID] = presence; 554 Entities[presence.UUID] = presence;
526 555
527 lock (m_presenceLock) 556 m_scenePresencesLock.EnterWriteLock();
557 try
528 { 558 {
529 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 559 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
530 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 560 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -548,6 +578,10 @@ namespace OpenSim.Region.Framework.Scenes
548 m_scenePresenceMap = newmap; 578 m_scenePresenceMap = newmap;
549 m_scenePresenceArray = newlist; 579 m_scenePresenceArray = newlist;
550 } 580 }
581 finally
582 {
583 m_scenePresencesLock.ExitWriteLock();
584 }
551 } 585 }
552 586
553 /// <summary> 587 /// <summary>
@@ -562,7 +596,8 @@ namespace OpenSim.Region.Framework.Scenes
562 agentID); 596 agentID);
563 } 597 }
564 598
565 lock (m_presenceLock) 599 m_scenePresencesLock.EnterWriteLock();
600 try
566 { 601 {
567 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 602 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
568 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 603 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -583,6 +618,10 @@ namespace OpenSim.Region.Framework.Scenes
583 m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 618 m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
584 } 619 }
585 } 620 }
621 finally
622 {
623 m_scenePresencesLock.ExitWriteLock();
624 }
586 } 625 }
587 626
588 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 627 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -1460,10 +1499,13 @@ namespace OpenSim.Region.Framework.Scenes
1460 /// <param name="childPrims"></param> 1499 /// <param name="childPrims"></param>
1461 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1500 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1462 { 1501 {
1502 SceneObjectGroup parentGroup = root.ParentGroup;
1503 if (parentGroup == null) return;
1463 Monitor.Enter(m_updateLock); 1504 Monitor.Enter(m_updateLock);
1505
1464 try 1506 try
1465 { 1507 {
1466 SceneObjectGroup parentGroup = root.ParentGroup; 1508 parentGroup.areUpdatesSuspended = true;
1467 1509
1468 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1510 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1469 if (parentGroup != null) 1511 if (parentGroup != null)
@@ -1502,12 +1544,12 @@ namespace OpenSim.Region.Framework.Scenes
1502 // occur on link to invoke this elsewhere (such as object selection) 1544 // occur on link to invoke this elsewhere (such as object selection)
1503 parentGroup.RootPart.CreateSelected = true; 1545 parentGroup.RootPart.CreateSelected = true;
1504 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1546 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1505 parentGroup.HasGroupChanged = true;
1506 parentGroup.ScheduleGroupForFullUpdate();
1507
1508 } 1547 }
1509 finally 1548 finally
1510 { 1549 {
1550 parentGroup.areUpdatesSuspended = false;
1551 parentGroup.HasGroupChanged = true;
1552 parentGroup.ScheduleGroupForFullUpdate();
1511 Monitor.Exit(m_updateLock); 1553 Monitor.Exit(m_updateLock);
1512 } 1554 }
1513 } 1555 }
@@ -1544,11 +1586,22 @@ namespace OpenSim.Region.Framework.Scenes
1544 } 1586 }
1545 } 1587 }
1546 1588
1547 foreach (SceneObjectPart child in childParts) 1589 if (childParts.Count > 0)
1548 { 1590 {
1549 // Unlink all child parts from their groups 1591 try
1550 // 1592 {
1551 child.ParentGroup.DelinkFromGroup(child, true); 1593 childParts[0].ParentGroup.areUpdatesSuspended = true;
1594 foreach (SceneObjectPart child in childParts)
1595 {
1596 // Unlink all child parts from their groups
1597 //
1598 child.ParentGroup.DelinkFromGroup(child, true);
1599 }
1600 }
1601 finally
1602 {
1603 childParts[0].ParentGroup.areUpdatesSuspended = false;
1604 }
1552 } 1605 }
1553 1606
1554 foreach (SceneObjectPart root in rootParts) 1607 foreach (SceneObjectPart root in rootParts)
@@ -1572,10 +1625,21 @@ namespace OpenSim.Region.Framework.Scenes
1572 if (numChildren > 1) 1625 if (numChildren > 1)
1573 sendEventsToRemainder = false; 1626 sendEventsToRemainder = false;
1574 1627
1575 foreach (SceneObjectPart p in newSet) 1628 if (newSet.Count > 0)
1576 { 1629 {
1577 if (p != group.RootPart) 1630 try
1578 group.DelinkFromGroup(p, sendEventsToRemainder); 1631 {
1632 newSet[0].ParentGroup.areUpdatesSuspended = true;
1633 foreach (SceneObjectPart p in newSet)
1634 {
1635 if (p != group.RootPart)
1636 group.DelinkFromGroup(p, sendEventsToRemainder);
1637 }
1638 }
1639 finally
1640 {
1641 newSet[0].ParentGroup.areUpdatesSuspended = false;
1642 }
1579 } 1643 }
1580 1644
1581 // If there is more than one prim remaining, we 1645 // If there is more than one prim remaining, we