Update svn properties.

0.6.6-post-fixes
Jeff Ames 2009-06-27 04:31:49 +00:00
parent 9e4d077d70
commit 2d173d7556
2 changed files with 244 additions and 244 deletions

View File

@ -1,14 +1,14 @@
using System; using System;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.Framework.Interfaces namespace OpenSim.Region.Framework.Interfaces
{ {
public interface ISceneViewer public interface ISceneViewer
{ {
void Reset(); void Reset();
void Close(); void Close();
int MaxPrimsPerFrame { get; set; } int MaxPrimsPerFrame { get; set; }
void QueuePartForUpdate(SceneObjectPart part); void QueuePartForUpdate(SceneObjectPart part);
void SendPrimUpdates(); void SendPrimUpdates();
} }
} }

View File

@ -1,230 +1,230 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the * * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using OpenMetaverse; using OpenMetaverse;
using log4net; using log4net;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Client; using OpenSim.Framework.Client;
using OpenSim.Framework.Communications.Cache; using OpenSim.Framework.Communications.Cache;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes.Types; using OpenSim.Region.Framework.Scenes.Types;
namespace OpenSim.Region.Framework.Scenes namespace OpenSim.Region.Framework.Scenes
{ {
public class SceneViewer : ISceneViewer public class SceneViewer : ISceneViewer
{ {
protected ScenePresence m_presence; protected ScenePresence m_presence;
protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); protected UpdateQueue m_partsUpdateQueue = new UpdateQueue();
protected Queue<SceneObjectGroup> m_pendingObjects; protected Queue<SceneObjectGroup> m_pendingObjects;
protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>();
protected int m_maxPrimsPerFrame = 200; protected int m_maxPrimsPerFrame = 200;
public int MaxPrimsPerFrame public int MaxPrimsPerFrame
{ {
get { return m_maxPrimsPerFrame; } get { return m_maxPrimsPerFrame; }
set { m_maxPrimsPerFrame = value; } set { m_maxPrimsPerFrame = value; }
} }
public SceneViewer() public SceneViewer()
{ {
} }
public SceneViewer(ScenePresence presence) public SceneViewer(ScenePresence presence)
{ {
m_presence = presence; m_presence = presence;
} }
/// <summary> /// <summary>
/// Add the part to the queue of parts for which we need to send an update to the client /// Add the part to the queue of parts for which we need to send an update to the client
/// </summary> /// </summary>
/// <param name="part"></param> /// <param name="part"></param>
public void QueuePartForUpdate(SceneObjectPart part) public void QueuePartForUpdate(SceneObjectPart part)
{ {
lock (m_partsUpdateQueue) lock (m_partsUpdateQueue)
{ {
m_partsUpdateQueue.Enqueue(part); m_partsUpdateQueue.Enqueue(part);
} }
} }
public void SendPrimUpdates() public void SendPrimUpdates()
{ {
if (m_pendingObjects == null) if (m_pendingObjects == null)
{ {
if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor)) if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor))
{ {
m_pendingObjects = new Queue<SceneObjectGroup>(); m_pendingObjects = new Queue<SceneObjectGroup>();
List<EntityBase> ents = new List<EntityBase>(m_presence.Scene.Entities); List<EntityBase> ents = new List<EntityBase>(m_presence.Scene.Entities);
if (!m_presence.IsChildAgent) // Proximity sort makes no sense for if (!m_presence.IsChildAgent) // Proximity sort makes no sense for
{ // Child agents { // Child agents
ents.Sort(delegate(EntityBase a, EntityBase b) ents.Sort(delegate(EntityBase a, EntityBase b)
{ {
return Vector3.Distance(m_presence.AbsolutePosition, a.AbsolutePosition).CompareTo(Vector3.Distance(m_presence.AbsolutePosition, b.AbsolutePosition)); return Vector3.Distance(m_presence.AbsolutePosition, a.AbsolutePosition).CompareTo(Vector3.Distance(m_presence.AbsolutePosition, b.AbsolutePosition));
}); });
} }
foreach (EntityBase e in ents) foreach (EntityBase e in ents)
{ {
if (e is SceneObjectGroup) if (e is SceneObjectGroup)
m_pendingObjects.Enqueue((SceneObjectGroup)e); m_pendingObjects.Enqueue((SceneObjectGroup)e);
} }
} }
} }
while (m_pendingObjects != null && m_pendingObjects.Count > 0 && m_partsUpdateQueue.Count < m_maxPrimsPerFrame) while (m_pendingObjects != null && m_pendingObjects.Count > 0 && m_partsUpdateQueue.Count < m_maxPrimsPerFrame)
{ {
SceneObjectGroup g = m_pendingObjects.Dequeue(); SceneObjectGroup g = m_pendingObjects.Dequeue();
// This is where we should check for draw distance // This is where we should check for draw distance
// do culling and stuff. Problem with that is that until // do culling and stuff. Problem with that is that until
// we recheck in movement, that won't work right. // we recheck in movement, that won't work right.
// So it's not implemented now. // So it's not implemented now.
// //
// Don't even queue if we have sent this one // Don't even queue if we have sent this one
// //
if (!m_updateTimes.ContainsKey(g.UUID)) if (!m_updateTimes.ContainsKey(g.UUID))
g.ScheduleFullUpdateToAvatar(m_presence); g.ScheduleFullUpdateToAvatar(m_presence);
} }
while (m_partsUpdateQueue.Count > 0) while (m_partsUpdateQueue.Count > 0)
{ {
SceneObjectPart part = m_partsUpdateQueue.Dequeue(); SceneObjectPart part = m_partsUpdateQueue.Dequeue();
if (part.ParentGroup == null || part.ParentGroup.IsDeleted) if (part.ParentGroup == null || part.ParentGroup.IsDeleted)
continue; continue;
if (m_updateTimes.ContainsKey(part.UUID)) if (m_updateTimes.ContainsKey(part.UUID))
{ {
ScenePartUpdate update = m_updateTimes[part.UUID]; ScenePartUpdate update = m_updateTimes[part.UUID];
// We deal with the possibility that two updates occur at // We deal with the possibility that two updates occur at
// the same unix time at the update point itself. // the same unix time at the update point itself.
if ((update.LastFullUpdateTime < part.TimeStampFull) || if ((update.LastFullUpdateTime < part.TimeStampFull) ||
part.IsAttachment) part.IsAttachment)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}",
// part.Name, part.UUID, part.TimeStampFull); // part.Name, part.UUID, part.TimeStampFull);
part.SendFullUpdate(m_presence.ControllingClient, part.SendFullUpdate(m_presence.ControllingClient,
m_presence.GenerateClientFlags(part.UUID)); m_presence.GenerateClientFlags(part.UUID));
// We'll update to the part's timestamp rather than // We'll update to the part's timestamp rather than
// the current time to avoid the race condition // the current time to avoid the race condition
// whereby the next tick occurs while we are doing // whereby the next tick occurs while we are doing
// this update. If this happened, then subsequent // this update. If this happened, then subsequent
// updates which occurred on the same tick or the // updates which occurred on the same tick or the
// next tick of the last update would be ignored. // next tick of the last update would be ignored.
update.LastFullUpdateTime = part.TimeStampFull; update.LastFullUpdateTime = part.TimeStampFull;
} }
else if (update.LastTerseUpdateTime <= part.TimeStampTerse) else if (update.LastTerseUpdateTime <= part.TimeStampTerse)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}",
// part.Name, part.UUID, part.TimeStampTerse); // part.Name, part.UUID, part.TimeStampTerse);
part.SendTerseUpdateToClient(m_presence.ControllingClient); part.SendTerseUpdateToClient(m_presence.ControllingClient);
update.LastTerseUpdateTime = part.TimeStampTerse; update.LastTerseUpdateTime = part.TimeStampTerse;
} }
} }
else else
{ {
//never been sent to client before so do full update //never been sent to client before so do full update
ScenePartUpdate update = new ScenePartUpdate(); ScenePartUpdate update = new ScenePartUpdate();
update.FullID = part.UUID; update.FullID = part.UUID;
update.LastFullUpdateTime = part.TimeStampFull; update.LastFullUpdateTime = part.TimeStampFull;
m_updateTimes.Add(part.UUID, update); m_updateTimes.Add(part.UUID, update);
// Attachment handling // Attachment handling
// //
if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0) if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0)
{ {
if (part != part.ParentGroup.RootPart) if (part != part.ParentGroup.RootPart)
continue; continue;
part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient); part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient);
continue; continue;
} }
part.SendFullUpdate(m_presence.ControllingClient, part.SendFullUpdate(m_presence.ControllingClient,
m_presence.GenerateClientFlags(part.UUID)); m_presence.GenerateClientFlags(part.UUID));
} }
} }
m_presence.ControllingClient.FlushPrimUpdates(); m_presence.ControllingClient.FlushPrimUpdates();
} }
public void Reset() public void Reset()
{ {
if (m_pendingObjects != null) if (m_pendingObjects != null)
{ {
lock (m_pendingObjects) lock (m_pendingObjects)
{ {
m_pendingObjects.Clear(); m_pendingObjects.Clear();
m_pendingObjects = null; m_pendingObjects = null;
} }
} }
} }
public void Close() public void Close()
{ {
lock (m_updateTimes) lock (m_updateTimes)
{ {
m_updateTimes.Clear(); m_updateTimes.Clear();
} }
lock (m_partsUpdateQueue) lock (m_partsUpdateQueue)
{ {
m_partsUpdateQueue.Clear(); m_partsUpdateQueue.Clear();
} }
Reset(); Reset();
} }
public class ScenePartUpdate public class ScenePartUpdate
{ {
public UUID FullID; public UUID FullID;
public uint LastFullUpdateTime; public uint LastFullUpdateTime;
public uint LastTerseUpdateTime; public uint LastTerseUpdateTime;
public ScenePartUpdate() public ScenePartUpdate()
{ {
FullID = UUID.Zero; FullID = UUID.Zero;
LastFullUpdateTime = 0; LastFullUpdateTime = 0;
LastTerseUpdateTime = 0; LastTerseUpdateTime = 0;
} }
} }
} }
} }