From b3179d34dabe8360d7d0549941e1e1a9fb7cfa3e Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Wed, 19 Jan 2011 10:52:06 -0800 Subject: [PATCH] reimplement SceneObjectGroup.UpdateObjectAllProperties to do parts updating differently, as an attemp to make linkset updates correct, and rename the function UpdateObjectGroupBySync. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- .../Framework/Scenes/SceneObjectGroup.cs | 96 ++++++++++++++----- 2 files changed, 74 insertions(+), 24 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 8666fe8ab9..f81fc17cf3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1945,7 +1945,7 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectGroup) { SceneObjectGroup localSog = (SceneObjectGroup)entity; - Scene.ObjectUpdateResult updateResult = localSog.UpdateObjectAllProperties(updatedSog); + Scene.ObjectUpdateResult updateResult = localSog.UpdateObjectGroupBySync(updatedSog); return updateResult; } else diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 044af42cb8..2215b909be 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3474,10 +3474,11 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - public Scene.ObjectUpdateResult UpdateObjectAllProperties(SceneObjectGroup updatedSog) + public Scene.ObjectUpdateResult UpdateObjectGroupBySync(SceneObjectGroup updatedSog) { - if (!this.GroupID.Equals(updatedSog.GroupID)) - return Scene.ObjectUpdateResult.Error; + //This GroupID check should be done by the actor who initiates the object update + //if (!this.GroupID.Equals(updatedSog.GroupID)) + // return Scene.ObjectUpdateResult.Error; //////////////////////////////////////////////////////////////////////////////////////////////////// //NOTE!!! @@ -3494,16 +3495,83 @@ namespace OpenSim.Region.Framework.Scenes bool partsRemoved = false; //has any old part been removed? bool rootPartChanged = false; //has the rootpart be changed to a different prim? - lock (m_parts) + lock (m_parts.SyncRoot) { //update rootpart, if changed + /* if (m_rootPart.UUID != updatedSog.RootPart.UUID) { m_rootPart = updatedSog.RootPart; rootPartChanged = true; } + * */ //foreach (KeyValuePair pair in updatedSog.Parts) + Dictionary remainedParts = new Dictionary(); + Dictionary removedParts = new Dictionary(); + Dictionary newParts = new Dictionary(); + + //Compare the parts in updatedSog and sort them into remained/removed/newParts groups + foreach (SceneObjectPart updatedPart in updatedSog.Parts) + { + UUID partUUID = updatedPart.UUID; + if (ContainsPart(partUUID)) + { + SceneObjectPart localPart = GetChildPart(partUUID); + remainedParts.Add(partUUID, localPart); + } + else + { + //in case the part is in the SceneGraph already + SceneObjectPart localPart = m_scene.GetSceneObjectPart(partUUID); + if(localPart!=null) + newParts.Add(partUUID, localPart); + else + newParts.Add(partUUID, updatedPart); + } + } + + foreach (SceneObjectPart localPart in this.Parts) + { + if (!remainedParts.ContainsKey(localPart.UUID)) + removedParts.Add(localPart.UUID, localPart); + } + + //Add in new parts + foreach (SceneObjectPart newPart in newParts.Values) + { + AddPart(newPart); + } + + //remove parts that are no longer in the group -- !!!!! need to further test how to do correct book-keeping and synchornized with other actors !!!!!!!! + foreach (SceneObjectPart rmPart in removedParts.Values) + { + DelinkFromGroup(rmPart, true); + } + + if (newParts.Count > 0 || removedParts.Count > 0) + { + groupUpdateResult = Scene.ObjectUpdateResult.Updated; + } + + //now update properties of the parts + foreach (SceneObjectPart part in this.Parts) + { + Scene.ObjectUpdateResult partUpdateResult = Scene.ObjectUpdateResult.Unchanged; + SceneObjectPart updatedPart = updatedSog.GetChildPart(part.UUID); + partUpdateResult = part.UpdateAllProperties(updatedPart); + + if (partUpdateResult != Scene.ObjectUpdateResult.Unchanged) + { + groupUpdateResult = partUpdateResult; + } + } + + //Just to make sure the parts each has the right localID of the rootpart + UpdateParentIDs(); + + /* + //old code below foreach (SceneObjectPart updatedPart in updatedSog.Parts) { UUID partUUID = updatedPart.UUID; @@ -3547,27 +3615,9 @@ namespace OpenSim.Region.Framework.Scenes { UpdateParentIDs(); } + * */ } - if (partsRemoved) - { - groupUpdateResult = Scene.ObjectUpdateResult.Updated; - } - - /* - //update the authoritative scene that this object is located, which is identified by (LocX, LocY) - if (this.m_locX != updatedSog.LocX) - { - this.m_locX = updatedSog.LocX; - groupUpdateResult = Scene.ObjectUpdateResult.Updated; - } - if (this.m_locY != updatedSog.LocY) - { - this.m_locY = updatedSog.LocY; - groupUpdateResult = Scene.ObjectUpdateResult.Updated; - } - * */ - //Schedule updates to be sent out, if the local copy has just been updated //(1) if we are debugging the actor with a viewer attaching to it, //we need to schedule updates to be sent to the viewer.