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