* 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.
parent
0eac34b7ab
commit
48e0e05446
|
@ -60,15 +60,9 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
protected Dictionary<LLUUID, ScenePresence> m_scenePresences;
|
protected Dictionary<LLUUID, ScenePresence> m_scenePresences;
|
||||||
protected Dictionary<LLUUID, SceneObjectGroup> m_sceneObjects;
|
protected Dictionary<LLUUID, SceneObjectGroup> m_sceneObjects;
|
||||||
|
|
||||||
/// publicized so it can be accessed from SceneObjectGroup.
|
|
||||||
protected float timeStep = 0.1f;
|
|
||||||
|
|
||||||
private Random Rand = new Random();
|
private Random Rand = new Random();
|
||||||
private uint _primCount = 702000;
|
private uint _primCount = 702000;
|
||||||
private readonly Mutex _primAllocateMutex = new Mutex(false);
|
private readonly Mutex _primAllocateMutex = new Mutex(false);
|
||||||
private int storageCount;
|
|
||||||
private int terrainCheckCount;
|
|
||||||
private int landPrimCheckCount;
|
|
||||||
|
|
||||||
private int m_timePhase = 24;
|
private int m_timePhase = 24;
|
||||||
private int m_timeUpdateCount;
|
private int m_timeUpdateCount;
|
||||||
|
@ -98,6 +92,23 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
private IHttpRequests m_httpRequestModule = null;
|
private IHttpRequests m_httpRequestModule = null;
|
||||||
private ISimChat m_simChatModule = null;
|
private ISimChat m_simChatModule = null;
|
||||||
|
|
||||||
|
|
||||||
|
// Central Update Loop
|
||||||
|
|
||||||
|
protected int m_fps = 10;
|
||||||
|
protected int m_frame = 0;
|
||||||
|
protected float m_timespan = 0.1f;
|
||||||
|
protected DateTime m_lastupdate = DateTime.Now;
|
||||||
|
|
||||||
|
private int m_update_physics = 1;
|
||||||
|
private int m_update_entitymovement = 1;
|
||||||
|
private int m_update_entities = 1;
|
||||||
|
private int m_update_events = 1;
|
||||||
|
private int m_update_backup = 200;
|
||||||
|
private int m_update_terrain = 50;
|
||||||
|
private int m_update_land = 1;
|
||||||
|
private int m_update_avatars = 1;
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
public AgentCircuitManager AuthenticateHandler
|
public AgentCircuitManager AuthenticateHandler
|
||||||
|
@ -222,7 +233,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
public void StartTimer()
|
public void StartTimer()
|
||||||
{
|
{
|
||||||
m_heartbeatTimer.Enabled = true;
|
m_heartbeatTimer.Enabled = true;
|
||||||
m_heartbeatTimer.Interval = 100;
|
m_heartbeatTimer.Interval = (int)(m_timespan * 1000);
|
||||||
m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
|
m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,50 +254,108 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
|
TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate;
|
||||||
|
// Aquire a lock so only one update call happens at once
|
||||||
updateLock.WaitOne();
|
updateLock.WaitOne();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// Increment the frame counter
|
||||||
|
m_frame++;
|
||||||
|
|
||||||
|
// Loop it
|
||||||
|
if (m_frame == Int32.MaxValue)
|
||||||
|
m_frame = 0;
|
||||||
|
|
||||||
|
if (m_frame % m_update_physics == 0)
|
||||||
|
UpdatePreparePhysics();
|
||||||
|
|
||||||
|
if (m_frame % m_update_entitymovement == 0)
|
||||||
|
UpdateEntityMovement();
|
||||||
|
|
||||||
|
if (m_frame % m_update_physics == 0)
|
||||||
|
UpdatePhysics(
|
||||||
|
Math.Min(SinceLastFrame.TotalSeconds, 0.001)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (m_frame % m_update_entities == 0)
|
||||||
|
UpdateEntities();
|
||||||
|
|
||||||
|
if (m_frame % m_update_events == 0)
|
||||||
|
UpdateEvents();
|
||||||
|
|
||||||
|
if (m_frame % m_update_backup == 0)
|
||||||
|
UpdateStorageBackup();
|
||||||
|
|
||||||
|
if (m_frame % m_update_terrain == 0)
|
||||||
|
UpdateTerrain();
|
||||||
|
|
||||||
|
if (m_frame % m_update_land == 0)
|
||||||
|
UpdateLand();
|
||||||
|
|
||||||
|
if (m_frame % m_update_avatars == 0)
|
||||||
|
UpdateAvatars();
|
||||||
|
}
|
||||||
|
catch (NotImplementedException)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MainLog.Instance.Error("Scene", "Failed with exception " + e.ToString());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
updateLock.ReleaseMutex();
|
||||||
|
m_lastupdate = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdatePreparePhysics()
|
||||||
|
{
|
||||||
|
// If we are using a threaded physics engine
|
||||||
|
// grab the latest scene from the engine before
|
||||||
|
// trying to process it.
|
||||||
|
|
||||||
|
// PhysX does this (runs in the background).
|
||||||
|
|
||||||
if (phyScene.IsThreaded)
|
if (phyScene.IsThreaded)
|
||||||
{
|
{
|
||||||
phyScene.GetResults();
|
phyScene.GetResults();
|
||||||
/// no engines implement this, and what does it have to do with threading? possible DEAD CODE
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<EntityBase> moveEntities = new List<EntityBase>(Entities.Values);
|
private void UpdateAvatars()
|
||||||
|
|
||||||
foreach (EntityBase entity in moveEntities)
|
|
||||||
{
|
{
|
||||||
entity.UpdateMovement();
|
m_timeUpdateCount++;
|
||||||
|
if (m_timeUpdateCount > 600)
|
||||||
|
{
|
||||||
|
List<ScenePresence> avatars = GetAvatars();
|
||||||
|
foreach (ScenePresence avatar in avatars)
|
||||||
|
{
|
||||||
|
avatar.ControllingClient.SendViewerTime(m_timePhase);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (m_syncRoot)
|
m_timeUpdateCount = 0;
|
||||||
|
m_timePhase++;
|
||||||
|
if (m_timePhase > 94)
|
||||||
{
|
{
|
||||||
phyScene.Simulate(timeStep);
|
m_timePhase = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<EntityBase> updateEntities = new List<EntityBase>(Entities.Values);
|
private void UpdateLand()
|
||||||
|
|
||||||
foreach (EntityBase entity in updateEntities)
|
|
||||||
{
|
{
|
||||||
entity.Update();
|
if (m_LandManager.landPrimCountTainted)
|
||||||
|
{
|
||||||
|
//Perform land update of prim count
|
||||||
|
performParcelPrimCountUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// General purpose event manager
|
private void UpdateTerrain()
|
||||||
m_eventManager.TriggerOnFrame();
|
|
||||||
|
|
||||||
//backup scene data
|
|
||||||
storageCount++;
|
|
||||||
if (storageCount > 1200) //set to how often you want to backup
|
|
||||||
{
|
{
|
||||||
Backup();
|
|
||||||
storageCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
terrainCheckCount++;
|
|
||||||
if (terrainCheckCount >= 50)
|
|
||||||
{
|
|
||||||
terrainCheckCount = 0;
|
|
||||||
|
|
||||||
if (Terrain.Tainted())
|
if (Terrain.Tainted())
|
||||||
{
|
{
|
||||||
CreateTerrainTexture();
|
CreateTerrainTexture();
|
||||||
|
@ -323,43 +392,42 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
landPrimCheckCount++;
|
private void UpdateStorageBackup()
|
||||||
if (landPrimCheckCount > 50) //check every 5 seconds for tainted prims
|
|
||||||
{
|
{
|
||||||
if (m_LandManager.landPrimCountTainted)
|
Backup();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateEvents()
|
||||||
{
|
{
|
||||||
//Perform land update of prim count
|
m_eventManager.TriggerOnFrame();
|
||||||
performParcelPrimCountUpdate();
|
}
|
||||||
landPrimCheckCount = 0;
|
|
||||||
|
private void UpdateEntities()
|
||||||
|
{
|
||||||
|
List<EntityBase> updateEntities = new List<EntityBase>(Entities.Values);
|
||||||
|
|
||||||
|
foreach (EntityBase entity in updateEntities)
|
||||||
|
{
|
||||||
|
entity.Update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_timeUpdateCount++;
|
private void UpdatePhysics(double elapsed)
|
||||||
if (m_timeUpdateCount > 600)
|
|
||||||
{
|
{
|
||||||
List<ScenePresence> avatars = GetAvatars();
|
lock (m_syncRoot)
|
||||||
foreach (ScenePresence avatar in avatars)
|
|
||||||
{
|
{
|
||||||
avatar.ControllingClient.SendViewerTime(m_timePhase);
|
phyScene.Simulate((float)elapsed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_timeUpdateCount = 0;
|
private void UpdateEntityMovement()
|
||||||
m_timePhase++;
|
|
||||||
if (m_timePhase > 94)
|
|
||||||
{
|
{
|
||||||
m_timePhase = 0;
|
List<EntityBase> moveEntities = new List<EntityBase>(Entities.Values);
|
||||||
}
|
|
||||||
}
|
foreach (EntityBase entity in moveEntities)
|
||||||
}
|
|
||||||
catch (NotImplementedException)
|
|
||||||
{
|
{
|
||||||
throw;
|
entity.UpdateMovement();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
MainLog.Instance.Error("Scene", "Failed with exception " + e.ToString());
|
|
||||||
}
|
|
||||||
updateLock.ReleaseMutex();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Loading…
Reference in New Issue