From e3dac1292ef000daadda3e264354d8df0fc77c22 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 29 May 2010 02:10:34 -0700 Subject: Implement suspended updates - When an operation is occurring on lots of prims in a single group, don't schedule any updates until the operation has completed. This makes things like llSetAlpha(LINK_SET,0.0,ALL_SIDES); a *lot* faster, more efficient and less buggy, and also makes unlinking a lot better. Linking is still treacherous.. this needs to be analysed. --- OpenSim/Region/Framework/ModuleLoader.cs | 3 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 47 ++++++-- .../Region/Framework/Scenes/SceneObjectGroup.cs | 17 +++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 8 +- .../Shared/Api/Implementation/LSL_Api.cs | 132 +++++++++++++++++---- 5 files changed, 168 insertions(+), 39 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/ModuleLoader.cs b/OpenSim/Region/Framework/ModuleLoader.cs index 23be9c2..69ba2042 100644 --- a/OpenSim/Region/Framework/ModuleLoader.cs +++ b/OpenSim/Region/Framework/ModuleLoader.cs @@ -226,7 +226,8 @@ namespace OpenSim.Region.Framework "[MODULES]: Could not load types for [{0}]. Exception {1}", pluginAssembly.FullName, e); // justincc: Right now this is fatal to really get the user's attention - throw e; + // TomMeta: WTF? No, how about we /don't/ throw a fatal exception when there's no need to? + //throw e; } } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index d4658ec..445c2c8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1499,10 +1499,13 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void LinkObjects(SceneObjectPart root, List children) { + SceneObjectGroup parentGroup = root.ParentGroup; + if (parentGroup == null) return; Monitor.Enter(m_updateLock); + try { - SceneObjectGroup parentGroup = root.ParentGroup; + parentGroup.areUpdatesSuspended = true; List childGroups = new List(); if (parentGroup != null) @@ -1541,12 +1544,12 @@ namespace OpenSim.Region.Framework.Scenes // occur on link to invoke this elsewhere (such as object selection) parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); parentGroup.TriggerScriptChangedEvent(Changed.LINK); - parentGroup.HasGroupChanged = true; - parentGroup.ScheduleGroupForFullUpdate(); - } finally { + parentGroup.areUpdatesSuspended = false; + parentGroup.HasGroupChanged = true; + parentGroup.ScheduleGroupForFullUpdate(); Monitor.Exit(m_updateLock); } } @@ -1583,11 +1586,22 @@ namespace OpenSim.Region.Framework.Scenes } } - foreach (SceneObjectPart child in childParts) + if (childParts.Count > 0) { - // Unlink all child parts from their groups - // - child.ParentGroup.DelinkFromGroup(child, true); + try + { + childParts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart child in childParts) + { + // Unlink all child parts from their groups + // + child.ParentGroup.DelinkFromGroup(child, true); + } + } + finally + { + childParts[0].ParentGroup.areUpdatesSuspended = false; + } } foreach (SceneObjectPart root in rootParts) @@ -1611,10 +1625,21 @@ namespace OpenSim.Region.Framework.Scenes if (numChildren > 1) sendEventsToRemainder = false; - foreach (SceneObjectPart p in newSet) + if (newSet.Count > 0) { - if (p != group.RootPart) - group.DelinkFromGroup(p, sendEventsToRemainder); + try + { + newSet[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart p in newSet) + { + if (p != group.RootPart) + group.DelinkFromGroup(p, sendEventsToRemainder); + } + } + finally + { + newSet[0].ParentGroup.areUpdatesSuspended = false; + } } // If there is more than one prim remaining, we diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index cee2be3..9ebb168 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -109,9 +109,26 @@ namespace OpenSim.Region.Framework.Scenes private long m_maxPersistTime = 0; private long m_minPersistTime = 0; private Random m_rand; + private bool m_suspendUpdates; private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim(); + public bool areUpdatesSuspended + { + get + { + return m_suspendUpdates; + } + set + { + m_suspendUpdates = value; + if (!value) + { + QueueForUpdateCheck(); + } + } + } + public void lockPartsForRead(bool locked) { if (locked) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index c84596b..6e73b65 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2724,7 +2724,10 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentGroup != null) { - m_parentGroup.QueueForUpdateCheck(); + if (!m_parentGroup.areUpdatesSuspended) + { + m_parentGroup.QueueForUpdateCheck(); + } } int timeNow = Util.UnixTimeSinceEpoch(); @@ -4450,8 +4453,9 @@ namespace OpenSim.Region.Framework.Scenes { m_shape.TextureEntry = textureEntry; TriggerScriptChangedEvent(Changed.TEXTURE); - + m_updateFlag = 1; ParentGroup.HasGroupChanged = true; + //This is madness.. //ParentGroup.ScheduleGroupForFullUpdate(); //This is sparta diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 68f6e7b..bb02fa3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1649,9 +1649,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); List parts = GetLinkParts(linknumber); - - foreach (SceneObjectPart part in parts) - SetAlpha(part, alpha, face); + if (parts.Count > 0) + { + try + { + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart part in parts) + SetAlpha(part, alpha, face); + } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } + } } protected void SetAlpha(SceneObjectPart part, double alpha, int face) @@ -1816,10 +1826,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); List parts = GetLinkParts(linknumber); - - foreach (SceneObjectPart part in parts) - SetTexture(part, texture, face); - + if (parts.Count > 0) + { + try + { + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart part in parts) + SetTexture(part, texture, face); + } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } + } ScriptSleep(200); } @@ -3661,9 +3680,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSetLinkColor(int linknumber, LSL_Vector color, int face) { List parts = GetLinkParts(linknumber); - - foreach (SceneObjectPart part in parts) - part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); + if (parts.Count > 0) + { + try + { + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart part in parts) + part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); + } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } + } } public void llCreateLink(string target, int parent) @@ -3776,10 +3805,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // Restructuring Multiple Prims. List parts = new List(parentPrim.Children.Values); parts.Remove(parentPrim.RootPart); - foreach (SceneObjectPart part in parts) + if (parts.Count > 0) { - parentPrim.DelinkFromGroup(part.LocalId, true); + try + { + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart part in parts) + { + parentPrim.DelinkFromGroup(part.LocalId, true); + } + } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } } + parentPrim.HasGroupChanged = true; parentPrim.ScheduleGroupForFullUpdate(); parentPrim.TriggerScriptChangedEvent(Changed.LINK); @@ -3788,11 +3829,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { SceneObjectPart newRoot = parts[0]; parts.Remove(newRoot); - foreach (SceneObjectPart part in parts) + + try { - part.UpdateFlag = 0; - newRoot.ParentGroup.LinkToGroup(part.ParentGroup); + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart part in parts) + { + part.UpdateFlag = 0; + newRoot.ParentGroup.LinkToGroup(part.ParentGroup); + } } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } + + newRoot.ParentGroup.HasGroupChanged = true; newRoot.ParentGroup.ScheduleGroupForFullUpdate(); } @@ -3818,11 +3870,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api List parts = new List(parentPrim.Children.Values); parts.Remove(parentPrim.RootPart); - - foreach (SceneObjectPart part in parts) + if (parts.Count > 0) { - parentPrim.DelinkFromGroup(part.LocalId, true); - parentPrim.TriggerScriptChangedEvent(Changed.LINK); + try + { + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart part in parts) + { + parentPrim.DelinkFromGroup(part.LocalId, true); + parentPrim.TriggerScriptChangedEvent(Changed.LINK); + } + } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } } parentPrim.HasGroupChanged = true; parentPrim.ScheduleGroupForFullUpdate(); @@ -5664,10 +5726,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); List parts = GetLinkParts(linknumber); - - foreach (var part in parts) + if (parts.Count > 0) { - SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); + try + { + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (var part in parts) + { + SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); + } + } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } } } @@ -7068,9 +7140,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); List parts = GetLinkParts(linknumber); - - foreach (SceneObjectPart part in parts) - SetPrimParams(part, rules); + if (parts.Count>0) + { + try + { + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart part in parts) + SetPrimParams(part, rules); + } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } + } } public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) -- cgit v1.1