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 673674d..80f9114 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 {
@@ -269,6 +274,30 @@ namespace OpenSim.Region.Framework.Scenes
269 protected internal bool AddRestoredSceneObject( 274 protected internal bool AddRestoredSceneObject(
270 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 275 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
271 { 276 {
277 // KF: Check for out-of-region, move inside and make static.
278 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
279 sceneObject.RootPart.GroupPosition.Y,
280 sceneObject.RootPart.GroupPosition.Z);
281 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 ||
282 npos.X > Constants.RegionSize ||
283 npos.Y > Constants.RegionSize))
284 {
285 if (npos.X < 0.0) npos.X = 1.0f;
286 if (npos.Y < 0.0) npos.Y = 1.0f;
287 if (npos.Z < 0.0) npos.Z = 0.0f;
288 if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
289 if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
290
291 foreach (SceneObjectPart part in sceneObject.Children.Values)
292 {
293 part.GroupPosition = npos;
294 }
295 sceneObject.RootPart.Velocity = Vector3.Zero;
296 sceneObject.RootPart.AngularVelocity = Vector3.Zero;
297 sceneObject.RootPart.Acceleration = Vector3.Zero;
298 sceneObject.RootPart.Velocity = Vector3.Zero;
299 }
300
272 if (!alreadyPersisted) 301 if (!alreadyPersisted)
273 { 302 {
274 sceneObject.ForceInventoryPersistence(); 303 sceneObject.ForceInventoryPersistence();
@@ -565,7 +594,8 @@ namespace OpenSim.Region.Framework.Scenes
565 594
566 Entities[presence.UUID] = presence; 595 Entities[presence.UUID] = presence;
567 596
568 lock (m_presenceLock) 597 m_scenePresencesLock.EnterWriteLock();
598 try
569 { 599 {
570 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 600 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
571 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 601 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -589,6 +619,10 @@ namespace OpenSim.Region.Framework.Scenes
589 m_scenePresenceMap = newmap; 619 m_scenePresenceMap = newmap;
590 m_scenePresenceArray = newlist; 620 m_scenePresenceArray = newlist;
591 } 621 }
622 finally
623 {
624 m_scenePresencesLock.ExitWriteLock();
625 }
592 } 626 }
593 627
594 /// <summary> 628 /// <summary>
@@ -603,7 +637,8 @@ namespace OpenSim.Region.Framework.Scenes
603 agentID); 637 agentID);
604 } 638 }
605 639
606 lock (m_presenceLock) 640 m_scenePresencesLock.EnterWriteLock();
641 try
607 { 642 {
608 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 643 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
609 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 644 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -624,6 +659,10 @@ namespace OpenSim.Region.Framework.Scenes
624 m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 659 m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
625 } 660 }
626 } 661 }
662 finally
663 {
664 m_scenePresencesLock.ExitWriteLock();
665 }
627 } 666 }
628 667
629 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 668 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -1501,10 +1540,13 @@ namespace OpenSim.Region.Framework.Scenes
1501 /// <param name="childPrims"></param> 1540 /// <param name="childPrims"></param>
1502 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1541 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1503 { 1542 {
1543 SceneObjectGroup parentGroup = root.ParentGroup;
1544 if (parentGroup == null) return;
1504 Monitor.Enter(m_updateLock); 1545 Monitor.Enter(m_updateLock);
1546
1505 try 1547 try
1506 { 1548 {
1507 SceneObjectGroup parentGroup = root.ParentGroup; 1549 parentGroup.areUpdatesSuspended = true;
1508 1550
1509 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1551 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1510 if (parentGroup != null) 1552 if (parentGroup != null)
@@ -1543,12 +1585,12 @@ namespace OpenSim.Region.Framework.Scenes
1543 // occur on link to invoke this elsewhere (such as object selection) 1585 // occur on link to invoke this elsewhere (such as object selection)
1544 parentGroup.RootPart.CreateSelected = true; 1586 parentGroup.RootPart.CreateSelected = true;
1545 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1587 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1546 parentGroup.HasGroupChanged = true;
1547 parentGroup.ScheduleGroupForFullUpdate();
1548
1549 } 1588 }
1550 finally 1589 finally
1551 { 1590 {
1591 parentGroup.areUpdatesSuspended = false;
1592 parentGroup.HasGroupChanged = true;
1593 parentGroup.ScheduleGroupForFullUpdate();
1552 Monitor.Exit(m_updateLock); 1594 Monitor.Exit(m_updateLock);
1553 } 1595 }
1554 } 1596 }
@@ -1585,11 +1627,22 @@ namespace OpenSim.Region.Framework.Scenes
1585 } 1627 }
1586 } 1628 }
1587 1629
1588 foreach (SceneObjectPart child in childParts) 1630 if (childParts.Count > 0)
1589 { 1631 {
1590 // Unlink all child parts from their groups 1632 try
1591 // 1633 {
1592 child.ParentGroup.DelinkFromGroup(child, true); 1634 childParts[0].ParentGroup.areUpdatesSuspended = true;
1635 foreach (SceneObjectPart child in childParts)
1636 {
1637 // Unlink all child parts from their groups
1638 //
1639 child.ParentGroup.DelinkFromGroup(child, true);
1640 }
1641 }
1642 finally
1643 {
1644 childParts[0].ParentGroup.areUpdatesSuspended = false;
1645 }
1593 } 1646 }
1594 1647
1595 foreach (SceneObjectPart root in rootParts) 1648 foreach (SceneObjectPart root in rootParts)
@@ -1613,10 +1666,21 @@ namespace OpenSim.Region.Framework.Scenes
1613 if (numChildren > 1) 1666 if (numChildren > 1)
1614 sendEventsToRemainder = false; 1667 sendEventsToRemainder = false;
1615 1668
1616 foreach (SceneObjectPart p in newSet) 1669 if (newSet.Count > 0)
1617 { 1670 {
1618 if (p != group.RootPart) 1671 try
1619 group.DelinkFromGroup(p, sendEventsToRemainder); 1672 {
1673 newSet[0].ParentGroup.areUpdatesSuspended = true;
1674 foreach (SceneObjectPart p in newSet)
1675 {
1676 if (p != group.RootPart)
1677 group.DelinkFromGroup(p, sendEventsToRemainder);
1678 }
1679 }
1680 finally
1681 {
1682 newSet[0].ParentGroup.areUpdatesSuspended = false;
1683 }
1620 } 1684 }
1621 1685
1622 // If there is more than one prim remaining, we 1686 // If there is more than one prim remaining, we