Enabled LinkObject to synchronize across actors.
							parent
							
								
									4860eba0ba
								
							
						
					
					
						commit
						101d67c45b
					
				|  | @ -333,7 +333,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | ||||||
|         //private void RegionSyncModule_OnObjectBeingRemovedFromScene(SceneObjectGroup sog) |         //private void RegionSyncModule_OnObjectBeingRemovedFromScene(SceneObjectGroup sog) | ||||||
|         public void SendDeleteObject(SceneObjectGroup sog, bool softDelete) |         public void SendDeleteObject(SceneObjectGroup sog, bool softDelete) | ||||||
|         { |         { | ||||||
|             //m_log.DebugFormat("RegionSyncModule_OnObjectBeingRemovedFromScene called at time {0}:{1}:{2}", DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond); |             m_log.DebugFormat("SendDeleteObject called for object {0}", sog.UUID); | ||||||
| 
 | 
 | ||||||
|             //Only send the message out if this is a relay node for sync messages, or this actor caused deleting the object |             //Only send the message out if this is a relay node for sync messages, or this actor caused deleting the object | ||||||
|             //if (m_isSyncRelay || CheckObjectForSendingUpdate(sog)) |             //if (m_isSyncRelay || CheckObjectForSendingUpdate(sog)) | ||||||
|  | @ -351,14 +351,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         public void SendLinkObject(SceneObjectPart root, List<SceneObjectPart> children) |         public void SendLinkObject(SceneObjectGroup linkedGroup, SceneObjectPart root, List<SceneObjectPart> children) | ||||||
|         { |         { | ||||||
|             if(children.Count==0) return; |             if(children.Count==0) return; | ||||||
| 
 | 
 | ||||||
|             OSDMap data = new OSDMap(); |             OSDMap data = new OSDMap(); | ||||||
|             //string sogxml = SceneObjectSerializer.ToXml2Format(linkedGroup); |             string sogxml = SceneObjectSerializer.ToXml2Format(linkedGroup); | ||||||
|             //data["linkedGroup"]=OSD.FromString(sogxml); |             data["linkedGroup"]=OSD.FromString(sogxml); | ||||||
|             data["root"] = OSD.FromUUID(root.UUID); |             data["rootID"] = OSD.FromUUID(root.UUID); | ||||||
|             data["partCount"] = OSD.FromInteger(children.Count); |             data["partCount"] = OSD.FromInteger(children.Count); | ||||||
|             data["actorID"] = OSD.FromString(m_actorID); |             data["actorID"] = OSD.FromString(m_actorID); | ||||||
|             int partNum = 0; |             int partNum = 0; | ||||||
|  | @ -369,7 +369,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.LinkObject, OSDParser.SerializeJsonString(data)); |             SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.LinkObject, OSDParser.SerializeJsonString(data)); | ||||||
|             SendObjectUpdateToRelevantSyncConnectors(root.ParentGroup, rsm); |             SendObjectUpdateToRelevantSyncConnectors(linkedGroup, rsm); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -1073,6 +1073,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | ||||||
|             { |             { | ||||||
|                 Scene.ObjectUpdateResult updateResult = m_scene.AddOrUpdateObjectBySynchronization(sog); |                 Scene.ObjectUpdateResult updateResult = m_scene.AddOrUpdateObjectBySynchronization(sog); | ||||||
| 
 | 
 | ||||||
|  |                 m_log.Debug(LogHeader + " handle update message of object " + sog.UUID); | ||||||
|  | 
 | ||||||
|                 //if (added) |                 //if (added) | ||||||
|                 switch (updateResult) |                 switch (updateResult) | ||||||
|                 { |                 { | ||||||
|  | @ -1157,14 +1159,17 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | ||||||
|             bool softDelete = data["softDelete"].AsBoolean(); |             bool softDelete = data["softDelete"].AsBoolean(); | ||||||
| 
 | 
 | ||||||
|             SceneObjectGroup sog = m_scene.SceneGraph.GetGroupByPrim(sogUUID); |             SceneObjectGroup sog = m_scene.SceneGraph.GetGroupByPrim(sogUUID); | ||||||
|  | 
 | ||||||
|             if (sog != null) |             if (sog != null) | ||||||
|             { |             { | ||||||
|                 if (!softDelete) |                 if (!softDelete) | ||||||
|                 { |                 { | ||||||
|  |                     m_log.Debug(LogHeader + " hard delete object " + sog.UUID); | ||||||
|                     m_scene.DeleteSceneObjectBySynchronization(sog); |                     m_scene.DeleteSceneObjectBySynchronization(sog); | ||||||
|                 } |                 } | ||||||
|                 else |                 else | ||||||
|                 { |                 { | ||||||
|  |                     m_log.Debug(LogHeader + " soft delete object " + sog.UUID); | ||||||
|                     m_scene.UnlinkSceneObject(sog, true); |                     m_scene.UnlinkSceneObject(sog, true); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | @ -1187,9 +1192,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             string init_actorID = data["actorID"].AsString(); |             string init_actorID = data["actorID"].AsString(); | ||||||
|             //string sogxml = data["linkedGroup"].AsString(); |             string sogxml = data["linkedGroup"].AsString(); | ||||||
|             //SceneObjectGroup linkedGroup = SceneObjectSerializer.FromXml2Format(sogxml); |             SceneObjectGroup linkedGroup = SceneObjectSerializer.FromXml2Format(sogxml); | ||||||
|             UUID rootID = data["root"].AsUUID(); |             UUID rootID = data["rootID"].AsUUID(); | ||||||
|             int partCount = data["partCount"].AsInteger(); |             int partCount = data["partCount"].AsInteger(); | ||||||
|             List<UUID> childrenIDs = new List<UUID>(); |             List<UUID> childrenIDs = new List<UUID>(); | ||||||
| 
 | 
 | ||||||
|  | @ -1199,7 +1204,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | ||||||
|                 childrenIDs.Add(data[partTempID].AsUUID()); |                 childrenIDs.Add(data[partTempID].AsUUID()); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             m_scene.LinkObjectBySync(rootID, childrenIDs); |             m_scene.LinkObjectBySync(linkedGroup, rootID, childrenIDs); | ||||||
| 
 | 
 | ||||||
|             //if this is a relay node, forwards the event |             //if this is a relay node, forwards the event | ||||||
|             if (m_isSyncRelay) |             if (m_isSyncRelay) | ||||||
|  |  | ||||||
|  | @ -610,14 +610,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | ||||||
|             m_lastUpdateActorID = actorID; |             m_lastUpdateActorID = actorID; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /* |  | ||||||
|         public void CheckForTerrainUpdatesBySynchronization(long timeStamp, string actorID) |  | ||||||
|         { |  | ||||||
|             SyncInfoUpdate(timeStamp, actorID); |  | ||||||
|             CheckForTerrainUpdates(false); |  | ||||||
|         } |  | ||||||
|          * */ |  | ||||||
| 
 |  | ||||||
|         public void TaintTerrianBySynchronization(long timeStamp, string actorID) |         public void TaintTerrianBySynchronization(long timeStamp, string actorID) | ||||||
|         { |         { | ||||||
|             SyncInfoUpdate(timeStamp, actorID); |             SyncInfoUpdate(timeStamp, actorID); | ||||||
|  |  | ||||||
|  | @ -68,7 +68,7 @@ namespace OpenSim.Region.Framework.Interfaces | ||||||
|         //May need some optimization there on the priorities. |         //May need some optimization there on the priorities. | ||||||
|         void SendTerrainUpdates(string lastUpdateActorID); |         void SendTerrainUpdates(string lastUpdateActorID); | ||||||
|         void SendDeleteObject(SceneObjectGroup sog, bool softDelete); |         void SendDeleteObject(SceneObjectGroup sog, bool softDelete); | ||||||
|         void SendLinkObject(SceneObjectPart root, List<SceneObjectPart> children); |         void SendLinkObject(SceneObjectGroup linkedGroup, SceneObjectPart root, List<SceneObjectPart> children); | ||||||
| 
 | 
 | ||||||
|         //For propogating scene events to other actors |         //For propogating scene events to other actors | ||||||
|         void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs); |         void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs); | ||||||
|  |  | ||||||
|  | @ -755,7 +755,7 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|         /// <param name="linkedGroup"></param> |         /// <param name="linkedGroup"></param> | ||||||
|         /// <param name="rootID"></param> |         /// <param name="rootID"></param> | ||||||
|         /// <param name="childrenIDs"></param> |         /// <param name="childrenIDs"></param> | ||||||
|         public void LinkObjectBySync(UUID rootID, List<UUID> childrenIDs) |         public void LinkObjectBySync(SceneObjectGroup linkedGroup, UUID rootID, List<UUID> childrenIDs) | ||||||
|         { |         { | ||||||
|             m_log.Debug("Start to LinkObjectBySync"); |             m_log.Debug("Start to LinkObjectBySync"); | ||||||
|             DebugSceneObjectGroups(); |             DebugSceneObjectGroups(); | ||||||
|  | @ -779,18 +779,30 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  |                 m_log.Debug("to link part " + part.DebugObjectPartProperties()); | ||||||
|  | 
 | ||||||
|                 children.Add(part); |                 children.Add(part); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             //Leverage the LinkObject implementation to get the book keeping of Group and Parts relations right |             //Leverage the LinkObject implementation to get the book keeping of Group and Parts relations right | ||||||
|             m_sceneGraph.LinkObjectsBySync(root, children); |             m_sceneGraph.LinkObjectsBySync(root, children); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|             //The properties of the newly linked object should be updated later with another UpdatedObject message.  |             //The properties of the newly linked object should be updated later with another UpdatedObject message.  | ||||||
| 
 | 
 | ||||||
|             //Set the property values as in the incoming copy of the object group |             //Set the property values as in the incoming copy of the object group | ||||||
|             //SceneObjectGroup localGroup = root.ParentGroup; |             SceneObjectGroup localGroup = root.ParentGroup; | ||||||
|             //localGroup.UpdateObjectProperties(linkedGroup); |             localGroup.UpdateObjectProperties(linkedGroup); | ||||||
| 
 | 
 | ||||||
|  |             //debug | ||||||
|  |             m_log.Debug("after SceneGraph.LinkObjectsBySync, the newly linked group is \n" + root.ParentGroup.DebugObjectUpdateResult()); | ||||||
|  |             m_log.Debug("parts before linking now have properties: "); | ||||||
|  |             foreach (SceneObjectPart part in children) | ||||||
|  |             { | ||||||
|  |                 m_log.Debug(part.DebugObjectPartProperties()); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         #endregion //SYMMETRIC SYNC |         #endregion //SYMMETRIC SYNC | ||||||
|  |  | ||||||
|  | @ -1577,25 +1577,11 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|                 //SYMMETRIC SYNC |  | ||||||
|                 //Send out a LinkObject message for synchronization purpose, before other object-update sync messages are sent out. |  | ||||||
|                 //We need to do this before the calling to parentGroup.LinkToGroup() below, as LinkToGroup will trigger |  | ||||||
|                 //SendDeleteObject message to be sent out. |  | ||||||
| 
 |  | ||||||
|                 // ------------- NOTE: This needs further optimization, as we don't want to block on sending messages while inside the lock. ------------- |  | ||||||
|                 //      However, we also want to make sure that the LinkObject message is sent out with high priority and sent  |  | ||||||
|                 //      earlier than the object update message triggered by the ScheduleGroupForFullUpdate() function below |  | ||||||
|                 if (m_parentScene.RegionSyncModule != null) |  | ||||||
|                 { |  | ||||||
|                     //Tell other actors to link the SceneObjectParts together as a new group. But not updating the properties yet. |  | ||||||
|                     //The properties will be updated later when parentGroup.ScheduleGroupForFullUpdate() is called below. |  | ||||||
|                     m_parentScene.RegionSyncModule.SendLinkObject(root, children); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 //end of SYMMETRIC SYNC |  | ||||||
| 
 | 
 | ||||||
|                 foreach (SceneObjectGroup child in childGroups) |                 foreach (SceneObjectGroup child in childGroups) | ||||||
|                 { |                 { | ||||||
|  |                     m_log.Debug("linking child " + child.UUID + " to parentGroup " + parentGroup.UUID); | ||||||
|  | 
 | ||||||
|                     parentGroup.LinkToGroup(child); |                     parentGroup.LinkToGroup(child); | ||||||
| 
 | 
 | ||||||
|                     // this is here so physics gets updated! |                     // this is here so physics gets updated! | ||||||
|  | @ -1603,13 +1589,25 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|                     child.AbsolutePosition = child.AbsolutePosition; |                     child.AbsolutePosition = child.AbsolutePosition; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|                 // We need to explicitly resend the newly link prim's object properties since no other actions |  | ||||||
|                 // occur on link to invoke this elsewhere (such as object selection) |  | ||||||
|                 parentGroup.RootPart.CreateSelected = true; |                 parentGroup.RootPart.CreateSelected = true; | ||||||
|                 parentGroup.TriggerScriptChangedEvent(Changed.LINK); |                 parentGroup.TriggerScriptChangedEvent(Changed.LINK); | ||||||
|                 parentGroup.HasGroupChanged = true; |                 parentGroup.HasGroupChanged = true; | ||||||
|                 parentGroup.ScheduleGroupForFullUpdate(); | 
 | ||||||
|  |                 //SYMMETRIC SYNC | ||||||
|  |                 //Schedule a LinkObject message for synchronization purpose. This will lead to enqueue a LinkObject message in SyncConnector's outgoingQueue, | ||||||
|  |                 //so should return quickly.  | ||||||
|  |                 if (m_parentScene.RegionSyncModule != null) | ||||||
|  |                 { | ||||||
|  |                     //Tell other actors to link the SceneObjectParts together as a new group. But not updating the properties yet. | ||||||
|  |                     //The properties will be updated later when parentGroup.ScheduleGroupForFullUpdate() is called below. | ||||||
|  |                     parentGroup.SyncInfoUpdate(); | ||||||
|  |                     m_parentScene.RegionSyncModule.SendLinkObject(parentGroup, root, children); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 //Schedule updates as in legacy OpenSim code, to send updates to viewers connected to this actor (at least needed for client managers) | ||||||
|  |                 parentGroup.ScheduleGroupForFullUpdate_SyncInfoUnchanged(); | ||||||
|  | 
 | ||||||
|  |                 //end of SYMMETRIC SYNC | ||||||
|                  |                  | ||||||
|             } |             } | ||||||
|             finally |             finally | ||||||
|  |  | ||||||
|  | @ -2128,8 +2128,8 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
| 
 | 
 | ||||||
|             //SYMMETRIC SYNC |             //SYMMETRIC SYNC | ||||||
|             //The DeleteObject message will be enqueued to be sent out by another thread, and the call will return quickly. |             //The DeleteObject message will be enqueued to be sent out by another thread, and the call will return quickly. | ||||||
|             if (m_scene.RegionSyncModule != null) |             //if (m_scene.RegionSyncModule != null) | ||||||
|                 m_scene.RegionSyncModule.SendDeleteObject(objectGroup, true); |             //    m_scene.RegionSyncModule.SendDeleteObject(objectGroup, true); | ||||||
|             //end of SYMMETRIC SYNC |             //end of SYMMETRIC SYNC | ||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
|  | @ -3859,6 +3859,15 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         public void SyncInfoUpdate() | ||||||
|  |         { | ||||||
|  |             long timeStamp = DateTime.Now.Ticks; | ||||||
|  |             string actorID = m_scene.ActorSyncModule.ActorID; | ||||||
|  |             foreach (SceneObjectPart part in Parts) | ||||||
|  |             { | ||||||
|  |                 part.SyncInfoUpdate(timeStamp, actorID); | ||||||
|  |             } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         #endregion |         #endregion | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -4931,9 +4931,9 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|             set { m_lastUpdateActorID = value; } |             set { m_lastUpdateActorID = value; } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public void UpdateTimestamp() |         public void UpdateTimestamp(long time) | ||||||
|         { |         { | ||||||
|             m_lastUpdateTimeStamp = DateTime.Now.Ticks; |             m_lastUpdateTimeStamp = time; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public void SetLastUpdateActorID() |         public void SetLastUpdateActorID() | ||||||
|  | @ -4948,17 +4948,26 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         private Object m_SyncInfoLock = new Object(); | ||||||
|  |         public void SyncInfoUpdate(long timeStamp, string actorID) | ||||||
|  |         { | ||||||
|  |             //update timestamp and actorID atomically | ||||||
|  |             lock (m_SyncInfoLock) | ||||||
|  |             { | ||||||
|  |                 UpdateTimestamp(timeStamp); | ||||||
|  |                 m_lastUpdateActorID = actorID; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         | ||||||
|  | 
 | ||||||
|         public void SyncInfoUpdate() |         public void SyncInfoUpdate() | ||||||
|         { |         { | ||||||
|             //if (m_parentGroup == null || m_parentGroup.Scene==null || m_parentGroup.Scene.ActorSyncModule == null || m_parentGroup.Scene.ActorSyncModule.ActorID == null) |  | ||||||
|             //    return; |  | ||||||
|             //Trick: calling UpdateTimestamp here makes sure that when an object was received and de-serialized, before |             //Trick: calling UpdateTimestamp here makes sure that when an object was received and de-serialized, before | ||||||
|             //       its parts are linked together, neither TimeStamp or ActorID will be modified. This is because during de-serialization,  |             //       its parts are linked together, neither TimeStamp or ActorID will be modified. This is because during de-serialization,  | ||||||
|             //       ScheduleFullUpdate() is called when m_parentGroup == null |             //       ScheduleFullUpdate() is called when m_parentGroup == null | ||||||
|             if (m_parentGroup != null && m_parentGroup.Scene != null && m_parentGroup.Scene.ActorSyncModule!=null) |             if (m_parentGroup != null && m_parentGroup.Scene != null && m_parentGroup.Scene.ActorSyncModule != null) | ||||||
|             { |             { | ||||||
|                 UpdateTimestamp(); |                 SyncInfoUpdate(DateTime.Now.Ticks, m_parentGroup.Scene.ActorSyncModule.ActorID); | ||||||
|                 m_lastUpdateActorID = m_parentGroup.Scene.ActorSyncModule.ActorID; |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -5102,6 +5111,7 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|         public string DebugObjectPartProperties() |         public string DebugObjectPartProperties() | ||||||
|         { |         { | ||||||
|             string debugMsg = "UUID " + UUID + ", Name " + Name + ", localID " + LocalId + ", lastUpdateActorID " + LastUpdateActorID + ", lastUpdateTimeStamp " + LastUpdateTimeStamp; |             string debugMsg = "UUID " + UUID + ", Name " + Name + ", localID " + LocalId + ", lastUpdateActorID " + LastUpdateActorID + ", lastUpdateTimeStamp " + LastUpdateTimeStamp; | ||||||
|  |             debugMsg += ", parentID " + ParentID + ", parentUUID " + ParentUUID; | ||||||
|             return debugMsg; |             return debugMsg; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -675,7 +675,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | ||||||
|                         return 0; |                         return 0; | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     m_log.DebugFormat("[Script] processing event {2} in state {3} to {0}.{1}, localID -{4}", m_PrimName, m_ScriptName, data.EventName, m_State, m_LocalID); |                     m_log.DebugFormat("[Script] processing event {2} in state {3} to {0}.{1}, localID-{4}", m_PrimName, m_ScriptName, data.EventName, m_State, m_LocalID); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|                     if (data.EventName == "timer") |                     if (data.EventName == "timer") | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Huaiyu (Kitty) Liu
						Huaiyu (Kitty) Liu