diff options
author | Justin Clark-Casey (justincc) | 2012-03-20 23:12:21 +0000 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-03-20 23:12:21 +0000 |
commit | 30b2a8c778d02926e038bc62977c4a4c9dbec5ee (patch) | |
tree | 0b35af969e4ac337cf4521d07b1f25765a5b3273 | |
parent | reduce avatar verticle jump from the absurd 5 meter jump to a less (diff) | |
download | opensim-SC-30b2a8c778d02926e038bc62977c4a4c9dbec5ee.zip opensim-SC-30b2a8c778d02926e038bc62977c4a4c9dbec5ee.tar.gz opensim-SC-30b2a8c778d02926e038bc62977c4a4c9dbec5ee.tar.bz2 opensim-SC-30b2a8c778d02926e038bc62977c4a4c9dbec5ee.tar.xz |
Move frame loop entirely within Scene.Update() for better future performance analysis and stat accuracy.
Update() now accepts a frames parameter which can control the number of frames updated.
-1 will update until shutdown.
The watchdog updating moves above the maintc recalculation for any required sleep since it should be accounted for within the frame.
-rw-r--r-- | OpenSim/Framework/Util.cs | 17 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 337 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneBase.cs | 8 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs | 12 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs | 12 | ||||
-rw-r--r-- | OpenSim/Tests/Torture/ObjectTortureTests.cs | 2 |
8 files changed, 213 insertions, 179 deletions
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 9e0f138..b2e5c7b 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -1758,13 +1758,26 @@ namespace OpenSim.Framework | |||
1758 | /// and negative every 24.9 days. Subtracts the passed value (previously fetched by | 1758 | /// and negative every 24.9 days. Subtracts the passed value (previously fetched by |
1759 | /// 'EnvironmentTickCount()') and accounts for any wrapping. | 1759 | /// 'EnvironmentTickCount()') and accounts for any wrapping. |
1760 | /// </summary> | 1760 | /// </summary> |
1761 | /// <param name="newValue"></param> | ||
1762 | /// <param name="prevValue"></param> | ||
1761 | /// <returns>subtraction of passed prevValue from current Environment.TickCount</returns> | 1763 | /// <returns>subtraction of passed prevValue from current Environment.TickCount</returns> |
1762 | public static Int32 EnvironmentTickCountSubtract(Int32 prevValue) | 1764 | public static Int32 EnvironmentTickCountSubtract(Int32 newValue, Int32 prevValue) |
1763 | { | 1765 | { |
1764 | Int32 diff = EnvironmentTickCount() - prevValue; | 1766 | Int32 diff = newValue - prevValue; |
1765 | return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); | 1767 | return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); |
1766 | } | 1768 | } |
1767 | 1769 | ||
1770 | /// <summary> | ||
1771 | /// Environment.TickCount is an int but it counts all 32 bits so it goes positive | ||
1772 | /// and negative every 24.9 days. Subtracts the passed value (previously fetched by | ||
1773 | /// 'EnvironmentTickCount()') and accounts for any wrapping. | ||
1774 | /// </summary> | ||
1775 | /// <returns>subtraction of passed prevValue from current Environment.TickCount</returns> | ||
1776 | public static Int32 EnvironmentTickCountSubtract(Int32 prevValue) | ||
1777 | { | ||
1778 | return EnvironmentTickCountSubtract(EnvironmentTickCount(), prevValue); | ||
1779 | } | ||
1780 | |||
1768 | // Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount | 1781 | // Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount |
1769 | // Assumes both tcA and tcB came from previous calls to Util.EnvironmentTickCount(). | 1782 | // Assumes both tcA and tcB came from previous calls to Util.EnvironmentTickCount(). |
1770 | // A positive return value indicates A occured later than B | 1783 | // A positive return value indicates A occured later than B |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs index fb94355..d76927b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs | |||
@@ -50,7 +50,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
50 | m_regStatus = RegionStatus.Up; | 50 | m_regStatus = RegionStatus.Up; |
51 | } | 51 | } |
52 | 52 | ||
53 | public override void Update() {} | 53 | public override void Update(int frames) {} |
54 | public override void LoadWorldMap() {} | 54 | public override void LoadWorldMap() {} |
55 | 55 | ||
56 | public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) | 56 | public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 18a7ce8..fe59e4d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1175,11 +1175,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1175 | // The first frame can take a very long time due to physics actors being added on startup. Therefore, | 1175 | // The first frame can take a very long time due to physics actors being added on startup. Therefore, |
1176 | // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false | 1176 | // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false |
1177 | // alarms for scenes with many objects. | 1177 | // alarms for scenes with many objects. |
1178 | Update(); | 1178 | Update(1); |
1179 | Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; | 1179 | Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; |
1180 | 1180 | ||
1181 | while (!shuttingdown) | 1181 | while (!shuttingdown) |
1182 | Update(); | 1182 | Update(-1); |
1183 | 1183 | ||
1184 | m_lastUpdate = Util.EnvironmentTickCount(); | 1184 | m_lastUpdate = Util.EnvironmentTickCount(); |
1185 | m_firstHeartbeat = false; | 1185 | m_firstHeartbeat = false; |
@@ -1193,184 +1193,205 @@ namespace OpenSim.Region.Framework.Scenes | |||
1193 | Watchdog.RemoveThread(); | 1193 | Watchdog.RemoveThread(); |
1194 | } | 1194 | } |
1195 | 1195 | ||
1196 | public override void Update() | 1196 | public override void Update(int frames) |
1197 | { | 1197 | { |
1198 | float physicsFPS = 0f; | 1198 | long? endFrame = null; |
1199 | |||
1200 | int maintc = Util.EnvironmentTickCount(); | ||
1201 | int tmpFrameMS = maintc; | ||
1202 | agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0; | ||
1203 | 1199 | ||
1204 | ++Frame; | 1200 | if (frames >= 0) |
1201 | endFrame = Frame + frames; | ||
1205 | 1202 | ||
1206 | // m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); | 1203 | float physicsFPS = 0f; |
1204 | int tmpFrameMS, tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS; | ||
1205 | int maintc; | ||
1206 | List<Vector3> coarseLocations; | ||
1207 | List<UUID> avatarUUIDs; | ||
1207 | 1208 | ||
1208 | try | 1209 | while (!shuttingdown && (endFrame == null || Frame < endFrame)) |
1209 | { | 1210 | { |
1210 | int tmpPhysicsMS2 = Util.EnvironmentTickCount(); | 1211 | maintc = Util.EnvironmentTickCount(); |
1211 | if ((Frame % m_update_physics == 0) && m_physics_enabled) | 1212 | ++Frame; |
1212 | m_sceneGraph.UpdatePreparePhysics(); | ||
1213 | physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2); | ||
1214 | |||
1215 | // Apply any pending avatar force input to the avatar's velocity | ||
1216 | int tmpAgentMS = Util.EnvironmentTickCount(); | ||
1217 | if (Frame % m_update_entitymovement == 0) | ||
1218 | m_sceneGraph.UpdateScenePresenceMovement(); | ||
1219 | agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS); | ||
1220 | |||
1221 | // Perform the main physics update. This will do the actual work of moving objects and avatars according to their | ||
1222 | // velocity | ||
1223 | int tmpPhysicsMS = Util.EnvironmentTickCount(); | ||
1224 | if (Frame % m_update_physics == 0) | ||
1225 | { | ||
1226 | if (m_physics_enabled) | ||
1227 | physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime); | ||
1228 | 1213 | ||
1229 | if (SynchronizeScene != null) | 1214 | // m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); |
1230 | SynchronizeScene(this); | ||
1231 | } | ||
1232 | physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS); | ||
1233 | |||
1234 | tmpAgentMS = Util.EnvironmentTickCount(); | ||
1235 | |||
1236 | // Check if any objects have reached their targets | ||
1237 | CheckAtTargets(); | ||
1238 | |||
1239 | // Update SceneObjectGroups that have scheduled themselves for updates | ||
1240 | // Objects queue their updates onto all scene presences | ||
1241 | if (Frame % m_update_objects == 0) | ||
1242 | m_sceneGraph.UpdateObjectGroups(); | ||
1243 | 1215 | ||
1244 | // Run through all ScenePresences looking for updates | 1216 | tmpFrameMS = maintc; |
1245 | // Presence updates and queued object updates for each presence are sent to clients | 1217 | agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0; |
1246 | if (Frame % m_update_presences == 0) | ||
1247 | m_sceneGraph.UpdatePresences(); | ||
1248 | 1218 | ||
1249 | // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) | 1219 | try |
1250 | if (Frame % m_update_coarse_locations == 0) | ||
1251 | { | 1220 | { |
1252 | List<Vector3> coarseLocations; | 1221 | tmpPhysicsMS2 = Util.EnvironmentTickCount(); |
1253 | List<UUID> avatarUUIDs; | 1222 | if ((Frame % m_update_physics == 0) && m_physics_enabled) |
1254 | SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); | 1223 | m_sceneGraph.UpdatePreparePhysics(); |
1255 | // Send coarse locations to clients | 1224 | physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2); |
1256 | ForEachScenePresence(delegate(ScenePresence presence) | 1225 | |
1226 | // Apply any pending avatar force input to the avatar's velocity | ||
1227 | tmpAgentMS = Util.EnvironmentTickCount(); | ||
1228 | if (Frame % m_update_entitymovement == 0) | ||
1229 | m_sceneGraph.UpdateScenePresenceMovement(); | ||
1230 | agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS); | ||
1231 | |||
1232 | // Perform the main physics update. This will do the actual work of moving objects and avatars according to their | ||
1233 | // velocity | ||
1234 | tmpPhysicsMS = Util.EnvironmentTickCount(); | ||
1235 | if (Frame % m_update_physics == 0) | ||
1257 | { | 1236 | { |
1258 | presence.SendCoarseLocations(coarseLocations, avatarUUIDs); | 1237 | if (m_physics_enabled) |
1259 | }); | 1238 | physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime); |
1260 | } | 1239 | |
1261 | 1240 | if (SynchronizeScene != null) | |
1262 | agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); | 1241 | SynchronizeScene(this); |
1263 | 1242 | } | |
1264 | // Delete temp-on-rez stuff | 1243 | physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS); |
1265 | if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps) | ||
1266 | { | ||
1267 | int tmpTempOnRezMS = Util.EnvironmentTickCount(); | ||
1268 | m_cleaningTemps = true; | ||
1269 | Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; }); | ||
1270 | tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS); | ||
1271 | } | ||
1272 | |||
1273 | if (Frame % m_update_events == 0) | ||
1274 | { | ||
1275 | int evMS = Util.EnvironmentTickCount(); | ||
1276 | UpdateEvents(); | ||
1277 | eventMS = Util.EnvironmentTickCountSubtract(evMS); ; | ||
1278 | } | ||
1279 | |||
1280 | if (Frame % m_update_backup == 0) | ||
1281 | { | ||
1282 | int backMS = Util.EnvironmentTickCount(); | ||
1283 | UpdateStorageBackup(); | ||
1284 | backupMS = Util.EnvironmentTickCountSubtract(backMS); | ||
1285 | } | ||
1286 | |||
1287 | if (Frame % m_update_terrain == 0) | ||
1288 | { | ||
1289 | int terMS = Util.EnvironmentTickCount(); | ||
1290 | UpdateTerrain(); | ||
1291 | terrainMS = Util.EnvironmentTickCountSubtract(terMS); | ||
1292 | } | ||
1293 | |||
1294 | //if (Frame % m_update_land == 0) | ||
1295 | //{ | ||
1296 | // int ldMS = Util.EnvironmentTickCount(); | ||
1297 | // UpdateLand(); | ||
1298 | // landMS = Util.EnvironmentTickCountSubtract(ldMS); | ||
1299 | //} | ||
1300 | |||
1301 | frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS); | ||
1302 | otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; | ||
1303 | lastCompletedFrame = Util.EnvironmentTickCount(); | ||
1304 | |||
1305 | // if (Frame%m_update_avatars == 0) | ||
1306 | // UpdateInWorldTime(); | ||
1307 | StatsReporter.AddPhysicsFPS(physicsFPS); | ||
1308 | StatsReporter.AddTimeDilation(TimeDilation); | ||
1309 | StatsReporter.AddFPS(1); | ||
1310 | StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount()); | ||
1311 | StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount()); | ||
1312 | StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount()); | ||
1313 | StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount()); | ||
1314 | StatsReporter.addFrameMS(frameMS); | ||
1315 | StatsReporter.addAgentMS(agentMS); | ||
1316 | StatsReporter.addPhysicsMS(physicsMS + physicsMS2); | ||
1317 | StatsReporter.addOtherMS(otherMS); | ||
1318 | StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount()); | ||
1319 | StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); | ||
1320 | |||
1321 | if (LoginsDisabled && Frame == 20) | ||
1322 | { | ||
1323 | // m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock); | ||
1324 | |||
1325 | // In 99.9% of cases it is a bad idea to manually force garbage collection. However, | ||
1326 | // this is a rare case where we know we have just went through a long cycle of heap | ||
1327 | // allocations, and there is no more work to be done until someone logs in | ||
1328 | GC.Collect(); | ||
1329 | 1244 | ||
1330 | IConfig startupConfig = m_config.Configs["Startup"]; | 1245 | tmpAgentMS = Util.EnvironmentTickCount(); |
1331 | if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) | 1246 | |
1247 | // Check if any objects have reached their targets | ||
1248 | CheckAtTargets(); | ||
1249 | |||
1250 | // Update SceneObjectGroups that have scheduled themselves for updates | ||
1251 | // Objects queue their updates onto all scene presences | ||
1252 | if (Frame % m_update_objects == 0) | ||
1253 | m_sceneGraph.UpdateObjectGroups(); | ||
1254 | |||
1255 | // Run through all ScenePresences looking for updates | ||
1256 | // Presence updates and queued object updates for each presence are sent to clients | ||
1257 | if (Frame % m_update_presences == 0) | ||
1258 | m_sceneGraph.UpdatePresences(); | ||
1259 | |||
1260 | // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) | ||
1261 | if (Frame % m_update_coarse_locations == 0) | ||
1262 | { | ||
1263 | SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); | ||
1264 | // Send coarse locations to clients | ||
1265 | ForEachScenePresence(delegate(ScenePresence presence) | ||
1266 | { | ||
1267 | presence.SendCoarseLocations(coarseLocations, avatarUUIDs); | ||
1268 | }); | ||
1269 | } | ||
1270 | |||
1271 | agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); | ||
1272 | |||
1273 | // Delete temp-on-rez stuff | ||
1274 | if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps) | ||
1275 | { | ||
1276 | tmpTempOnRezMS = Util.EnvironmentTickCount(); | ||
1277 | m_cleaningTemps = true; | ||
1278 | Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; }); | ||
1279 | tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS); | ||
1280 | } | ||
1281 | |||
1282 | if (Frame % m_update_events == 0) | ||
1332 | { | 1283 | { |
1333 | // This handles a case of a region having no scripts for the RegionReady module | 1284 | evMS = Util.EnvironmentTickCount(); |
1334 | if (m_sceneGraph.GetActiveScriptsCount() == 0) | 1285 | UpdateEvents(); |
1286 | eventMS = Util.EnvironmentTickCountSubtract(evMS); | ||
1287 | } | ||
1288 | |||
1289 | if (Frame % m_update_backup == 0) | ||
1290 | { | ||
1291 | backMS = Util.EnvironmentTickCount(); | ||
1292 | UpdateStorageBackup(); | ||
1293 | backupMS = Util.EnvironmentTickCountSubtract(backMS); | ||
1294 | } | ||
1295 | |||
1296 | if (Frame % m_update_terrain == 0) | ||
1297 | { | ||
1298 | terMS = Util.EnvironmentTickCount(); | ||
1299 | UpdateTerrain(); | ||
1300 | terrainMS = Util.EnvironmentTickCountSubtract(terMS); | ||
1301 | } | ||
1302 | |||
1303 | //if (Frame % m_update_land == 0) | ||
1304 | //{ | ||
1305 | // int ldMS = Util.EnvironmentTickCount(); | ||
1306 | // UpdateLand(); | ||
1307 | // landMS = Util.EnvironmentTickCountSubtract(ldMS); | ||
1308 | //} | ||
1309 | |||
1310 | frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS); | ||
1311 | otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; | ||
1312 | lastCompletedFrame = Util.EnvironmentTickCount(); | ||
1313 | |||
1314 | // if (Frame%m_update_avatars == 0) | ||
1315 | // UpdateInWorldTime(); | ||
1316 | StatsReporter.AddPhysicsFPS(physicsFPS); | ||
1317 | StatsReporter.AddTimeDilation(TimeDilation); | ||
1318 | StatsReporter.AddFPS(1); | ||
1319 | StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount()); | ||
1320 | StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount()); | ||
1321 | StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount()); | ||
1322 | StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount()); | ||
1323 | |||
1324 | // frameMS currently records work frame times, not total frame times (work + any required sleep to | ||
1325 | // reach min frame time. | ||
1326 | StatsReporter.addFrameMS(frameMS); | ||
1327 | |||
1328 | StatsReporter.addAgentMS(agentMS); | ||
1329 | StatsReporter.addPhysicsMS(physicsMS + physicsMS2); | ||
1330 | StatsReporter.addOtherMS(otherMS); | ||
1331 | StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount()); | ||
1332 | StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); | ||
1333 | |||
1334 | if (LoginsDisabled && Frame == 20) | ||
1335 | { | ||
1336 | // m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock); | ||
1337 | |||
1338 | // In 99.9% of cases it is a bad idea to manually force garbage collection. However, | ||
1339 | // this is a rare case where we know we have just went through a long cycle of heap | ||
1340 | // allocations, and there is no more work to be done until someone logs in | ||
1341 | GC.Collect(); | ||
1342 | |||
1343 | IConfig startupConfig = m_config.Configs["Startup"]; | ||
1344 | if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) | ||
1335 | { | 1345 | { |
1336 | // need to be able to tell these have changed in RegionReady | 1346 | // This handles a case of a region having no scripts for the RegionReady module |
1337 | LoginLock = false; | 1347 | if (m_sceneGraph.GetActiveScriptsCount() == 0) |
1338 | EventManager.TriggerLoginsEnabled(RegionInfo.RegionName); | 1348 | { |
1349 | // need to be able to tell these have changed in RegionReady | ||
1350 | LoginLock = false; | ||
1351 | EventManager.TriggerLoginsEnabled(RegionInfo.RegionName); | ||
1352 | } | ||
1353 | m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); | ||
1354 | |||
1355 | // For RegionReady lockouts | ||
1356 | if(LoginLock == false) | ||
1357 | { | ||
1358 | LoginsDisabled = false; | ||
1359 | } | ||
1360 | |||
1361 | m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo); | ||
1339 | } | 1362 | } |
1340 | m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); | 1363 | else |
1341 | |||
1342 | // For RegionReady lockouts | ||
1343 | if(LoginLock == false) | ||
1344 | { | 1364 | { |
1345 | LoginsDisabled = false; | 1365 | StartDisabled = true; |
1366 | LoginsDisabled = true; | ||
1346 | } | 1367 | } |
1347 | |||
1348 | m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo); | ||
1349 | } | ||
1350 | else | ||
1351 | { | ||
1352 | StartDisabled = true; | ||
1353 | LoginsDisabled = true; | ||
1354 | } | 1368 | } |
1355 | } | 1369 | } |
1356 | } | 1370 | catch (Exception e) |
1357 | catch (Exception e) | 1371 | { |
1358 | { | 1372 | m_log.ErrorFormat( |
1359 | m_log.ErrorFormat( | 1373 | "[SCENE]: Failed on region {0} with exception {1}{2}", |
1360 | "[SCENE]: Failed on region {0} with exception {1}{2}", | 1374 | RegionInfo.RegionName, e.Message, e.StackTrace); |
1361 | RegionInfo.RegionName, e.Message, e.StackTrace); | 1375 | } |
1362 | } | 1376 | |
1377 | EventManager.TriggerRegionHeartbeatEnd(this); | ||
1363 | 1378 | ||
1364 | EventManager.TriggerRegionHeartbeatEnd(this); | 1379 | // Tell the watchdog that this thread is still alive |
1380 | Watchdog.UpdateThread(); | ||
1365 | 1381 | ||
1366 | maintc = Util.EnvironmentTickCountSubtract(maintc); | 1382 | maintc = Util.EnvironmentTickCountSubtract(maintc); |
1367 | maintc = (int)(MinFrameTime * 1000) - maintc; | 1383 | maintc = (int)(MinFrameTime * 1000) - maintc; |
1368 | 1384 | ||
1369 | if (maintc > 0) | 1385 | if (maintc > 0) |
1370 | Thread.Sleep(maintc); | 1386 | Thread.Sleep(maintc); |
1371 | 1387 | ||
1372 | // Tell the watchdog that this thread is still alive | 1388 | // if (frameMS > (int)(MinFrameTime * 1000)) |
1373 | Watchdog.UpdateThread(); | 1389 | // m_log.WarnFormat( |
1390 | // "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", | ||
1391 | // frameMS, | ||
1392 | // MinFrameTime * 1000, | ||
1393 | // RegionInfo.RegionName); | ||
1394 | } | ||
1374 | } | 1395 | } |
1375 | 1396 | ||
1376 | public void AddGroupTarget(SceneObjectGroup grp) | 1397 | public void AddGroupTarget(SceneObjectGroup grp) |
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index 495cede..9c6b884 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs | |||
@@ -149,9 +149,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
149 | #region Update Methods | 149 | #region Update Methods |
150 | 150 | ||
151 | /// <summary> | 151 | /// <summary> |
152 | /// Normally called once every frame/tick to let the world preform anything required (like running the physics simulation) | 152 | /// Called to update the scene loop by a number of frames and until shutdown. |
153 | /// </summary> | 153 | /// </summary> |
154 | public abstract void Update(); | 154 | /// <param name="frames"> |
155 | /// Number of frames to update. Exits on shutdown even if there are frames remaining. | ||
156 | /// If -1 then updates until shutdown. | ||
157 | /// </param> | ||
158 | public abstract void Update(int frames); | ||
155 | 159 | ||
156 | #endregion | 160 | #endregion |
157 | 161 | ||
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs index 442cb8b..cfea10d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs | |||
@@ -81,7 +81,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
81 | // For now, we'll make the scene presence fly to simplify this test, but this needs to change. | 81 | // For now, we'll make the scene presence fly to simplify this test, but this needs to change. |
82 | sp.Flying = true; | 82 | sp.Flying = true; |
83 | 83 | ||
84 | m_scene.Update(); | 84 | m_scene.Update(1); |
85 | Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos)); | 85 | Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos)); |
86 | 86 | ||
87 | Vector3 targetPos = startPos + new Vector3(0, 10, 0); | 87 | Vector3 targetPos = startPos + new Vector3(0, 10, 0); |
@@ -91,7 +91,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
91 | Assert.That( | 91 | Assert.That( |
92 | sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); | 92 | sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); |
93 | 93 | ||
94 | m_scene.Update(); | 94 | m_scene.Update(1); |
95 | 95 | ||
96 | // We should really check the exact figure. | 96 | // We should really check the exact figure. |
97 | Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X)); | 97 | Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X)); |
@@ -99,8 +99,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
99 | Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); | 99 | Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); |
100 | Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X)); | 100 | Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X)); |
101 | 101 | ||
102 | for (int i = 0; i < 10; i++) | 102 | m_scene.Update(10); |
103 | m_scene.Update(); | ||
104 | 103 | ||
105 | double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); | 104 | double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); |
106 | Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move"); | 105 | Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move"); |
@@ -116,7 +115,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
116 | Assert.That( | 115 | Assert.That( |
117 | sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001)); | 116 | sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001)); |
118 | 117 | ||
119 | m_scene.Update(); | 118 | m_scene.Update(1); |
120 | 119 | ||
121 | // We should really check the exact figure. | 120 | // We should really check the exact figure. |
122 | Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X)); | 121 | Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X)); |
@@ -124,8 +123,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
124 | Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); | 123 | Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); |
125 | Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); | 124 | Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); |
126 | 125 | ||
127 | for (int i = 0; i < 10; i++) | 126 | m_scene.Update(10); |
128 | m_scene.Update(); | ||
129 | 127 | ||
130 | distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); | 128 | distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); |
131 | Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move"); | 129 | Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move"); |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs index 8b8aea5..5c9a77d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs | |||
@@ -61,7 +61,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
61 | TestHelpers.InMethod(); | 61 | TestHelpers.InMethod(); |
62 | 62 | ||
63 | Scene scene = SceneHelpers.SetupScene(); | 63 | Scene scene = SceneHelpers.SetupScene(); |
64 | scene.Update(); | 64 | scene.Update(1); |
65 | 65 | ||
66 | Assert.That(scene.Frame, Is.EqualTo(1)); | 66 | Assert.That(scene.Frame, Is.EqualTo(1)); |
67 | } | 67 | } |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 9a7e9e8..eea0b2e 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs | |||
@@ -238,7 +238,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
238 | // For now, we'll make the scene presence fly to simplify this test, but this needs to change. | 238 | // For now, we'll make the scene presence fly to simplify this test, but this needs to change. |
239 | npc.Flying = true; | 239 | npc.Flying = true; |
240 | 240 | ||
241 | m_scene.Update(); | 241 | m_scene.Update(1); |
242 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); | 242 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); |
243 | 243 | ||
244 | Vector3 targetPos = startPos + new Vector3(0, 10, 0); | 244 | Vector3 targetPos = startPos + new Vector3(0, 10, 0); |
@@ -249,7 +249,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
249 | Assert.That( | 249 | Assert.That( |
250 | npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); | 250 | npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); |
251 | 251 | ||
252 | m_scene.Update(); | 252 | m_scene.Update(1); |
253 | 253 | ||
254 | // We should really check the exact figure. | 254 | // We should really check the exact figure. |
255 | Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X)); | 255 | Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X)); |
@@ -257,8 +257,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
257 | Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); | 257 | Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); |
258 | Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X)); | 258 | Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X)); |
259 | 259 | ||
260 | for (int i = 0; i < 10; i++) | 260 | m_scene.Update(10); |
261 | m_scene.Update(); | ||
262 | 261 | ||
263 | double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); | 262 | double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); |
264 | Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move"); | 263 | Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move"); |
@@ -275,7 +274,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
275 | Assert.That( | 274 | Assert.That( |
276 | npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001)); | 275 | npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001)); |
277 | 276 | ||
278 | m_scene.Update(); | 277 | m_scene.Update(1); |
279 | 278 | ||
280 | // We should really check the exact figure. | 279 | // We should really check the exact figure. |
281 | Assert.That(npc.AbsolutePosition.X, Is.GreaterThan(startPos.X)); | 280 | Assert.That(npc.AbsolutePosition.X, Is.GreaterThan(startPos.X)); |
@@ -283,8 +282,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
283 | Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); | 282 | Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); |
284 | Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); | 283 | Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); |
285 | 284 | ||
286 | for (int i = 0; i < 10; i++) | 285 | m_scene.Update(10); |
287 | m_scene.Update(); | ||
288 | 286 | ||
289 | distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); | 287 | distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); |
290 | Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on second move"); | 288 | Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on second move"); |
diff --git a/OpenSim/Tests/Torture/ObjectTortureTests.cs b/OpenSim/Tests/Torture/ObjectTortureTests.cs index 978a308..d0d2199 100644 --- a/OpenSim/Tests/Torture/ObjectTortureTests.cs +++ b/OpenSim/Tests/Torture/ObjectTortureTests.cs | |||
@@ -157,7 +157,7 @@ namespace OpenSim.Tests.Torture | |||
157 | // | 157 | // |
158 | // However, that means that we need to manually run an update here to clear out that list so that deleted | 158 | // However, that means that we need to manually run an update here to clear out that list so that deleted |
159 | // objects will be clean up by the garbage collector before the next stress test is run. | 159 | // objects will be clean up by the garbage collector before the next stress test is run. |
160 | scene.Update(); | 160 | scene.Update(1); |
161 | 161 | ||
162 | Console.WriteLine( | 162 | Console.WriteLine( |
163 | "Took {0}ms, {1}MB ({2} - {3}) to create {4} objects each containing {5} prim(s)", | 163 | "Took {0}ms, {1}MB ({2} - {3}) to create {4} objects each containing {5} prim(s)", |