aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment
diff options
context:
space:
mode:
authorAdam Frisby2007-09-24 15:46:03 +0000
committerAdam Frisby2007-09-24 15:46:03 +0000
commit48e0e05446b8490476fab4fb117d55c66abb40d3 (patch)
treedd07bbd1589a87b7f504ded561c651fa738f152c /OpenSim/Region/Environment
parentMore structural changes to new SE (diff)
downloadopensim-SC-48e0e05446b8490476fab4fb117d55c66abb40d3.zip
opensim-SC-48e0e05446b8490476fab4fb117d55c66abb40d3.tar.gz
opensim-SC-48e0e05446b8490476fab4fb117d55c66abb40d3.tar.bz2
opensim-SC-48e0e05446b8490476fab4fb117d55c66abb40d3.tar.xz
* Refactored the central update loop - now easier to work with. Switching from per-framecounts to per-second time periods and moving to OpenSim.ini shortly.
Diffstat (limited to 'OpenSim/Region/Environment')
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs248
1 files changed, 158 insertions, 90 deletions
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index 8fc477a..4e9cbe3 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -60,15 +60,9 @@ namespace OpenSim.Region.Environment.Scenes
60 protected Dictionary<LLUUID, ScenePresence> m_scenePresences; 60 protected Dictionary<LLUUID, ScenePresence> m_scenePresences;
61 protected Dictionary<LLUUID, SceneObjectGroup> m_sceneObjects; 61 protected Dictionary<LLUUID, SceneObjectGroup> m_sceneObjects;
62 62
63 /// publicized so it can be accessed from SceneObjectGroup.
64 protected float timeStep = 0.1f;
65
66 private Random Rand = new Random(); 63 private Random Rand = new Random();
67 private uint _primCount = 702000; 64 private uint _primCount = 702000;
68 private readonly Mutex _primAllocateMutex = new Mutex(false); 65 private readonly Mutex _primAllocateMutex = new Mutex(false);
69 private int storageCount;
70 private int terrainCheckCount;
71 private int landPrimCheckCount;
72 66
73 private int m_timePhase = 24; 67 private int m_timePhase = 24;
74 private int m_timeUpdateCount; 68 private int m_timeUpdateCount;
@@ -98,6 +92,23 @@ namespace OpenSim.Region.Environment.Scenes
98 private IHttpRequests m_httpRequestModule = null; 92 private IHttpRequests m_httpRequestModule = null;
99 private ISimChat m_simChatModule = null; 93 private ISimChat m_simChatModule = null;
100 94
95
96 // Central Update Loop
97
98 protected int m_fps = 10;
99 protected int m_frame = 0;
100 protected float m_timespan = 0.1f;
101 protected DateTime m_lastupdate = DateTime.Now;
102
103 private int m_update_physics = 1;
104 private int m_update_entitymovement = 1;
105 private int m_update_entities = 1;
106 private int m_update_events = 1;
107 private int m_update_backup = 200;
108 private int m_update_terrain = 50;
109 private int m_update_land = 1;
110 private int m_update_avatars = 1;
111
101 #region Properties 112 #region Properties
102 113
103 public AgentCircuitManager AuthenticateHandler 114 public AgentCircuitManager AuthenticateHandler
@@ -222,7 +233,7 @@ namespace OpenSim.Region.Environment.Scenes
222 public void StartTimer() 233 public void StartTimer()
223 { 234 {
224 m_heartbeatTimer.Enabled = true; 235 m_heartbeatTimer.Enabled = true;
225 m_heartbeatTimer.Interval = 100; 236 m_heartbeatTimer.Interval = (int)(m_timespan * 1000);
226 m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 237 m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
227 } 238 }
228 239
@@ -243,123 +254,180 @@ namespace OpenSim.Region.Environment.Scenes
243 /// </summary> 254 /// </summary>
244 public override void Update() 255 public override void Update()
245 { 256 {
257 TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate;
258 // Aquire a lock so only one update call happens at once
246 updateLock.WaitOne(); 259 updateLock.WaitOne();
260
247 try 261 try
248 { 262 {
249 if (phyScene.IsThreaded) 263 // Increment the frame counter
250 { 264 m_frame++;
251 phyScene.GetResults();
252 /// no engines implement this, and what does it have to do with threading? possible DEAD CODE
253 }
254 265
255 List<EntityBase> moveEntities = new List<EntityBase>(Entities.Values); 266 // Loop it
267 if (m_frame == Int32.MaxValue)
268 m_frame = 0;
256 269
257 foreach (EntityBase entity in moveEntities) 270 if (m_frame % m_update_physics == 0)
258 { 271 UpdatePreparePhysics();
259 entity.UpdateMovement();
260 }
261 272
262 lock (m_syncRoot) 273 if (m_frame % m_update_entitymovement == 0)
263 { 274 UpdateEntityMovement();
264 phyScene.Simulate(timeStep);
265 }
266 275
267 List<EntityBase> updateEntities = new List<EntityBase>(Entities.Values); 276 if (m_frame % m_update_physics == 0)
277 UpdatePhysics(
278 Math.Min(SinceLastFrame.TotalSeconds, 0.001)
279 );
268 280
269 foreach (EntityBase entity in updateEntities) 281 if (m_frame % m_update_entities == 0)
270 { 282 UpdateEntities();
271 entity.Update(); 283
272 } 284 if (m_frame % m_update_events == 0)
285 UpdateEvents();
273 286
274 // General purpose event manager 287 if (m_frame % m_update_backup == 0)
275 m_eventManager.TriggerOnFrame(); 288 UpdateStorageBackup();
276 289
277 //backup scene data 290 if (m_frame % m_update_terrain == 0)
278 storageCount++; 291 UpdateTerrain();
279 if (storageCount > 1200) //set to how often you want to backup 292
293 if (m_frame % m_update_land == 0)
294 UpdateLand();
295
296 if (m_frame % m_update_avatars == 0)
297 UpdateAvatars();
298 }
299 catch (NotImplementedException)
300 {
301 throw;
302 }
303 catch (Exception e)
304 {
305 MainLog.Instance.Error("Scene", "Failed with exception " + e.ToString());
306 }
307 finally
308 {
309 updateLock.ReleaseMutex();
310 m_lastupdate = DateTime.Now;
311 }
312 }
313
314 private void UpdatePreparePhysics()
315 {
316 // If we are using a threaded physics engine
317 // grab the latest scene from the engine before
318 // trying to process it.
319
320 // PhysX does this (runs in the background).
321
322 if (phyScene.IsThreaded)
323 {
324 phyScene.GetResults();
325 }
326 }
327
328 private void UpdateAvatars()
329 {
330 m_timeUpdateCount++;
331 if (m_timeUpdateCount > 600)
332 {
333 List<ScenePresence> avatars = GetAvatars();
334 foreach (ScenePresence avatar in avatars)
280 { 335 {
281 Backup(); 336 avatar.ControllingClient.SendViewerTime(m_timePhase);
282 storageCount = 0;
283 } 337 }
284 338
285 terrainCheckCount++; 339 m_timeUpdateCount = 0;
286 if (terrainCheckCount >= 50) 340 m_timePhase++;
341 if (m_timePhase > 94)
287 { 342 {
288 terrainCheckCount = 0; 343 m_timePhase = 0;
344 }
345 }
346 }
289 347
290 if (Terrain.Tainted()) 348 private void UpdateLand()
291 { 349 {
292 CreateTerrainTexture(); 350 if (m_LandManager.landPrimCountTainted)
351 {
352 //Perform land update of prim count
353 performParcelPrimCountUpdate();
354 }
355 }
293 356
294 lock (Terrain.heightmap) 357 private void UpdateTerrain()
295 { 358 {
296 lock (m_syncRoot) 359 if (Terrain.Tainted())
297 { 360 {
298 phyScene.SetTerrain(Terrain.GetHeights1D()); 361 CreateTerrainTexture();
299 }
300 362
301 storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD()); 363 lock (Terrain.heightmap)
364 {
365 lock (m_syncRoot)
366 {
367 phyScene.SetTerrain(Terrain.GetHeights1D());
368 }
302 369
303 float[] terData = Terrain.GetHeights1D(); 370 storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD());
304 371
305 Broadcast(delegate(IClientAPI client) 372 float[] terData = Terrain.GetHeights1D();
373
374 Broadcast(delegate(IClientAPI client)
375 {
376 for (int x = 0; x < 16; x++)
377 {
378 for (int y = 0; y < 16; y++)
306 { 379 {
307 for (int x = 0; x < 16; x++) 380 if (Terrain.Tainted(x * 16, y * 16))
308 { 381 {
309 for (int y = 0; y < 16; y++) 382 client.SendLayerData(x, y, terData);
310 {
311 if (Terrain.Tainted(x * 16, y * 16))
312 {
313 client.SendLayerData(x, y, terData);
314 }
315 }
316 } 383 }
317 }); 384 }
385 }
386 });
318 387
319 388
320 389
321 Terrain.ResetTaint(); 390 Terrain.ResetTaint();
322 }
323 }
324 } 391 }
392 }
393 }
325 394
326 landPrimCheckCount++; 395 private void UpdateStorageBackup()
327 if (landPrimCheckCount > 50) //check every 5 seconds for tainted prims 396 {
328 { 397 Backup();
329 if (m_LandManager.landPrimCountTainted) 398 }
330 {
331 //Perform land update of prim count
332 performParcelPrimCountUpdate();
333 landPrimCheckCount = 0;
334 }
335 }
336 399
337 m_timeUpdateCount++; 400 private void UpdateEvents()
338 if (m_timeUpdateCount > 600) 401 {
339 { 402 m_eventManager.TriggerOnFrame();
340 List<ScenePresence> avatars = GetAvatars(); 403 }
341 foreach (ScenePresence avatar in avatars)
342 {
343 avatar.ControllingClient.SendViewerTime(m_timePhase);
344 }
345 404
346 m_timeUpdateCount = 0; 405 private void UpdateEntities()
347 m_timePhase++; 406 {
348 if (m_timePhase > 94) 407 List<EntityBase> updateEntities = new List<EntityBase>(Entities.Values);
349 { 408
350 m_timePhase = 0; 409 foreach (EntityBase entity in updateEntities)
351 } 410 {
352 } 411 entity.Update();
353 } 412 }
354 catch (NotImplementedException) 413 }
414
415 private void UpdatePhysics(double elapsed)
416 {
417 lock (m_syncRoot)
355 { 418 {
356 throw; 419 phyScene.Simulate((float)elapsed);
357 } 420 }
358 catch (Exception e) 421 }
422
423 private void UpdateEntityMovement()
424 {
425 List<EntityBase> moveEntities = new List<EntityBase>(Entities.Values);
426
427 foreach (EntityBase entity in moveEntities)
359 { 428 {
360 MainLog.Instance.Error("Scene", "Failed with exception " + e.ToString()); 429 entity.UpdateMovement();
361 } 430 }
362 updateLock.ReleaseMutex();
363 } 431 }
364 432
365 /// <summary> 433 /// <summary>