From 6ac9c9c97277e510cbe7eb908f3cf7883a01c1c3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 3 Apr 2014 01:14:39 +0100 Subject: refactor: Use m_sittingAvatars to maintain the list of sitting avatars instead of two independent structures that do exactly the same thing m_sittingAvatars code also already properly handles locking to avoid races. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 54 +++------------------- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 28 +++++------ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 12 ++--- .../Scenes/Tests/SceneObjectCrossingTests.cs | 2 - .../Scenes/Tests/ScenePresenceSitTests.cs | 8 ++-- .../Shared/Api/Implementation/LSL_Api.cs | 19 ++++---- 6 files changed, 36 insertions(+), 87 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 7ede725..529bc9f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -121,7 +121,6 @@ namespace OpenSim.Region.Framework.Scenes private bool m_hasGroupChanged = false; private long timeFirstChanged; private long timeLastChanged; - private List m_linkedAvatars = new List(); /// /// This indicates whether the object has changed such that it needs to be repersisted to permenant storage @@ -484,7 +483,7 @@ namespace OpenSim.Region.Framework.Scenes m_rootPart.KeyframeMotion.StartCrossingCheck(); bool canCross = true; - foreach (ScenePresence av in m_linkedAvatars) + foreach (ScenePresence av in GetSittingAvatars()) { // We need to cross these agents. First, let's find // out if any of them can't cross for some reason. @@ -511,7 +510,7 @@ namespace OpenSim.Region.Framework.Scenes List avsToCross = new List(); - foreach (ScenePresence av in m_linkedAvatars) + foreach (ScenePresence av in GetSittingAvatars()) { avtocrossInfo avinfo = new avtocrossInfo(); SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID); @@ -838,7 +837,7 @@ namespace OpenSim.Region.Framework.Scenes /// No avatar should appear more than once in this list. /// Do not manipulate this list directly - use the Add/Remove sitting avatar methods on SceneObjectPart. /// - protected internal List m_sittingAvatars = new List(); + protected internal List m_sittingAvatars = new List(); #endregion @@ -1281,46 +1280,6 @@ namespace OpenSim.Region.Framework.Scenes part.ParentID = m_rootPart.LocalId; part.ClearUndoState(); } - /// - /// Add the avatar to this linkset (avatar is sat). - /// - /// - public void AddAvatar(UUID agentID) - { - ScenePresence presence; - if (m_scene.TryGetScenePresence(agentID, out presence)) - { - if (!m_linkedAvatars.Contains(presence)) - { - m_linkedAvatars.Add(presence); - } - } - } - - /// - /// Delete the avatar from this linkset (avatar is unsat). - /// - /// - public void DeleteAvatar(UUID agentID) - { - ScenePresence presence; - if (m_scene.TryGetScenePresence(agentID, out presence)) - { - if (m_linkedAvatars.Contains(presence)) - { - m_linkedAvatars.Remove(presence); - } - } - } - - /// - /// Returns the list of linked presences (avatars sat on this group) - /// - /// - public List GetLinkedAvatars() - { - return m_linkedAvatars; - } public ushort GetTimeDilation() { @@ -1714,8 +1673,7 @@ namespace OpenSim.Region.Framework.Scenes dupe.Backup = false; dupe.m_parts = new MapAndArray(); - dupe.m_sittingAvatars = new List(); - dupe.m_linkedAvatars = new List(); + dupe.m_sittingAvatars = new List(); dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; @@ -3833,10 +3791,10 @@ namespace OpenSim.Region.Framework.Scenes /// down after it move one place down the list. /// /// A list of the sitting avatars. Returns an empty list if there are no sitting avatars. - public List GetSittingAvatars() + public List GetSittingAvatars() { lock (m_sittingAvatars) - return new List(m_sittingAvatars); + return new List(m_sittingAvatars); } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index c06175e..43fec35 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1299,7 +1299,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// null if there are no sitting avatars. This is to save us create a hashset for every prim in a scene. /// - private HashSet m_sittingAvatars; + private HashSet m_sittingAvatars; public virtual UUID RegionID { @@ -1803,7 +1803,7 @@ namespace OpenSim.Region.Framework.Scenes Array.Copy(Shape.ExtraParams, extraP, extraP.Length); dupe.Shape.ExtraParams = extraP; - dupe.m_sittingAvatars = new HashSet(); + dupe.m_sittingAvatars = new HashSet(); // safeguard actual copy is done in sog.copy dupe.KeyframeMotion = null; @@ -4917,19 +4917,19 @@ namespace OpenSim.Region.Framework.Scenes /// true if the avatar was not already recorded, false otherwise. /// /// - protected internal bool AddSittingAvatar(UUID avatarId) + protected internal bool AddSittingAvatar(ScenePresence sp) { lock (ParentGroup.m_sittingAvatars) { if (IsSitTargetSet && SitTargetAvatar == UUID.Zero) - SitTargetAvatar = avatarId; + SitTargetAvatar = sp.UUID; if (m_sittingAvatars == null) - m_sittingAvatars = new HashSet(); + m_sittingAvatars = new HashSet(); - if (m_sittingAvatars.Add(avatarId)) + if (m_sittingAvatars.Add(sp)) { - ParentGroup.m_sittingAvatars.Add(avatarId); + ParentGroup.m_sittingAvatars.Add(sp); return true; } @@ -4946,22 +4946,22 @@ namespace OpenSim.Region.Framework.Scenes /// true if the avatar was present and removed, false if it was not present. /// /// - protected internal bool RemoveSittingAvatar(UUID avatarId) + protected internal bool RemoveSittingAvatar(ScenePresence sp) { lock (ParentGroup.m_sittingAvatars) { - if (SitTargetAvatar == avatarId) + if (SitTargetAvatar == sp.UUID) SitTargetAvatar = UUID.Zero; if (m_sittingAvatars == null) return false; - if (m_sittingAvatars.Remove(avatarId)) + if (m_sittingAvatars.Remove(sp)) { if (m_sittingAvatars.Count == 0) m_sittingAvatars = null; - ParentGroup.m_sittingAvatars.Remove(avatarId); + ParentGroup.m_sittingAvatars.Remove(sp); return true; } @@ -4975,14 +4975,14 @@ namespace OpenSim.Region.Framework.Scenes /// /// This applies to all sitting avatars whether there is a sit target set or not. /// A hashset of the sitting avatars. Returns null if there are no sitting avatars. - public HashSet GetSittingAvatars() + public HashSet GetSittingAvatars() { lock (ParentGroup.m_sittingAvatars) { if (m_sittingAvatars == null) return null; else - return new HashSet(m_sittingAvatars); + return new HashSet(m_sittingAvatars); } } @@ -5002,4 +5002,4 @@ namespace OpenSim.Region.Framework.Scenes } } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 6386a45..3d1c58c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1022,8 +1022,7 @@ namespace OpenSim.Region.Framework.Scenes } else { - part.ParentGroup.AddAvatar(UUID); - part.AddSittingAvatar(UUID); + part.AddSittingAvatar(this); if (part.SitTargetPosition != Vector3.Zero) part.SitTargetAvatar = UUID; // ParentPosition = part.GetWorldPosition(); @@ -2522,7 +2521,6 @@ namespace OpenSim.Region.Framework.Scenes } } - part.ParentGroup.DeleteAvatar(UUID); Vector3 sitPartWorldPosition = part.GetWorldPosition(); ControllingClient.SendClearFollowCamProperties(part.ParentUUID); @@ -2578,7 +2576,7 @@ namespace OpenSim.Region.Framework.Scenes SendAvatarDataToAllAgents(); m_requestedSitTargetID = 0; - part.RemoveSittingAvatar(UUID); + part.RemoveSittingAvatar(this); part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); } @@ -2688,7 +2686,7 @@ namespace OpenSim.Region.Framework.Scenes Velocity = Vector3.Zero; - part.AddSittingAvatar(UUID); + part.AddSittingAvatar(this); cameraAtOffset = part.GetCameraAtOffset(); cameraEyeOffset = part.GetCameraEyeOffset(); @@ -2821,7 +2819,7 @@ namespace OpenSim.Region.Framework.Scenes Velocity = Vector3.Zero; - part.AddSittingAvatar(UUID); + part.AddSittingAvatar(this); Vector3 cameraAtOffset = part.GetCameraAtOffset(); Vector3 cameraEyeOffset = part.GetCameraEyeOffset(); @@ -2836,7 +2834,6 @@ namespace OpenSim.Region.Framework.Scenes m_pos = offset; m_requestedSitTargetID = 0; - part.ParentGroup.AddAvatar(UUID); ParentPart = part; ParentID = part.LocalId; @@ -2936,7 +2933,6 @@ namespace OpenSim.Region.Framework.Scenes // Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); } - part.ParentGroup.AddAvatar(UUID); ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID); ParentID = m_requestedSitTargetID; m_AngularVelocity = Vector3.Zero; diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs index d65b0b6..969f73d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs @@ -172,7 +172,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests so1PostCross = sceneB.GetSceneObjectGroup(so1Id); Assert.NotNull(so1PostCross); Assert.AreEqual(1, so1PostCross.GetSittingAvatarsCount()); - Assert.AreEqual(1, so1PostCross.GetLinkedAvatars().Count); } Vector3 so1PostCrossPos = so1PostCross.AbsolutePosition; @@ -198,7 +197,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests SceneObjectGroup so1PostReCross = sceneA.GetSceneObjectGroup(so1Id); Assert.NotNull(so1PostReCross); Assert.AreEqual(1, so1PostReCross.GetSittingAvatarsCount()); - Assert.AreEqual(1, so1PostReCross.GetLinkedAvatars().Count); } } diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs index 0911f00..dcdec5c 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs @@ -93,9 +93,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1)); - HashSet sittingAvatars = part.GetSittingAvatars(); + HashSet sittingAvatars = part.GetSittingAvatars(); Assert.That(sittingAvatars.Count, Is.EqualTo(1)); - Assert.That(sittingAvatars.Contains(m_sp.UUID)); + Assert.That(sittingAvatars.Contains(m_sp)); Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId)); } @@ -151,9 +151,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(m_sp.PhysicsActor, Is.Null); Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1)); - HashSet sittingAvatars = part.GetSittingAvatars(); + HashSet sittingAvatars = part.GetSittingAvatars(); Assert.That(sittingAvatars.Count, Is.EqualTo(1)); - Assert.That(sittingAvatars.Contains(m_sp.UUID)); + Assert.That(sittingAvatars.Contains(m_sp)); m_sp.StandUp(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 86509aa..e38394a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -335,14 +335,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } int actualPrimCount = part.ParentGroup.PrimCount; - List sittingAvatarIds = part.ParentGroup.GetSittingAvatars(); - int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count; + List sittingAvatars = part.ParentGroup.GetSittingAvatars(); + int adjustedPrimCount = actualPrimCount + sittingAvatars.Count; // Special case for a single prim. In this case the linknum is zero. However, this will not match a single // prim that has any avatars sat upon it (in which case the root prim is link 1). if (linknum == 0) { - if (actualPrimCount == 1 && sittingAvatarIds.Count == 0) + if (actualPrimCount == 1 && sittingAvatars.Count == 0) return part; return null; @@ -351,7 +351,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // here we must match 1 (ScriptBaseClass.LINK_ROOT). else if (linknum == ScriptBaseClass.LINK_ROOT && actualPrimCount == 1) { - if (sittingAvatarIds.Count > 0) + if (sittingAvatars.Count > 0) return part.ParentGroup.RootPart; else return null; @@ -364,11 +364,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]); - if (sp != null) - return sp; - else - return null; + return sittingAvatars[linknum - actualPrimCount - 1]; } } else @@ -3619,7 +3615,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - if (m_host.ParentGroup.GetSittingAvatars().Contains(agentID)) + if (m_host.ParentGroup.GetSittingAvatars().SingleOrDefault(sp => sp.UUID == agentID) != null) { // When agent is sitting, certain permissions are implicit if requested from sitting agent implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | @@ -3651,10 +3647,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } ScenePresence presence = World.GetScenePresence(agentID); + if (presence != null) { // If permissions are being requested from an NPC and were not implicitly granted above then - // auto grant all reuqested permissions if the script is owned by the NPC or the NPCs owner + // auto grant all requested permissions if the script is owned by the NPC or the NPCs owner INPCModule npcModule = World.RequestModuleInterface(); if (npcModule != null && npcModule.IsNPC(agentID, World)) { -- cgit v1.1