From e237e1b2fa444b0bf0077036c9436f919e344e2b Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 4 Apr 2017 19:27:45 +0100 Subject: [PATCH] add LSL_Integer osGetLinkNumber(LSL_String name). uses a cache for the string to linknumber map, cache invalidations may still be missing :( --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 + .../Framework/Scenes/SceneObjectGroup.cs | 61 +++++++++++++++++++ .../Shared/Api/Implementation/OSSL_Api.cs | 9 +++ .../Shared/Api/Runtime/OSSL_Stub.cs | 5 ++ 4 files changed, 77 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 49e98e7d3a..6b29ec12b5 100755 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1985,6 +1985,7 @@ namespace OpenSim.Region.Framework.Scenes { newRoot.TriggerScriptChangedEvent(Changed.LINK); newRoot.ParentGroup.HasGroupChanged = true; + newRoot.ParentGroup.InvalidatePartsLinkMaps(); newRoot.ParentGroup.ScheduleGroupForFullUpdate(); } } @@ -2001,6 +2002,7 @@ namespace OpenSim.Region.Framework.Scenes // from the database. They will be rewritten immediately, // minus the rows for the unlinked child prims. m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID); + g.InvalidatePartsLinkMaps(); g.TriggerScriptChangedEvent(Changed.LINK); g.HasGroupChanged = true; // Persist g.ScheduleGroupForFullUpdate(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index a0d7bfd678..b410b74fb8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2004,6 +2004,7 @@ namespace OpenSim.Region.Framework.Scenes if (part.LinkNum == 2) RootPart.LinkNum = 1; + InvalidatePartsLinkMaps(); } /// @@ -2560,6 +2561,7 @@ namespace OpenSim.Region.Framework.Scenes dupe.ScheduleGroupForFullUpdate(); } + dupe.InvalidatePartsLinkMaps(); m_dupeInProgress = false; return dupe; } @@ -3321,6 +3323,7 @@ namespace OpenSim.Region.Framework.Scenes ResetChildPrimPhysicsPositions(); InvalidBoundsRadius(); + InvalidatePartsLinkMaps(); if (m_rootPart.PhysActor != null) m_rootPart.PhysActor.Building = false; @@ -3477,6 +3480,7 @@ namespace OpenSim.Region.Framework.Scenes objectGroup.HasGroupChangedDueToDelink = true; InvalidBoundsRadius(); + InvalidatePartsLinkMaps(); objectGroup.AggregatePerms(); if (sendEvents) @@ -5333,6 +5337,63 @@ namespace OpenSim.Region.Framework.Scenes m_PlaySoundSlavePrims.Clear(); m_LoopSoundMasterPrim = null; m_targets.Clear(); + m_partsNameToLinkMap.Clear(); + } + + Dictionary m_partsNameToLinkMap = new Dictionary(); + + // this scales bad but so does GetLinkNumPart + public int GetLinkNumber(string name) + { + if(String.IsNullOrEmpty(name) || name == "Object") + return -1; + + lock(m_partsNameToLinkMap) + { + if(m_partsNameToLinkMap.Count == 0) + { + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + { + string s = parts[i].Name; + if(String.IsNullOrEmpty(s) || s == "Object" || s == "Primitive") + continue; + + if(m_partsNameToLinkMap.ContainsKey(s)) + { + int ol = parts[i].LinkNum; + if(ol < m_partsNameToLinkMap[s]) + m_partsNameToLinkMap[s] = ol; + } + else + m_partsNameToLinkMap[s] = parts[i].LinkNum; + } + } + + if(m_partsNameToLinkMap.ContainsKey(name)) + return m_partsNameToLinkMap[name]; + } + + if(m_sittingAvatars.Count > 0) + { + int j = m_parts.Count; + if(j > 1) + j++; + ScenePresence[] avs = m_sittingAvatars.ToArray(); + for (int i = 0; i < avs.Length; i++, j++) + { + if (avs[i].Name == name) + return j; + } + } + + return -1; + } + + public void InvalidatePartsLinkMaps() + { + lock(m_partsNameToLinkMap) + m_partsNameToLinkMap.Clear(); } #endregion diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index b50ae28827..0275cf4985 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -4663,5 +4663,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api sog.TeleportObject(myid, targetPos, rotation, flags); // a delay here may break vehicles } + + public LSL_Integer osGetLinkNumber(LSL_String name) + { + m_host.AddScriptLPS(1); + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return -1; + return sog.GetLinkNumber(name); + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 3c8e02da6f..7c0862845b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -1144,5 +1144,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { m_OSSL_Functions.osTeleportObject(objectUUID, targetPos, targetrotation, flags); } + + public LSL_Integer osGetLinkNumber(LSL_String name) + { + return m_OSSL_Functions.osGetLinkNumber(name); + } } }