From 88da253c947c78e97f78119203e3c2f216a788e2 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 18 Feb 2011 21:54:44 +0000
Subject: Add very basic test which invokes the scene update loop once and
checks the frame number.
This makes Scene.Update() match its original description of performing a single update, which also matches the semantics of SOG and ScenePresence.
---
OpenSim/Region/Framework/Scenes/Scene.cs | 307 ++++++++++-----------
.../Framework/Scenes/Tests/ScenePresenceTests.cs | 3 -
.../Region/Framework/Scenes/Tests/SceneTests.cs | 71 +++++
3 files changed, 224 insertions(+), 157 deletions(-)
create mode 100644 OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
(limited to 'OpenSim/Region')
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 02a0268..e0af2d6 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -129,7 +129,16 @@ namespace OpenSim.Region.Framework.Scenes
protected ICapabilitiesModule m_capsModule;
// Central Update Loop
protected int m_fps = 10;
- protected uint m_frame;
+
+ ///
+ /// Current scene frame number
+ ///
+ public uint Frame
+ {
+ get;
+ protected set;
+ }
+
protected float m_timespan = 0.089f;
protected DateTime m_lastupdate = DateTime.UtcNow;
@@ -1183,7 +1192,8 @@ namespace OpenSim.Region.Framework.Scenes
try
{
- Update();
+ while (!shuttingdown)
+ Update();
m_lastUpdate = Util.EnvironmentTickCount();
m_firstHeartbeat = false;
@@ -1200,187 +1210,176 @@ namespace OpenSim.Region.Framework.Scenes
Watchdog.RemoveThread();
}
- ///
- /// Performs per-frame updates on the scene, this should be the central scene loop
- ///
public override void Update()
- {
- float physicsFPS;
- int maintc;
+ {
+ TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate;
+ float physicsFPS = 0f;
- while (!shuttingdown)
+ int maintc = Util.EnvironmentTickCount();
+ int tmpFrameMS = maintc;
+ tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
+
+ // Increment the frame counter
+ ++Frame;
+
+ try
{
- TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate;
- physicsFPS = 0f;
+ // Check if any objects have reached their targets
+ CheckAtTargets();
- maintc = Util.EnvironmentTickCount();
- int tmpFrameMS = maintc;
- tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
+ // Update SceneObjectGroups that have scheduled themselves for updates
+ // Objects queue their updates onto all scene presences
+ if (Frame % m_update_objects == 0)
+ m_sceneGraph.UpdateObjectGroups();
- // Increment the frame counter
- ++m_frame;
+ // Run through all ScenePresences looking for updates
+ // Presence updates and queued object updates for each presence are sent to clients
+ if (Frame % m_update_presences == 0)
+ m_sceneGraph.UpdatePresences();
- try
+ // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
+ if (Frame % m_update_coarse_locations == 0)
{
- // Check if any objects have reached their targets
- CheckAtTargets();
-
- // Update SceneObjectGroups that have scheduled themselves for updates
- // Objects queue their updates onto all scene presences
- if (m_frame % m_update_objects == 0)
- m_sceneGraph.UpdateObjectGroups();
+ List coarseLocations;
+ List avatarUUIDs;
+ SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
+ // Send coarse locations to clients
+ ForEachScenePresence(delegate(ScenePresence presence)
+ {
+ presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
+ });
+ }
- // Run through all ScenePresences looking for updates
- // Presence updates and queued object updates for each presence are sent to clients
- if (m_frame % m_update_presences == 0)
- m_sceneGraph.UpdatePresences();
+ int tmpPhysicsMS2 = Util.EnvironmentTickCount();
+ if ((Frame % m_update_physics == 0) && m_physics_enabled)
+ m_sceneGraph.UpdatePreparePhysics();
+ physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
- // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
- if (m_frame % m_update_coarse_locations == 0)
- {
- List coarseLocations;
- List avatarUUIDs;
- SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
- // Send coarse locations to clients
- ForEachScenePresence(delegate(ScenePresence presence)
- {
- presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
- });
- }
+ // Apply any pending avatar force input to the avatar's velocity
+ if (Frame % m_update_entitymovement == 0)
+ m_sceneGraph.UpdateScenePresenceMovement();
- int tmpPhysicsMS2 = Util.EnvironmentTickCount();
- if ((m_frame % m_update_physics == 0) && m_physics_enabled)
- m_sceneGraph.UpdatePreparePhysics();
- physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
+ // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
+ // velocity
+ int tmpPhysicsMS = Util.EnvironmentTickCount();
+ if (Frame % m_update_physics == 0)
+ {
+ if (m_physics_enabled)
+ physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan));
+ if (SynchronizeScene != null)
+ SynchronizeScene(this);
+ }
+ physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
- // Apply any pending avatar force input to the avatar's velocity
- if (m_frame % m_update_entitymovement == 0)
- m_sceneGraph.UpdateScenePresenceMovement();
+ // Delete temp-on-rez stuff
+ if (Frame % 1000 == 0 && !m_cleaningTemps)
+ {
+ int tmpTempOnRezMS = Util.EnvironmentTickCount();
+ m_cleaningTemps = true;
+ Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
+ tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
+ }
- // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
- // velocity
- int tmpPhysicsMS = Util.EnvironmentTickCount();
- if (m_frame % m_update_physics == 0)
+ if (RegionStatus != RegionStatus.SlaveScene)
+ {
+ if (Frame % m_update_events == 0)
{
- if (m_physics_enabled)
- physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan));
- if (SynchronizeScene != null)
- SynchronizeScene(this);
+ int evMS = Util.EnvironmentTickCount();
+ UpdateEvents();
+ eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
}
- physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
- // Delete temp-on-rez stuff
- if (m_frame % 1000 == 0 && !m_cleaningTemps)
+ if (Frame % m_update_backup == 0)
{
- int tmpTempOnRezMS = Util.EnvironmentTickCount();
- m_cleaningTemps = true;
- Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
- tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
+ int backMS = Util.EnvironmentTickCount();
+ UpdateStorageBackup();
+ backupMS = Util.EnvironmentTickCountSubtract(backMS);
}
- if (RegionStatus != RegionStatus.SlaveScene)
+ if (Frame % m_update_terrain == 0)
{
- if (m_frame % m_update_events == 0)
- {
- int evMS = Util.EnvironmentTickCount();
- UpdateEvents();
- eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
- }
-
- if (m_frame % m_update_backup == 0)
- {
- int backMS = Util.EnvironmentTickCount();
- UpdateStorageBackup();
- backupMS = Util.EnvironmentTickCountSubtract(backMS);
- }
+ int terMS = Util.EnvironmentTickCount();
+ UpdateTerrain();
+ terrainMS = Util.EnvironmentTickCountSubtract(terMS);
+ }
- if (m_frame % m_update_terrain == 0)
- {
- int terMS = Util.EnvironmentTickCount();
- UpdateTerrain();
- terrainMS = Util.EnvironmentTickCountSubtract(terMS);
- }
+ //if (Frame % m_update_land == 0)
+ //{
+ // int ldMS = Util.EnvironmentTickCount();
+ // UpdateLand();
+ // landMS = Util.EnvironmentTickCountSubtract(ldMS);
+ //}
- //if (m_frame % m_update_land == 0)
- //{
- // int ldMS = Util.EnvironmentTickCount();
- // UpdateLand();
- // landMS = Util.EnvironmentTickCountSubtract(ldMS);
- //}
+ frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
+ otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
+ lastCompletedFrame = Util.EnvironmentTickCount();
+
+ // if (Frame%m_update_avatars == 0)
+ // UpdateInWorldTime();
+ StatsReporter.AddPhysicsFPS(physicsFPS);
+ StatsReporter.AddTimeDilation(TimeDilation);
+ StatsReporter.AddFPS(1);
+ StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
+ StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
+ StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
+ StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
+ StatsReporter.addFrameMS(frameMS);
+ StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
+ StatsReporter.addOtherMS(otherMS);
+ StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
+ StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
+ }
- frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
- otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
- lastCompletedFrame = Util.EnvironmentTickCount();
-
- // if (m_frame%m_update_avatars == 0)
- // UpdateInWorldTime();
- StatsReporter.AddPhysicsFPS(physicsFPS);
- StatsReporter.AddTimeDilation(TimeDilation);
- StatsReporter.AddFPS(1);
- StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
- StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
- StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
- StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
- StatsReporter.addFrameMS(frameMS);
- StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
- StatsReporter.addOtherMS(otherMS);
- StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
- StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
- }
+ if (LoginsDisabled && Frame == 20)
+ {
+ // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
+ // this is a rare case where we know we have just went through a long cycle of heap
+ // allocations, and there is no more work to be done until someone logs in
+ GC.Collect();
- if (LoginsDisabled && m_frame == 20)
+ IConfig startupConfig = m_config.Configs["Startup"];
+ if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
{
- // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
- // this is a rare case where we know we have just went through a long cycle of heap
- // allocations, and there is no more work to be done until someone logs in
- GC.Collect();
-
- IConfig startupConfig = m_config.Configs["Startup"];
- if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
- {
- m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
- LoginsDisabled = false;
- m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface(), RegionInfo);
- }
+ m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
+ LoginsDisabled = false;
+ m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface(), RegionInfo);
}
}
- catch (NotImplementedException)
- {
- throw;
- }
- catch (AccessViolationException e)
- {
- m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
- }
- //catch (NullReferenceException e)
- //{
- // m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
- //}
- catch (InvalidOperationException e)
- {
- m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
- }
- catch (Exception e)
- {
- m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
- }
- finally
- {
- m_lastupdate = DateTime.UtcNow;
- }
-
- maintc = Util.EnvironmentTickCountSubtract(maintc);
- maintc = (int)(m_timespan * 1000) - maintc;
+ }
+ catch (NotImplementedException)
+ {
+ throw;
+ }
+ catch (AccessViolationException e)
+ {
+ m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
+ }
+ //catch (NullReferenceException e)
+ //{
+ // m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
+ //}
+ catch (InvalidOperationException e)
+ {
+ m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
+ }
+ catch (Exception e)
+ {
+ m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
+ }
+ finally
+ {
+ m_lastupdate = DateTime.UtcNow;
+ }
- if (maintc > 0)
- Thread.Sleep(maintc);
+ maintc = Util.EnvironmentTickCountSubtract(maintc);
+ maintc = (int)(m_timespan * 1000) - maintc;
- // Tell the watchdog that this thread is still alive
- Watchdog.UpdateThread();
- }
- }
+ if (maintc > 0)
+ Thread.Sleep(maintc);
-
+ // Tell the watchdog that this thread is still alive
+ Watchdog.UpdateThread();
+ }
public void AddGroupTarget(SceneObjectGroup grp)
{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
index ef52363..8286e4f 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
@@ -116,9 +116,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests
agent.ChildrenCapSeeds = new Dictionary();
agent.child = true;
- if (scene.PresenceService == null)
- Console.WriteLine("Presence Service is null");
-
scene.PresenceService.LoginAgent(agent.AgentID.ToString(), agent.SessionID, agent.SecureSessionID);
string reason;
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
new file mode 100644
index 0000000..9aba8a8
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using System.Timers;
+using Timer=System.Timers.Timer;
+using Nini.Config;
+using NUnit.Framework;
+using NUnit.Framework.SyntaxHelpers;
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Framework.Communications;
+using OpenSim.Region.Framework.Scenes;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.CoreModules.World.Serialiser;
+using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
+using OpenSim.Tests.Common;
+using OpenSim.Tests.Common.Mock;
+using OpenSim.Tests.Common.Setup;
+
+namespace OpenSim.Region.Framework.Scenes.Tests
+{
+ ///
+ /// Scene presence tests
+ ///
+ [TestFixture]
+ public class SceneTests
+ {
+ ///
+ /// Very basic scene update test. Should become more elaborate with time.
+ ///
+ [Test]
+ public void TestUpdateScene()
+ {
+ TestHelper.InMethod();
+
+ Scene scene = SceneSetupHelpers.SetupScene();
+ scene.Update();
+
+ Assert.That(scene.Frame, Is.EqualTo(1));
+ }
+ }
+}
\ No newline at end of file
--
cgit v1.1