From 95130df78aa8fc86384d889c0a8884cc22007e88 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Wed, 5 May 2010 16:51:41 -0700 Subject: [PATCH] * Changed many more "terse" and "full" update sending and update scheduling methods to take PrimUpdateFlags instead * Disabled m_killRecord until the issue of avatars keeping the same localID when TPing away and back can be resolved --- OpenSim/Data/Tests/BasicRegionTest.cs | 5 - .../ClientStack/LindenUDP/LLClientView.cs | 3 - .../EntityTransfer/EntityTransferModule.cs | 4 +- .../InventoryAccess/InventoryAccessModule.cs | 4 +- .../Framework/Interfaces/ISceneViewer.cs | 3 +- .../Framework/Scenes/Scene.Inventory.cs | 6 +- .../Framework/Scenes/Scene.PacketHandlers.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 8 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 10 +- .../Framework/Scenes/SceneObjectGroup.cs | 85 +++---- .../Framework/Scenes/SceneObjectPart.cs | 228 +++++++----------- .../Scenes/SceneObjectPartInventory.cs | 6 +- .../Region/Framework/Scenes/ScenePresence.cs | 7 +- .../Region/Framework/Scenes/SceneViewer.cs | 59 ++--- .../Scenes/Tests/SceneObjectLinkingTests.cs | 16 +- .../Framework/Scenes/Types/UpdateQueue.cs | 36 +-- OpenSim/Region/Framework/Scenes/UndoState.cs | 12 +- .../ContentManagementSystem/CMModel.cs | 2 +- .../TreePopulator/TreePopulatorModule.cs | 4 +- .../Shared/Api/Implementation/LSL_Api.cs | 38 +-- 20 files changed, 219 insertions(+), 319 deletions(-) diff --git a/OpenSim/Data/Tests/BasicRegionTest.cs b/OpenSim/Data/Tests/BasicRegionTest.cs index dfbf5228ec..90fdb92dba 100644 --- a/OpenSim/Data/Tests/BasicRegionTest.cs +++ b/OpenSim/Data/Tests/BasicRegionTest.cs @@ -245,7 +245,6 @@ namespace OpenSim.Data.Tests pbshap.ProfileEnd = ushort.MaxValue; pbshap.ProfileHollow = ushort.MaxValue; Vector3 scale = new Vector3(random.Next(),random.Next(),random.Next()); - byte updatef = (byte) random.Next(127); RegionInfo regionInfo = new RegionInfo(); regionInfo.RegionID = region3; @@ -284,7 +283,6 @@ namespace OpenSim.Data.Tests sop.LinkNum = linknum; sop.ClickAction = clickaction; sop.Scale = scale; - sop.UpdateFlag = updatef; //Tests if local part accepted the parameters: Assert.That(regionh,Is.EqualTo(sop.RegionHandle), "Assert.That(regionh,Is.EqualTo(sop.RegionHandle))"); @@ -317,7 +315,6 @@ namespace OpenSim.Data.Tests Assert.That(linknum,Is.EqualTo(sop.LinkNum), "Assert.That(linknum,Is.EqualTo(sop.LinkNum))"); Assert.That(clickaction,Is.EqualTo(sop.ClickAction), "Assert.That(clickaction,Is.EqualTo(sop.ClickAction))"); Assert.That(scale,Is.EqualTo(sop.Scale), "Assert.That(scale,Is.EqualTo(sop.Scale))"); - Assert.That(updatef,Is.EqualTo(sop.UpdateFlag), "Assert.That(updatef,Is.EqualTo(sop.UpdateFlag))"); // This is necessary or object will not be inserted in DB sop.ObjectFlags = 0; @@ -417,7 +414,6 @@ namespace OpenSim.Data.Tests PrimitiveBaseShape pbshap = new PrimitiveBaseShape(); pbshap = PrimitiveBaseShape.Default; Vector3 scale = new Vector3(random.Next(),random.Next(),random.Next()); - byte updatef = (byte) random.Next(127); // Updates the region with new values SceneObjectGroup sog2 = FindSOG("Adam West", region3); @@ -447,7 +443,6 @@ namespace OpenSim.Data.Tests sog2.RootPart.LinkNum = linknum; sog2.RootPart.ClickAction = clickaction; sog2.RootPart.Scale = scale; - sog2.RootPart.UpdateFlag = updatef; db.StoreObject(sog2, region3); List sogs = db.LoadObjects(region3); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 2415791a98..99ea4adae3 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -3450,9 +3450,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP while ((update = m_entityUpdates.Dequeue()) != null) { - if (m_killRecord.Contains(update.Entity.LocalId)) - continue; - #region UpdateFlags to packet type conversion PrimUpdateFlags updateFlags = update.Flags; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 80c0af8461..4ec09ba51c 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1446,7 +1446,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (destination != null && !CrossPrimGroupIntoNewRegion(destination, grp, silent)) { grp.OffsetForNewRegion(oldGroupPosition); - grp.ScheduleGroupForFullUpdate(); + grp.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); } } @@ -1465,7 +1465,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<"); bool successYN = false; - grp.RootPart.UpdateFlag = 0; + grp.RootPart.ClearPendingUpdate(); //int primcrossingXMLmethod = 0; if (destination != null) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 2352cedef4..1035478df3 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -511,7 +511,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // if not, we set it's position in world. if (!attachment) { - group.ScheduleGroupForFullUpdate(); + group.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); float offsetHeight = 0; pos = m_Scene.GetNewRezLocation( @@ -603,7 +603,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0); rootPart.ParentGroup.ResumeScripts(); - rootPart.ScheduleFullUpdate(); + rootPart.ScheduleUpdate(PrimUpdateFlags.FullUpdate); } if (!m_Scene.Permissions.BypassPermissions()) diff --git a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs index 7251d57f69..7411d1b754 100644 --- a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs +++ b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs @@ -26,6 +26,7 @@ */ using System; +using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.Framework.Interfaces @@ -34,7 +35,7 @@ namespace OpenSim.Region.Framework.Interfaces { void Reset(); void Close(); - void QueuePartForUpdate(SceneObjectPart part); + void QueuePartForUpdate(SceneObjectPart part, PrimUpdateFlags updateFlags); void SendPrimUpdates(); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 20760b2ad8..0a83421a28 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1857,10 +1857,10 @@ namespace OpenSim.Region.Framework.Scenes { group.RootPart.ApplyImpulse((vel * group.GetMass()), false); group.Velocity = vel; - rootPart.ScheduleFullUpdate(); + rootPart.ScheduleUpdate(PrimUpdateFlags.FullUpdate); } group.CreateScriptInstances(param, true, DefaultScriptEngine, 2); - rootPart.ScheduleFullUpdate(); + rootPart.ScheduleUpdate(PrimUpdateFlags.FullUpdate); if (!Permissions.BypassPermissions()) { @@ -1929,7 +1929,7 @@ namespace OpenSim.Region.Framework.Scenes { sog.SetOwnerId(ownerID); sog.SetGroup(groupID, remoteClient); - sog.ScheduleGroupForFullUpdate(); + sog.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); foreach (SceneObjectPart child in sog.Children.Values) child.Inventory.ChangeInventoryOwner(ownerID); diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 600c9cd1be..a888e305a1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -208,7 +208,7 @@ namespace OpenSim.Region.Framework.Scenes if (part.ParentGroup.IsAttachment) isAttachment = true; else - part.ParentGroup.ScheduleGroupForFullUpdate(); + part.ParentGroup.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); // If it's not an attachment, and we are allowed to move it, // then we might have done so. If we moved across a parcel diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 1a46837d60..20aa83e8d8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2051,7 +2051,7 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.SetGroup(groupID, null); } - sceneObject.ScheduleGroupForFullUpdate(); + sceneObject.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); return sceneObject; } @@ -2541,7 +2541,7 @@ namespace OpenSim.Region.Framework.Scenes sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false); RootPrim.RemFlag(PrimFlags.TemporaryOnRez); - grp.SendGroupFullUpdate(); + grp.SendGroupUpdate(PrimUpdateFlags.FullUpdate); } else { @@ -4037,7 +4037,7 @@ namespace OpenSim.Region.Framework.Scenes { if (ent is SceneObjectGroup) { - ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(); + ((SceneObjectGroup)ent).ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); } } } @@ -4538,7 +4538,7 @@ namespace OpenSim.Region.Framework.Scenes part.GetProperties(remoteClient); part.TriggerScriptChangedEvent(Changed.OWNER); group.ResumeScripts(); - part.ScheduleFullUpdate(); + part.ScheduleUpdate(PrimUpdateFlags.FullUpdate); break; diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index cc314d7244..dbf0e463af 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -297,7 +297,7 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.AttachToScene(m_parentScene); if (sendClientUpdates) - sceneObject.ScheduleGroupForFullUpdate(); + sceneObject.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); lock (sceneObject) { @@ -1512,7 +1512,7 @@ namespace OpenSim.Region.Framework.Scenes parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); parentGroup.TriggerScriptChangedEvent(Changed.LINK); parentGroup.HasGroupChanged = true; - parentGroup.ScheduleGroupForFullUpdate(); + parentGroup.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); } finally @@ -1612,7 +1612,7 @@ namespace OpenSim.Region.Framework.Scenes List linkIDs = new List(); foreach (SceneObjectPart newChild in newSet) - newChild.UpdateFlag = 0; + newChild.ClearPendingUpdate(); LinkObjects(newRoot, newSet); if (!affectedGroups.Contains(newRoot.ParentGroup)) @@ -1627,7 +1627,7 @@ namespace OpenSim.Region.Framework.Scenes { g.TriggerScriptChangedEvent(Changed.LINK); g.HasGroupChanged = true; // Persist - g.ScheduleGroupForFullUpdate(); + g.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); } } finally @@ -1735,7 +1735,7 @@ namespace OpenSim.Region.Framework.Scenes copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 0); copy.HasGroupChanged = true; - copy.ScheduleGroupForFullUpdate(); + copy.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); copy.ResumeScripts(); // required for physics to update it's position diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 82e43ae65c..1488acf2ea 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1001,7 +1001,7 @@ namespace OpenSim.Region.Framework.Scenes } IsSelected = false; // fudge.... - ScheduleGroupForFullUpdate(); + ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); } } else @@ -1052,7 +1052,7 @@ namespace OpenSim.Region.Framework.Scenes RootPart.RemFlag(PrimFlags.TemporaryOnRez); AttachToBackup(); m_scene.EventManager.TriggerParcelPrimCountTainted(); - m_rootPart.ScheduleFullUpdate(); + m_rootPart.ScheduleUpdate(PrimUpdateFlags.ParentID); m_rootPart.ClearUndoState(); } @@ -1277,7 +1277,7 @@ namespace OpenSim.Region.Framework.Scenes if (!silent) { - part.UpdateFlag = 0; + part.ClearPendingUpdate(); if (part == m_rootPart) avatar.ControllingClient.SendKillObject(m_regionHandle, part.LocalId); } @@ -1339,7 +1339,7 @@ namespace OpenSim.Region.Framework.Scenes m_scene.RemoveGroupTarget(this); } - ScheduleGroupForFullUpdate(); + ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); } public override void SetText(string text, Vector3 color, double alpha) @@ -1351,7 +1351,7 @@ namespace OpenSim.Region.Framework.Scenes Text = text; HasGroupChanged = true; - m_rootPart.ScheduleFullUpdate(); + m_rootPart.ScheduleUpdate(PrimUpdateFlags.Text); } /// @@ -1563,7 +1563,7 @@ namespace OpenSim.Region.Framework.Scenes if (userExposed) { SetRootPartOwner(m_rootPart, cAgentID, cGroupID); - m_rootPart.ScheduleFullUpdate(); + m_rootPart.ScheduleUpdate(PrimUpdateFlags.FullUpdate); } List partList; @@ -1590,7 +1590,7 @@ namespace OpenSim.Region.Framework.Scenes if (userExposed) { SetPartOwner(newPart, cAgentID, cGroupID); - newPart.ScheduleFullUpdate(); + newPart.ScheduleUpdate(PrimUpdateFlags.FullUpdate); } } } @@ -1601,7 +1601,7 @@ namespace OpenSim.Region.Framework.Scenes dupe.HasGroupChanged = true; dupe.AttachToBackup(); - ScheduleGroupForFullUpdate(); + ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); } return dupe; @@ -1854,7 +1854,7 @@ namespace OpenSim.Region.Framework.Scenes ApplyNextOwnerPermissions(); } - part.ScheduleFullUpdate(); + part.ScheduleUpdate(PrimUpdateFlags.FullUpdate); } /// @@ -1940,13 +1940,13 @@ namespace OpenSim.Region.Framework.Scenes if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f)) { - m_rootPart.UpdateFlag = 1; + m_rootPart.PendingUpdateFlags |= PrimUpdateFlags.Position; lastPhysGroupPos = AbsolutePosition; } if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f)) { - m_rootPart.UpdateFlag = 1; + m_rootPart.PendingUpdateFlags |= PrimUpdateFlags.Rotation; lastPhysGroupRot = GroupRotation; } @@ -1959,31 +1959,18 @@ namespace OpenSim.Region.Framework.Scenes } } - public void ScheduleFullUpdateToAvatar(ScenePresence presence) + public void ScheduleUpdateToAvatar(ScenePresence presence, PrimUpdateFlags updateFlags) { // m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); - RootPart.AddFullUpdateToAvatar(presence); + RootPart.AddUpdateToAvatar(presence, updateFlags); lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) { if (part != RootPart) - part.AddFullUpdateToAvatar(presence); - } - } - } - - public void ScheduleTerseUpdateToAvatar(ScenePresence presence) - { -// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); - - lock (m_parts) - { - foreach (SceneObjectPart part in m_parts.Values) - { - part.AddTerseUpdateToAvatar(presence); + part.AddUpdateToAvatar(presence, updateFlags); } } } @@ -1991,35 +1978,19 @@ namespace OpenSim.Region.Framework.Scenes /// /// Schedule a full update for this scene object /// - public void ScheduleGroupForFullUpdate() + public void ScheduleGroupForUpdate(PrimUpdateFlags updateFlags) { // m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID); checkAtTargets(); - RootPart.ScheduleFullUpdate(); + RootPart.ScheduleUpdate(updateFlags); lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) { if (part != RootPart) - part.ScheduleFullUpdate(); - } - } - } - - /// - /// Schedule a terse update for this scene object - /// - public void ScheduleGroupForTerseUpdate() - { -// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); - - lock (m_parts) - { - foreach (SceneObjectPart part in m_parts.Values) - { - part.ScheduleTerseUpdate(); + part.ScheduleUpdate(updateFlags); } } } @@ -2027,21 +1998,21 @@ namespace OpenSim.Region.Framework.Scenes /// /// Immediately send a full update for this scene object. /// - public void SendGroupFullUpdate() + public void SendGroupUpdate(PrimUpdateFlags updateFlags) { if (IsDeleted) return; // m_log.DebugFormat("[SOG]: Sending immediate full group update for {0} {1}", Name, UUID); - RootPart.SendUpdateToAllClients(PrimUpdateFlags.FullUpdate); + RootPart.SendUpdateToAllClients(updateFlags); lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) { if (part != RootPart) - part.SendUpdateToAllClients(PrimUpdateFlags.FullUpdate); + part.SendUpdateToAllClients(updateFlags); } } } @@ -2779,7 +2750,7 @@ namespace OpenSim.Region.Framework.Scenes //if (part.UUID != m_rootPart.UUID) HasGroupChanged = true; - ScheduleGroupForFullUpdate(); + ScheduleGroupForUpdate(PrimUpdateFlags.Scale); //if (part.UUID == m_rootPart.UUID) //{ @@ -2931,7 +2902,7 @@ namespace OpenSim.Region.Framework.Scenes part.IgnoreUndoUpdate = false; part.StoreUndoState(); HasGroupChanged = true; - ScheduleGroupForTerseUpdate(); + ScheduleGroupForUpdate(PrimUpdateFlags.Position); } } @@ -2972,7 +2943,7 @@ namespace OpenSim.Region.Framework.Scenes //we need to do a terse update even if the move wasn't allowed // so that the position is reset in the client (the object snaps back) - ScheduleGroupForTerseUpdate(); + ScheduleGroupForUpdate(PrimUpdateFlags.Position); } /// @@ -3037,7 +3008,7 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = newPos; HasGroupChanged = true; - ScheduleGroupForTerseUpdate(); + ScheduleGroupForUpdate(PrimUpdateFlags.Position); } public void OffsetForNewRegion(Vector3 offset) @@ -3069,7 +3040,7 @@ namespace OpenSim.Region.Framework.Scenes } HasGroupChanged = true; - ScheduleGroupForTerseUpdate(); + ScheduleGroupForUpdate(PrimUpdateFlags.Position | PrimUpdateFlags.Rotation); } /// @@ -3095,7 +3066,7 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = pos; HasGroupChanged = true; - ScheduleGroupForTerseUpdate(); + ScheduleGroupForUpdate(PrimUpdateFlags.Position | PrimUpdateFlags.Rotation); } /// @@ -3181,7 +3152,7 @@ namespace OpenSim.Region.Framework.Scenes Quaternion newRot = primsRot * oldParentRot; newRot *= Quaternion.Inverse(axRot); prim.RotationOffset = newRot; - prim.ScheduleTerseUpdate(); + prim.ScheduleUpdate(PrimUpdateFlags.Position | PrimUpdateFlags.Rotation); } } } @@ -3193,7 +3164,7 @@ namespace OpenSim.Region.Framework.Scenes childpart.StoreUndoState(); } } - m_rootPart.ScheduleTerseUpdate(); + m_rootPart.ScheduleUpdate(PrimUpdateFlags.Position | PrimUpdateFlags.Rotation); } #endregion diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 5de004646b..0ed19c9fa0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -168,13 +168,10 @@ namespace OpenSim.Region.Framework.Scenes public double SoundRadius; [XmlIgnore] - public uint TimeStampFull; + public uint TimeStampUpdate; [XmlIgnore] public uint TimeStampLastActivity; // Will be used for AutoReturn - - [XmlIgnore] - public uint TimeStampTerse; [XmlIgnore] public UUID FromItemID; @@ -282,15 +279,8 @@ namespace OpenSim.Region.Framework.Scenes private bool m_passTouches; - /// - /// 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 - /// - private byte m_updateFlag; + /// Modified fields that need to be broadcast + private PrimUpdateFlags m_pendingUpdateFlags; protected Vector3 m_acceleration; protected Vector3 m_angularVelocity; @@ -961,10 +951,10 @@ namespace OpenSim.Region.Framework.Scenes TriggerScriptChangedEvent(Changed.SCALE); } } - public byte UpdateFlag + public PrimUpdateFlags PendingUpdateFlags { - get { return m_updateFlag; } - set { m_updateFlag = value; } + get { return m_pendingUpdateFlags; } + set { m_pendingUpdateFlags = value; } } #endregion @@ -1205,14 +1195,6 @@ namespace OpenSim.Region.Framework.Scenes } } - /// - /// Clear all pending updates of parts to clients - /// - private void ClearUpdateSchedule() - { - m_updateFlag = 0; - } - private void SendObjectPropertiesToClient(UUID AgentID) { m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) @@ -1253,6 +1235,14 @@ namespace OpenSim.Region.Framework.Scenes #region Public Methods + /// + /// Clear all pending updates of parts to clients + /// + public void ClearPendingUpdate() + { + m_pendingUpdateFlags = 0; + } + public void ResetExpire() { Expires = DateTime.Now + new TimeSpan(600000000); @@ -1275,17 +1265,17 @@ namespace OpenSim.Region.Framework.Scenes /// /// Tell all scene presences that they should send updates for this part to their clients /// - public void AddFullUpdateToAllAvatars() + public void AddUpdateToAllAvatars(PrimUpdateFlags updateFlags) { m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) { - avatar.SceneViewer.QueuePartForUpdate(this); + avatar.SceneViewer.QueuePartForUpdate(this, updateFlags); }); } - public void AddFullUpdateToAvatar(ScenePresence presence) + public void AddUpdateToAvatar(ScenePresence presence, PrimUpdateFlags updateFlags) { - presence.SceneViewer.QueuePartForUpdate(this); + presence.SceneViewer.QueuePartForUpdate(this, updateFlags); } public void AddNewParticleSystem(Primitive.ParticleSystem pSystem) @@ -1298,20 +1288,6 @@ namespace OpenSim.Region.Framework.Scenes m_particleSystem = new byte[0]; } - /// Terse updates - public void AddTerseUpdateToAllAvatars() - { - m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) - { - avatar.SceneViewer.QueuePartForUpdate(this); - }); - } - - public void AddTerseUpdateToAvatar(ScenePresence presence) - { - presence.SceneViewer.QueuePartForUpdate(this); - } - public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim) { byte[] data = new byte[16]; @@ -2588,19 +2564,19 @@ namespace OpenSim.Region.Framework.Scenes { if (PhysActor != null) { + Vector3 newpos = PhysActor.Position; - Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); - - if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) + if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | + m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | + m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | + m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) { m_parentGroup.AbsolutePosition = newpos; return; } - //m_parentGroup.RootPart.m_groupPosition = newpos; } - ScheduleTerseUpdate(); - //SendTerseUpdateToAllClients(); + ScheduleUpdate(PrimUpdateFlags.Position); } public void PreloadSound(string sound) @@ -2688,7 +2664,7 @@ namespace OpenSim.Region.Framework.Scenes m_shape.Scale = scale; ParentGroup.HasGroupChanged = true; - ScheduleFullUpdate(); + ScheduleUpdate(PrimUpdateFlags.Scale); } public void RotLookAt(Quaternion target, float strength, float damping) @@ -2728,58 +2704,24 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Schedules this prim for a full update + /// Schedules this prim for an update /// - public void ScheduleFullUpdate() + public void ScheduleUpdate(PrimUpdateFlags updateFlags) { -// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); - if (m_parentGroup != null) - { m_parentGroup.QueueForUpdateCheck(); - } int timeNow = Util.UnixTimeSinceEpoch(); // If multiple updates are scheduled on the same second, we still need to perform all of them // So we'll force the issue by bumping up the timestamp so that later processing sees these need // to be performed. - if (timeNow <= TimeStampFull) - { - TimeStampFull += 1; - } + if (timeNow <= TimeStampUpdate) + TimeStampUpdate += 1; else - { - TimeStampFull = (uint)timeNow; - } + TimeStampUpdate = (uint)timeNow; - m_updateFlag = 2; - - // m_log.DebugFormat( - // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}", - // UUID, Name, TimeStampFull); - } - - /// - /// Schedule a terse update for this prim. Terse updates only send position, - /// rotation, velocity, rotational velocity and shape information. - /// - public void ScheduleTerseUpdate() - { - if (m_updateFlag < 1) - { - if (m_parentGroup != null) - { - m_parentGroup.HasGroupChanged = true; - m_parentGroup.QueueForUpdateCheck(); - } - TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); - m_updateFlag = 1; - - // m_log.DebugFormat( - // "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}", - // UUID, Name, TimeStampTerse); - } + m_pendingUpdateFlags |= updateFlags; } public void ScriptSetPhantomStatus(bool Phantom) @@ -2886,50 +2828,59 @@ namespace OpenSim.Region.Framework.Scenes public void SendScheduledUpdates() { const float ROTATION_TOLERANCE = 0.01f; - const float VELOCITY_TOLERANCE = 0.001f; const float POSITION_TOLERANCE = 0.05f; const int TIME_MS_TOLERANCE = 3000; - if (m_updateFlag == 1) - { - // Throw away duplicate or insignificant updates - if (!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || - !Acceleration.Equals(m_lastAcceleration) || - !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || - Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || - !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || - !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || - Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) - { - AddTerseUpdateToAllAvatars(); - ClearUpdateSchedule(); + #region PrimUpdateFlags Management - // This causes the Scene to 'poll' physical objects every couple of frames - // bad, so it's been replaced by an event driven method. - //if ((ObjectFlags & (uint)PrimFlags.Physics) != 0) - //{ - // Only send the constant terse updates on physical objects! - //ScheduleTerseUpdate(); - //} + // Check if any of the movement fields changes and set flags accordingly + PrimUpdateFlags updateFlags = m_pendingUpdateFlags; - // Update the "last" values - m_lastPosition = OffsetPosition; - m_lastRotation = RotationOffset; - m_lastVelocity = Velocity; - m_lastAcceleration = Acceleration; - m_lastAngularVelocity = AngularVelocity; - m_lastTerseSent = Environment.TickCount; - } - } + if (!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) + updateFlags |= PrimUpdateFlags.Rotation; else + updateFlags &= ~PrimUpdateFlags.Rotation; + + if (!Acceleration.Equals(m_lastAcceleration)) + updateFlags |= PrimUpdateFlags.Acceleration; + else + updateFlags &= ~PrimUpdateFlags.Acceleration; + + if (!Velocity.Equals(m_lastVelocity)) + updateFlags |= PrimUpdateFlags.Velocity; + else + updateFlags &= ~PrimUpdateFlags.Velocity; + + if (!AngularVelocity.Equals(m_lastAngularVelocity)) + updateFlags |= PrimUpdateFlags.AngularVelocity; + else + updateFlags &= ~PrimUpdateFlags.AngularVelocity; + + if (!OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) + updateFlags |= PrimUpdateFlags.Position; + else + updateFlags &= ~PrimUpdateFlags.Position; + + // For good measure + if (Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) + updateFlags |= PrimUpdateFlags.Position; + + #endregion PrimUpdateFlags Management + + if (updateFlags != 0) { - if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes - { - AddFullUpdateToAllAvatars(); - ClearUpdateSchedule(); - } + AddUpdateToAllAvatars(updateFlags); + + // Update the "last" values + m_lastPosition = OffsetPosition; + m_lastRotation = RotationOffset; + m_lastVelocity = Velocity; + m_lastAcceleration = Acceleration; + m_lastAngularVelocity = AngularVelocity; + m_lastTerseSent = Environment.TickCount; } - ClearUpdateSchedule(); + + ClearPendingUpdate(); } /// @@ -3323,7 +3274,7 @@ namespace OpenSim.Region.Framework.Scenes _groupID = groupID; if (client != null) GetProperties(client); - m_updateFlag = 2; + m_pendingUpdateFlags |= PrimUpdateFlags.FullUpdate; } /// @@ -3385,14 +3336,14 @@ namespace OpenSim.Region.Framework.Scenes Text = text; ParentGroup.HasGroupChanged = true; - ScheduleFullUpdate(); + ScheduleUpdate(PrimUpdateFlags.Text); } public void StopLookAt() { m_parentGroup.stopLookAt(); - m_parentGroup.ScheduleGroupForTerseUpdate(); + m_parentGroup.ScheduleGroupForUpdate(PrimUpdateFlags.Position | PrimUpdateFlags.Rotation); } /// @@ -3414,8 +3365,7 @@ namespace OpenSim.Region.Framework.Scenes { m_parentGroup.stopMoveToTarget(); - m_parentGroup.ScheduleGroupForTerseUpdate(); - //m_parentGroup.ScheduleGroupForFullUpdate(); + m_parentGroup.ScheduleGroupForUpdate(PrimUpdateFlags.Position | PrimUpdateFlags.Rotation); } public void StoreUndoState() @@ -3962,7 +3912,7 @@ namespace OpenSim.Region.Framework.Scenes } ParentGroup.HasGroupChanged = true; - ScheduleFullUpdate(); + ScheduleUpdate(PrimUpdateFlags.ExtraData); } public void UpdateGroupPosition(Vector3 pos) @@ -3973,7 +3923,7 @@ namespace OpenSim.Region.Framework.Scenes { Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); GroupPosition = newPos; - ScheduleTerseUpdate(); + ScheduleUpdate(PrimUpdateFlags.Position); } } @@ -4005,7 +3955,7 @@ namespace OpenSim.Region.Framework.Scenes } OffsetPosition = newPos; - ScheduleTerseUpdate(); + ScheduleUpdate(PrimUpdateFlags.Position); } } @@ -4285,7 +4235,7 @@ namespace OpenSim.Region.Framework.Scenes // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); ParentGroup.HasGroupChanged = true; - ScheduleFullUpdate(); + ScheduleUpdate(PrimUpdateFlags.PrimFlags); } public void UpdateRotation(Quaternion rot) @@ -4297,7 +4247,7 @@ namespace OpenSim.Region.Framework.Scenes { RotationOffset = rot; ParentGroup.HasGroupChanged = true; - ScheduleTerseUpdate(); + ScheduleUpdate(PrimUpdateFlags.Rotation); } } @@ -4341,7 +4291,7 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.RootPart.Rezzed = DateTime.UtcNow; ParentGroup.HasGroupChanged = true; - ScheduleFullUpdate(); + ScheduleUpdate(PrimUpdateFlags.PrimData); } /// @@ -4388,7 +4338,7 @@ namespace OpenSim.Region.Framework.Scenes //This is madness.. //ParentGroup.ScheduleGroupForFullUpdate(); //This is sparta - ScheduleFullUpdate(); + ScheduleUpdate(PrimUpdateFlags.Textures); } public void aggregateScriptEvents() @@ -4456,7 +4406,7 @@ namespace OpenSim.Region.Framework.Scenes { // m_log.DebugFormat( // "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents() since m_parentGroup == null", Name, LocalId); - ScheduleFullUpdate(); + ScheduleUpdate(PrimUpdateFlags.FullUpdate); return; } @@ -4479,7 +4429,7 @@ namespace OpenSim.Region.Framework.Scenes { // m_log.DebugFormat( // "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents()", Name, LocalId); - ScheduleFullUpdate(); + ScheduleUpdate(PrimUpdateFlags.FullUpdate); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 8b83b0660c..7f1798c4ea 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -278,7 +278,7 @@ namespace OpenSim.Region.Framework.Scenes m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); m_part.ParentGroup.AddActiveScriptCount(1); - m_part.ScheduleFullUpdate(); + m_part.ScheduleUpdate(PrimUpdateFlags.FullUpdate); return; } @@ -306,7 +306,7 @@ namespace OpenSim.Region.Framework.Scenes m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); m_part.ParentGroup.AddActiveScriptCount(1); - m_part.ScheduleFullUpdate(); + m_part.ScheduleUpdate(PrimUpdateFlags.FullUpdate); } } } @@ -697,7 +697,7 @@ namespace OpenSim.Region.Framework.Scenes m_part.RemFlag(PrimFlags.Scripted); } - m_part.ScheduleFullUpdate(); + m_part.ScheduleUpdate(PrimUpdateFlags.FullUpdate); return type; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 1462a8b9aa..718789b7a2 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -783,10 +783,9 @@ namespace OpenSim.Region.Framework.Scenes /// /// Add the part to the queue of parts for which we need to send an update to the client /// - /// - public void QueuePartForUpdate(SceneObjectPart part) + public void QueuePartForUpdate(SceneObjectPart part, PrimUpdateFlags updateFlags) { - m_sceneViewer.QueuePartForUpdate(part); + m_sceneViewer.QueuePartForUpdate(part, updateFlags); } /// @@ -1573,7 +1572,7 @@ namespace OpenSim.Region.Framework.Scenes // Commented out this code since it could never have executed, but might still be informative. // if (proxyObjectGroup != null) // { - proxyObjectGroup.SendGroupFullUpdate(); + proxyObjectGroup.SendGroupUpdate(PrimUpdateFlags.FullUpdate); remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); m_scene.DeleteSceneObject(proxyObjectGroup, false); // } diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 4033feed36..a87d0bdf92 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -38,6 +38,12 @@ namespace OpenSim.Region.Framework.Scenes { public class SceneViewer : ISceneViewer { + public class ScenePartUpdate + { + public UUID FullID; + public uint LastUpdateTime; + } + protected ScenePresence m_presence; protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); protected Queue m_pendingObjects; @@ -56,13 +62,10 @@ namespace OpenSim.Region.Framework.Scenes /// /// Add the part to the queue of parts for which we need to send an update to the client /// - /// - public void QueuePartForUpdate(SceneObjectPart part) + public void QueuePartForUpdate(SceneObjectPart part, PrimUpdateFlags updateFlags) { lock (m_partsUpdateQueue) - { - m_partsUpdateQueue.Enqueue(part); - } + m_partsUpdateQueue.Enqueue(part, updateFlags); } public void SendPrimUpdates() @@ -94,14 +97,15 @@ namespace OpenSim.Region.Framework.Scenes // Don't even queue if we have sent this one // if (!m_updateTimes.ContainsKey(g.UUID)) - g.ScheduleFullUpdateToAvatar(m_presence); + g.ScheduleUpdateToAvatar(m_presence, PrimUpdateFlags.FullUpdate); } - while (m_partsUpdateQueue.Count > 0) + SceneObjectPart part; + PrimUpdateFlags updateFlags; + + while (m_partsUpdateQueue.TryDequeue(out part, out updateFlags)) { - SceneObjectPart part = m_partsUpdateQueue.Dequeue(); - - if (part.ParentGroup == null || part.ParentGroup.IsDeleted) + if (part.ParentGroup.IsDeleted) continue; if (m_updateTimes.ContainsKey(part.UUID)) @@ -111,14 +115,13 @@ namespace OpenSim.Region.Framework.Scenes // We deal with the possibility that two updates occur at // the same unix time at the update point itself. - if ((update.LastFullUpdateTime < part.TimeStampFull) || - part.IsAttachment) + if ((update.LastUpdateTime < part.TimeStampUpdate) || part.IsAttachment) { // m_log.DebugFormat( // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", // part.Name, part.UUID, part.TimeStampFull); - part.SendUpdateToClient(m_presence.ControllingClient, PrimUpdateFlags.FullUpdate); + part.SendUpdateToClient(m_presence.ControllingClient, updateFlags); // We'll update to the part's timestamp rather than // the current time to avoid the race condition @@ -127,19 +130,7 @@ namespace OpenSim.Region.Framework.Scenes // updates which occurred on the same tick or the // next tick of the last update would be ignored. - update.LastFullUpdateTime = part.TimeStampFull; - - } - else if (update.LastTerseUpdateTime <= part.TimeStampTerse) - { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", -// part.Name, part.UUID, part.TimeStampTerse); - - part.SendUpdateToClient(m_presence.ControllingClient, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | - PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); - - update.LastTerseUpdateTime = part.TimeStampTerse; + update.LastUpdateTime = part.TimeStampUpdate; } } else @@ -147,7 +138,7 @@ namespace OpenSim.Region.Framework.Scenes //never been sent to client before so do full update ScenePartUpdate update = new ScenePartUpdate(); update.FullID = part.UUID; - update.LastFullUpdateTime = part.TimeStampFull; + update.LastUpdateTime = part.TimeStampUpdate; m_updateTimes.Add(part.UUID, update); // Attachment handling @@ -191,19 +182,5 @@ namespace OpenSim.Region.Framework.Scenes } Reset(); } - - public class ScenePartUpdate - { - public UUID FullID; - public uint LastFullUpdateTime; - public uint LastTerseUpdateTime; - - public ScenePartUpdate() - { - FullID = UUID.Zero; - LastFullUpdateTime = 0; - LastTerseUpdateTime = 0; - } - } } } diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs index 0b7608d0b8..e0e30a8527 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs @@ -72,8 +72,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests grp2.UpdateGroupRotationR(Quaternion.CreateFromEulers(180 * Utils.DEG_TO_RAD, 0, 0)); // Required for linking - grp1.RootPart.UpdateFlag = 0; - grp2.RootPart.UpdateFlag = 0; + grp1.RootPart.ClearPendingUpdate(); + grp2.RootPart.ClearPendingUpdate(); // Link grp2 to grp1. part2 becomes child prim to grp1. grp2 is eliminated. grp1.LinkToGroup(grp2); @@ -165,10 +165,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests grp4.UpdateGroupRotationR(Quaternion.CreateFromEulers(0, 90 * Utils.DEG_TO_RAD, 0)); // Required for linking - grp1.RootPart.UpdateFlag = 0; - grp2.RootPart.UpdateFlag = 0; - grp3.RootPart.UpdateFlag = 0; - grp4.RootPart.UpdateFlag = 0; + grp1.RootPart.ClearPendingUpdate(); + grp2.RootPart.ClearPendingUpdate(); + grp3.RootPart.ClearPendingUpdate(); + grp4.RootPart.ClearPendingUpdate(); // Link grp2 to grp1. part2 becomes child prim to grp1. grp2 is eliminated. grp1.LinkToGroup(grp2); @@ -199,8 +199,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests } // Required for linking - grp1.RootPart.UpdateFlag = 0; - grp3.RootPart.UpdateFlag = 0; + grp1.RootPart.ClearPendingUpdate(); + grp3.RootPart.ClearPendingUpdate(); // root part should have no offset position or rotation Assert.That(part1.OffsetPosition == Vector3.Zero && part1.RotationOffset == Quaternion.Identity, diff --git a/OpenSim/Region/Framework/Scenes/Types/UpdateQueue.cs b/OpenSim/Region/Framework/Scenes/Types/UpdateQueue.cs index 213e954c1f..943816487f 100644 --- a/OpenSim/Region/Framework/Scenes/Types/UpdateQueue.cs +++ b/OpenSim/Region/Framework/Scenes/Types/UpdateQueue.cs @@ -30,16 +30,21 @@ using System.Collections.Generic; using System.Runtime.Serialization; using System.Security.Permissions; using OpenMetaverse; +using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.Framework.Scenes.Types { public class UpdateQueue { - private Queue m_queue; - - private Dictionary m_ids; + private struct Update + { + public SceneObjectPart Entity; + public PrimUpdateFlags UpdateFlags; + } + private Queue m_queue; + private HashSet m_ids; private object m_syncObject = new object(); public int Count @@ -49,8 +54,8 @@ namespace OpenSim.Region.Framework.Scenes.Types public UpdateQueue() { - m_queue = new Queue(); - m_ids = new Dictionary(); + m_queue = new Queue(); + m_ids = new HashSet(); } public void Clear() @@ -62,30 +67,33 @@ namespace OpenSim.Region.Framework.Scenes.Types } } - public void Enqueue(SceneObjectPart part) + public void Enqueue(SceneObjectPart part, PrimUpdateFlags updateFlags) { lock (m_syncObject) { - if (!m_ids.ContainsKey(part.UUID)) { - m_ids.Add(part.UUID, true); - m_queue.Enqueue(part); - } + if (m_ids.Add(part.UUID)) + m_queue.Enqueue(new Update { Entity = part, UpdateFlags = updateFlags }); } } - public SceneObjectPart Dequeue() + public bool TryDequeue(out SceneObjectPart part, out PrimUpdateFlags updateFlags) { - SceneObjectPart part = null; lock (m_syncObject) { if (m_queue.Count > 0) { - part = m_queue.Dequeue(); + Update update = m_queue.Dequeue(); + part = update.Entity; + updateFlags = update.UpdateFlags; + m_ids.Remove(part.UUID); + return true; } } - return part; + part = null; + updateFlags = 0; + return false; } } } diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 55e407ec5f..631d3071b4 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -26,6 +26,7 @@ */ using OpenMetaverse; +using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; namespace OpenSim.Region.Framework.Scenes @@ -91,7 +92,7 @@ namespace OpenSim.Region.Framework.Scenes part.RotationOffset = Rotation; if (Scale != Vector3.Zero) part.Resize(Scale); - part.ParentGroup.ScheduleGroupForTerseUpdate(); + part.ParentGroup.ScheduleGroupForUpdate(PrimUpdateFlags.Position | PrimUpdateFlags.Rotation); } else { @@ -99,10 +100,11 @@ namespace OpenSim.Region.Framework.Scenes part.OffsetPosition = Position; part.UpdateRotation(Rotation); if (Scale != Vector3.Zero) - part.Resize(Scale); part.ScheduleTerseUpdate(); + part.Resize(Scale); + part.ScheduleUpdate(PrimUpdateFlags.Position | PrimUpdateFlags.Rotation); } - part.Undoing = false; + part.Undoing = false; } } public void PlayfwdState(SceneObjectPart part) @@ -119,7 +121,7 @@ namespace OpenSim.Region.Framework.Scenes part.UpdateRotation(Rotation); if (Scale != Vector3.Zero) part.Resize(Scale); - part.ParentGroup.ScheduleGroupForTerseUpdate(); + part.ParentGroup.ScheduleGroupForUpdate(PrimUpdateFlags.Position | PrimUpdateFlags.Rotation); } else { @@ -129,7 +131,7 @@ namespace OpenSim.Region.Framework.Scenes part.UpdateRotation(Rotation); if (Scale != Vector3.Zero) part.Resize(Scale); - part.ScheduleTerseUpdate(); + part.ScheduleUpdate(PrimUpdateFlags.Position | PrimUpdateFlags.Rotation); } part.Undoing = false; diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs index 0dc78c0d41..a567b0ed5c 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs @@ -284,7 +284,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement ((SceneObjectGroup)ent).ApplyPhysics(true); ((SceneObjectGroup)ent).AttachToBackup(); ((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected. - ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(); + ((SceneObjectGroup)ent).ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); } catch(Exception e) { diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs index 3ed338baea..ac90c64738 100644 --- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs +++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs @@ -641,7 +641,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator { s_tree.Scale += copse.m_rate; s_tree.ParentGroup.HasGroupChanged = true; - s_tree.ScheduleFullUpdate(); + s_tree.ScheduleUpdate(PrimUpdateFlags.Scale); } } else @@ -773,7 +773,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator tree.Name = copse.ToString(); copse.m_trees.Add(tree.UUID); - tree.SendGroupFullUpdate(); + tree.SendGroupUpdate(PrimUpdateFlags.FullUpdate); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 839255e17c..39ee0414fe 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1343,7 +1343,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); m_host.ClickAction = (byte)action; if (m_host.ParentGroup != null) m_host.ParentGroup.HasGroupChanged = true; - m_host.ScheduleFullUpdate(); + m_host.ScheduleUpdate(PrimUpdateFlags.PrimFlags); return; } @@ -1595,7 +1595,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } part.ParentGroup.HasGroupChanged = true; - part.ScheduleFullUpdate(); + part.ScheduleUpdate(PrimUpdateFlags.ExtraData); } /// @@ -1630,7 +1630,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } part.ParentGroup.HasGroupChanged = true; - part.ScheduleFullUpdate(); + part.ScheduleUpdate(PrimUpdateFlags.ExtraData); } public LSL_Vector llGetColor(int face) @@ -1913,7 +1913,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api part.OffsetPosition = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z); SceneObjectGroup parent = part.ParentGroup; parent.HasGroupChanged = true; - parent.ScheduleGroupForTerseUpdate(); + parent.ScheduleGroupForUpdate(PrimUpdateFlags.Position); } } } @@ -2245,7 +2245,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.SoundFlags = 1; // looping m_host.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable? - m_host.ScheduleFullUpdate(); + m_host.ScheduleUpdate(PrimUpdateFlags.Sound); m_host.SendUpdateToAllClients(PrimUpdateFlags.Sound); } @@ -2265,7 +2265,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api prim.SoundFlags = 1; // looping prim.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable? - prim.ScheduleFullUpdate(); + prim.ScheduleUpdate(PrimUpdateFlags.Sound); prim.SendUpdateToAllClients(PrimUpdateFlags.Sound); } } @@ -2277,7 +2277,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.SoundFlags = 1; // looping m_host.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable? - m_host.ScheduleFullUpdate(); + m_host.ScheduleUpdate(PrimUpdateFlags.Sound); m_host.SendUpdateToAllClients(PrimUpdateFlags.Sound); } @@ -2319,7 +2319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api part.SoundGain = 0; part.SoundFlags = 0; part.SoundRadius = 0; - part.ScheduleFullUpdate(); + part.ScheduleUpdate(PrimUpdateFlags.Sound); part.SendUpdateToAllClients(PrimUpdateFlags.Sound); } m_host.ParentGroup.LoopSoundMasterPrim = null; @@ -2331,7 +2331,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.SoundGain = 0; m_host.SoundFlags = 0; m_host.SoundRadius = 0; - m_host.ScheduleFullUpdate(); + m_host.ScheduleUpdate(PrimUpdateFlags.Sound); m_host.SendUpdateToAllClients(PrimUpdateFlags.Sound); } } @@ -2341,7 +2341,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.SoundGain = 0; m_host.SoundFlags = 0; m_host.SoundRadius = 0; - m_host.ScheduleFullUpdate(); + m_host.ScheduleUpdate(PrimUpdateFlags.Sound); m_host.SendUpdateToAllClients(PrimUpdateFlags.Sound); } } @@ -3240,7 +3240,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); m_host.AngularVelocity = new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate)); - m_host.ScheduleTerseUpdate(); + m_host.ScheduleUpdate(PrimUpdateFlags.AngularVelocity); m_host.SendUpdateToAllClients(PrimUpdateFlags.AngularVelocity); m_host.ParentGroup.HasGroupChanged = true; } @@ -3507,7 +3507,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api childPrim = m_host.ParentGroup; } // byte uf = childPrim.RootPart.UpdateFlag; - childPrim.RootPart.UpdateFlag = 0; + childPrim.RootPart.ClearPendingUpdate(); parentPrim.LinkToGroup(childPrim); // if (uf != (Byte)0) // parent.RootPart.UpdateFlag = uf; @@ -3516,7 +3516,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parentPrim.TriggerScriptChangedEvent(Changed.LINK); parentPrim.RootPart.AddFlag(PrimFlags.CreateSelected); parentPrim.HasGroupChanged = true; - parentPrim.ScheduleGroupForFullUpdate(); + parentPrim.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); if (client != null) parentPrim.GetProperties(client); @@ -3582,7 +3582,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parentPrim.DelinkFromGroup(part.LocalId, true); } parentPrim.HasGroupChanged = true; - parentPrim.ScheduleGroupForFullUpdate(); + parentPrim.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); parentPrim.TriggerScriptChangedEvent(Changed.LINK); if (parts.Count > 0) @@ -3591,11 +3591,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parts.Remove(newRoot); foreach (SceneObjectPart part in parts) { - part.UpdateFlag = 0; + part.ClearPendingUpdate(); newRoot.ParentGroup.LinkToGroup(part.ParentGroup); } newRoot.ParentGroup.HasGroupChanged = true; - newRoot.ParentGroup.ScheduleGroupForFullUpdate(); + newRoot.ParentGroup.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); } } else @@ -3605,7 +3605,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parentPrim.DelinkFromGroup(childPrim.LocalId, true); parentPrim.HasGroupChanged = true; - parentPrim.ScheduleGroupForFullUpdate(); + parentPrim.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); parentPrim.TriggerScriptChangedEvent(Changed.LINK); } } @@ -3626,7 +3626,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parentPrim.TriggerScriptChangedEvent(Changed.LINK); } parentPrim.HasGroupChanged = true; - parentPrim.ScheduleGroupForFullUpdate(); + parentPrim.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); } public LSL_String llGetLinkKey(int linknum) @@ -3866,7 +3866,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api Util.Clip((float)color.z, 0.0f, 1.0f)); m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); m_host.ParentGroup.HasGroupChanged = true; - m_host.ParentGroup.ScheduleGroupForFullUpdate(); + m_host.ParentGroup.ScheduleGroupForUpdate(PrimUpdateFlags.Text); } public LSL_Float llWater(LSL_Vector offset)