aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
diff options
context:
space:
mode:
authorDan Lake2009-10-13 19:13:06 -0700
committerJohn Hurliman2009-10-13 19:32:59 -0700
commit5976ac16b0eedaeca2360010a3d6f7be4213700a (patch)
tree8f6a80582a4640b5be0c242fd7cf2f19db39a72a /OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
parent* Copied LocklessQueue.cs into OpenSim.Framework and added the .Count propert... (diff)
downloadopensim-SC_OLD-5976ac16b0eedaeca2360010a3d6f7be4213700a.zip
opensim-SC_OLD-5976ac16b0eedaeca2360010a3d6f7be4213700a.tar.gz
opensim-SC_OLD-5976ac16b0eedaeca2360010a3d6f7be4213700a.tar.bz2
opensim-SC_OLD-5976ac16b0eedaeca2360010a3d6f7be4213700a.tar.xz
Optimized heartbeat by calling Update() only on updated objects.
During the heartbeat loop, Update() is called on every SceneObjectGroup which in turn checks if any SceneObjectPart has changed. For large regions (> 100k prims) this work consumes 20-30% of a CPU even though there are only a few objects updating each frame. There is only one other reason to check every object on every frame, and that is the case where a script has registered the object with an "at target" listener. We can easily track when an object is registered or unregistered with an AtTarget, so this is not a reason to check every object every heartbeat. In the attached patch, I have added a dictionary to the scene which tracks the objects which have At Targets. Each heartbeat, the AtTarget() function will be called on every object registered with a listener for that event. Also, I added a dictionary to SceneGraph which stores references to objects which have been queued for updates during the heartbeat. At each heartbeat, Update() is called only on the objects which have generated updates during that beat.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs15
1 files changed, 6 insertions, 9 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 6a10618..d4cef7d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1234,6 +1234,7 @@ namespace OpenSim.Region.Framework.Scenes
1234 { 1234 {
1235 lock (m_targets) 1235 lock (m_targets)
1236 m_targets.Clear(); 1236 m_targets.Clear();
1237 m_scene.RemoveGroupTarget(this);
1237 } 1238 }
1238 1239
1239 ScheduleGroupForFullUpdate(); 1240 ScheduleGroupForFullUpdate();
@@ -1864,12 +1865,6 @@ namespace OpenSim.Region.Framework.Scenes
1864 m_rootPart.UpdateFlag = 1; 1865 m_rootPart.UpdateFlag = 1;
1865 lastPhysGroupPos = AbsolutePosition; 1866 lastPhysGroupPos = AbsolutePosition;
1866 } 1867 }
1867 //foreach (SceneObjectPart part in m_parts.Values)
1868 //{
1869 //if (part.UpdateFlag == 0) part.UpdateFlag = 1;
1870 //}
1871
1872 checkAtTargets();
1873 1868
1874 if (UsePhysics && ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1) 1869 if (UsePhysics && ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1)
1875 || (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1) 1870 || (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1)
@@ -3114,6 +3109,7 @@ namespace OpenSim.Region.Framework.Scenes
3114 { 3109 {
3115 m_targets.Add(handle, waypoint); 3110 m_targets.Add(handle, waypoint);
3116 } 3111 }
3112 m_scene.AddGroupTarget(this);
3117 return (int)handle; 3113 return (int)handle;
3118 } 3114 }
3119 3115
@@ -3121,12 +3117,13 @@ namespace OpenSim.Region.Framework.Scenes
3121 { 3117 {
3122 lock (m_targets) 3118 lock (m_targets)
3123 { 3119 {
3124 if (m_targets.ContainsKey((uint)handle)) 3120 m_targets.Remove((uint)handle);
3125 m_targets.Remove((uint)handle); 3121 if (m_targets.Count == 0)
3122 m_scene.RemoveGroupTarget(this);
3126 } 3123 }
3127 } 3124 }
3128 3125
3129 private void checkAtTargets() 3126 public void checkAtTargets()
3130 { 3127 {
3131 if (m_scriptListens_atTarget || m_scriptListens_notAtTarget) 3128 if (m_scriptListens_atTarget || m_scriptListens_notAtTarget)
3132 { 3129 {