* Fix Mantis 761 (linking and delinking prims rapidly caused prims to 'disappear')
* Root cause was that if two updates occurred in the same second of time, the second one was never sent * Linking/delinking appears to be okay now0.6.0-stable
parent
27ff09cb2b
commit
a4304fb9e6
|
@ -206,6 +206,12 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add an entity to the list of prims to process on the next update
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">
|
||||||
|
/// A <see cref="EntityBase"/>
|
||||||
|
/// </param>
|
||||||
internal void AddToUpdateList(EntityBase obj)
|
internal void AddToUpdateList(EntityBase obj)
|
||||||
{
|
{
|
||||||
lock (m_updateList)
|
lock (m_updateList)
|
||||||
|
|
|
@ -614,7 +614,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Start the timer which triggers regular scene updates
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void StartTimer()
|
public void StartTimer()
|
||||||
{
|
{
|
||||||
|
|
|
@ -247,9 +247,11 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
public SceneObjectGroup(Scene scene, ulong regionHandle, SceneObjectPart part)
|
public SceneObjectGroup(Scene scene, ulong regionHandle, SceneObjectPart part)
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
|
|
||||||
part.SetParent(this);
|
part.SetParent(this);
|
||||||
part.ParentID = 0;
|
part.ParentID = 0;
|
||||||
part.LinkNum = 0;
|
part.LinkNum = 0;
|
||||||
|
|
||||||
m_parts.Add(part.UUID, part);
|
m_parts.Add(part.UUID, part);
|
||||||
|
|
||||||
SetPartAsRoot(part);
|
SetPartAsRoot(part);
|
||||||
|
@ -691,7 +693,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
#region Scheduling
|
#region Scheduling
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Examine this object's parts to see if they've changed sufficiently to warrant an update
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
|
@ -703,6 +705,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
lastPhysGroupPos = AbsolutePosition;
|
lastPhysGroupPos = AbsolutePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1)
|
if ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1)
|
||||||
|| (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1)
|
|| (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1)
|
||||||
|| (Math.Abs(lastPhysGroupRot.Y - GroupRotation.Y) > 0.1)
|
|| (Math.Abs(lastPhysGroupRot.Y - GroupRotation.Y) > 0.1)
|
||||||
|
@ -714,6 +717,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
lastPhysGroupRot = GroupRotation;
|
lastPhysGroupRot = GroupRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
part.SendScheduledUpdates();
|
part.SendScheduledUpdates();
|
||||||
|
@ -737,7 +741,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Schedule a full update for every part in this object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ScheduleGroupForFullUpdate()
|
public void ScheduleGroupForFullUpdate()
|
||||||
{
|
{
|
||||||
|
@ -910,6 +914,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
linkPart.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w);
|
linkPart.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w);
|
||||||
|
|
||||||
linkPart.ParentID = m_rootPart.LocalId;
|
linkPart.ParentID = m_rootPart.LocalId;
|
||||||
|
|
||||||
linkPart.LinkNum = m_parts.Count;
|
linkPart.LinkNum = m_parts.Count;
|
||||||
|
|
||||||
m_parts.Add(linkPart.UUID, linkPart);
|
m_parts.Add(linkPart.UUID, linkPart);
|
||||||
|
@ -1715,6 +1720,9 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
m_scene.EventManager.TriggerGroupGrab(UUID, offsetPos, remoteClient.AgentId);
|
m_scene.EventManager.TriggerGroupGrab(UUID, offsetPos, remoteClient.AgentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Completely delete this group and tell all the scene presences about that deletion.
|
||||||
|
/// </summary>
|
||||||
public void DeleteGroup()
|
public void DeleteGroup()
|
||||||
{
|
{
|
||||||
DetachFromBackup(this);
|
DetachFromBackup(this);
|
||||||
|
|
|
@ -132,7 +132,12 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
[XmlIgnore] public uint TimeStampLastActivity = 0; // Will be used for AutoReturn
|
[XmlIgnore] public uint TimeStampLastActivity = 0; // Will be used for AutoReturn
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Only used internally to schedule client updates
|
/// Only used internally to schedule client updates.
|
||||||
|
/// 0 - no update is scheduled
|
||||||
|
/// 1 - terse update scheduled
|
||||||
|
/// 2 - full update scheduled
|
||||||
|
///
|
||||||
|
/// TODO - This should be an enumeration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private byte m_updateFlag;
|
private byte m_updateFlag;
|
||||||
|
|
||||||
|
@ -1090,7 +1095,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
#region Update Scheduling
|
#region Update Scheduling
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Clear all pending updates
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void ClearUpdateSchedule()
|
private void ClearUpdateSchedule()
|
||||||
{
|
{
|
||||||
|
@ -1098,7 +1103,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Schedules this prim for a full update
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ScheduleFullUpdate()
|
public void ScheduleFullUpdate()
|
||||||
{
|
{
|
||||||
|
@ -1107,6 +1112,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
m_parentGroup.HasGroupChanged = true;
|
m_parentGroup.HasGroupChanged = true;
|
||||||
m_parentGroup.QueueForUpdateCheck();
|
m_parentGroup.QueueForUpdateCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeStampFull = (uint) Util.UnixTimeSinceEpoch();
|
TimeStampFull = (uint) Util.UnixTimeSinceEpoch();
|
||||||
m_updateFlag = 2;
|
m_updateFlag = 2;
|
||||||
}
|
}
|
||||||
|
@ -1156,7 +1162,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Tell all the prims which have had updates scheduled
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendScheduledUpdates()
|
public void SendScheduledUpdates()
|
||||||
{
|
{
|
||||||
|
@ -1689,6 +1695,9 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
#region Client Update Methods
|
#region Client Update Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tell all scene presences that they should send updates for this part to their clients
|
||||||
|
/// </summary>
|
||||||
public void AddFullUpdateToAllAvatars()
|
public void AddFullUpdateToAllAvatars()
|
||||||
{
|
{
|
||||||
List<ScenePresence> avatars = m_parentGroup.GetScenePresences();
|
List<ScenePresence> avatars = m_parentGroup.GetScenePresences();
|
||||||
|
@ -1697,6 +1706,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
avatars[i].QueuePartForUpdate(this);
|
avatars[i].QueuePartForUpdate(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendFullUpdateToAllClientsExcept(LLUUID agentID)
|
public void SendFullUpdateToAllClientsExcept(LLUUID agentID)
|
||||||
{
|
{
|
||||||
List<ScenePresence> avatars = m_parentGroup.GetScenePresences();
|
List<ScenePresence> avatars = m_parentGroup.GetScenePresences();
|
||||||
|
@ -1710,6 +1720,8 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void AddFullUpdateToAvatar(ScenePresence presence)
|
public void AddFullUpdateToAvatar(ScenePresence presence)
|
||||||
{
|
{
|
||||||
presence.QueuePartForUpdate(this);
|
presence.QueuePartForUpdate(this);
|
||||||
|
|
|
@ -418,6 +418,10 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add the part to the queue of parts for which we need to send an update to the client
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="part"></param>
|
||||||
public void QueuePartForUpdate(SceneObjectPart part)
|
public void QueuePartForUpdate(SceneObjectPart part)
|
||||||
{
|
{
|
||||||
//if (InterestList.Contains(part.ParentGroup))
|
//if (InterestList.Contains(part.ParentGroup))
|
||||||
|
@ -434,6 +438,11 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
return m_scene.PermissionsMngr.GenerateClientFlags(m_uuid, ObjectID);
|
return m_scene.PermissionsMngr.GenerateClientFlags(m_uuid, ObjectID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send updates to the client about prims which have been placed on the update queue. We don't
|
||||||
|
/// necessarily send updates for all the parts on the queue, e.g. if an updates with a more recent
|
||||||
|
/// timestamp has already been sent.
|
||||||
|
/// </summary>
|
||||||
public void SendPrimUpdates()
|
public void SendPrimUpdates()
|
||||||
{
|
{
|
||||||
// if (m_scene.QuadTree.GetNodeID(this.AbsolutePosition.X, this.AbsolutePosition.Y) != m_currentQuadNode)
|
// if (m_scene.QuadTree.GetNodeID(this.AbsolutePosition.X, this.AbsolutePosition.Y) != m_currentQuadNode)
|
||||||
|
@ -447,12 +456,11 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
{
|
{
|
||||||
if (!m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor)
|
if (!m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor)
|
||||||
{
|
{
|
||||||
|
|
||||||
m_scene.SendAllSceneObjectsToClient(this);
|
m_scene.SendAllSceneObjectsToClient(this);
|
||||||
m_gotAllObjectsInScene = true;
|
m_gotAllObjectsInScene = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_partsUpdateQueue.Count > 0)
|
if (m_partsUpdateQueue.Count > 0)
|
||||||
{
|
{
|
||||||
bool runUpdate = true;
|
bool runUpdate = true;
|
||||||
|
@ -465,16 +473,18 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
ScenePartUpdate update = m_updateTimes[part.UUID];
|
ScenePartUpdate update = m_updateTimes[part.UUID];
|
||||||
|
|
||||||
// Two updates can occur with the same timestamp (especially
|
// Two updates can occur with the same timestamp (especially
|
||||||
// since our timestamp resolution is to the nearest second). The first
|
// since our timestamp resolution is to the nearest second). Therefore, we still need
|
||||||
// could have been sent in the last update - we still need to send the
|
// to send an update even if the last full update time is identical to the part's
|
||||||
// second here.
|
// update timestamp.
|
||||||
|
//
|
||||||
if (update.LastFullUpdateTime < part.TimeStampFull)
|
// If we don't do this, various events (such as linking and delinking in the same
|
||||||
|
// second), will stop working properly!
|
||||||
|
if (update.LastFullUpdateTime <= part.TimeStampFull)
|
||||||
{
|
{
|
||||||
//need to do a full update
|
//need to do a full update
|
||||||
part.SendFullUpdate(ControllingClient, GenerateClientFlags(part.UUID));
|
part.SendFullUpdate(ControllingClient, GenerateClientFlags(part.UUID));
|
||||||
|
|
||||||
// We'll update to the part's timestamp rather than the current to
|
// We'll update to the part's timestamp rather than the current time to
|
||||||
// avoid the race condition whereby the next tick occurs while we are
|
// avoid the race condition whereby the next tick occurs while we are
|
||||||
// doing this update. If this happened, then subsequent updates which occurred
|
// doing this update. If this happened, then subsequent updates which occurred
|
||||||
// on the same tick or the next tick of the last update would be ignored.
|
// on the same tick or the next tick of the last update would be ignored.
|
||||||
|
|
Loading…
Reference in New Issue