diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index 23417dbfba..2f77ac06ad 100755 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -167,11 +167,35 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private RegionSyncListener m_localSyncListener = null; + // Lock is used to synchronize access to the update status and update queues + private object m_updateSceneObjectPartLock = new object(); + private Dictionary m_primUpdates = new Dictionary(); + private object m_updatePresenceLock = new object(); + private Dictionary m_presenceUpdates = new Dictionary(); + + public void QueueSceneObjectPartForUpdate(SceneObjectPart part) + { + lock (m_updateSceneObjectPartLock) + { + m_primUpdates[part.UUID] = part.ParentGroup; + } + } + + public void QueueScenePresenceForTerseUpdate(ScenePresence presence) + { + lock (m_updateSceneObjectPartLock) + { + m_presenceUpdates[presence.UUID] = presence; + } + } + public void SendObjectUpdates(List sog) { } + + #endregion //IRegionSyncModule #region ICommandableModule Members @@ -553,13 +577,19 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { string sogxml = SceneObjectSerializer.ToXml2Format((SceneObjectGroup)e); SendSyncMessage(SymmetricSyncMessage.MsgType.NewObject, sogxml); + + //m_log.Debug(LogHeader + ": " + sogxml); } } return; } case SymmetricSyncMessage.MsgType.NewObject: { - SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(Encoding.ASCII.GetString(msg.Data, 0, msg.Length)); + string sogxml = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); + + //m_log.Debug(LogHeader + ": " + sogxml); + + SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml); //HandleAddOrUpdateObjectInLocalScene(sog, true, true); HandleAddNewObject(sog); diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScenePersistenceSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScenePersistenceSyncModule.cs index c8e165fb20..f922b66980 100755 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScenePersistenceSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScenePersistenceSyncModule.cs @@ -45,7 +45,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule string actorType = syncConfig.GetString("DSGActorType", "").ToLower(); if (!actorType.Equals("scene_persistence")) { - m_log.Warn(LogHeader + ": not configured as Scene Persistence Actor. Shut down."); + m_log.Warn(LogHeader + ": not configured as Scene Persistence Actor. Shutting down."); + return; + } + + m_actorID = syncConfig.GetString("ActorID", ""); + if (m_actorID.Equals("")) + { + m_log.Warn(LogHeader + ": ActorID not specified in config file. Shutting down."); return; } @@ -79,7 +86,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } //Called after AddRegion() has been called for all region modules of the scene. - //NOTE::However, at this point, Scene may not have requested all the needed region module interfaces yet. + //NOTE::However, at this point, Scene may not have requested all the needed region module interfaces yet. + // So to try to access other region modules in RegionLoaded, e.g. RegionSyncModule, is not a good idea. public void RegionLoaded(Scene scene) { if (!m_active) @@ -107,8 +115,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule get { return "ScenePersistenceSyncModule"; } } - - #endregion //INonSharedRegionModule #region IDSGActorSyncModule members and functions @@ -119,6 +125,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule get { return m_actorType; } } + private string m_actorID; + public string ActorID + { + get { return m_actorID; } + } + #endregion //IDSGActorSyncModule #region ScenePersistenceSyncModule memebers and functions diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScriptEngineSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScriptEngineSyncModule.cs index cde08746d2..c1cb8025c7 100755 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScriptEngineSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScriptEngineSyncModule.cs @@ -50,6 +50,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule return; } + m_actorID = syncConfig.GetString("ActorID", ""); + if (m_actorID.Equals("")) + { + m_log.Warn(LogHeader + ": ActorID not specified in config file. Shutting down."); + return; + } + m_active = true; m_log.Warn(LogHeader + " Initialised"); @@ -117,6 +124,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule get { return m_actorType; } } + private string m_actorID; + public string ActorID + { + get { return m_actorID; } + } + #endregion //IDSGActorSyncModule diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 6879cf7335..54297b1c78 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3456,5 +3456,9 @@ namespace OpenSim.Region.Framework.Scenes this.m_locY = updatedSog.LocY; } #endregion + + #region SYMMETRIC SYNC + + #endregion } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 9487fc8142..6799bc5bf8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2892,6 +2892,13 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}", // UUID, Name, TimeStampFull); + + //SYMMETRIC SYNC + + //update information (timestamp, actorID, etc) needed for synchronization across copies of Scene + SyncInfoUpdate(); + + //end of SYMMETRIC SYNC } /// @@ -2913,6 +2920,13 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}", // UUID, Name, TimeStampTerse); + + //SYMMETRIC SYNC + + //update information (timestamp, actorID, etc) needed for synchronization across copies of Scene + SyncInfoUpdate(); + + //end of SYMMETRIC SYNC } } @@ -3130,6 +3144,10 @@ namespace OpenSim.Region.Framework.Scenes } } ClearUpdateSchedule(); + + //SYMMETRIC SYNC + + //end of SYMMETRIC SYNC } /// @@ -4895,5 +4913,56 @@ namespace OpenSim.Region.Framework.Scenes #endregion + #region SYMMETRIC SYNC + + //Time stamp for the most recent update on this prim. We only have one time-stamp per prim for now. + //The goal is to evetually have time-stamp per property bucket for each prim. + private long m_lastUpdateTimeStamp = DateTime.Now.Ticks; + public long LastUpdateTimeStamp + { + get { return m_lastUpdateTimeStamp; } + set { m_lastUpdateTimeStamp = value; } + } + + //The ID the identifies which actor has caused the most recent update to the prim. + //We use type "string" for the ID only to make it human-readable. + private string m_lastUpdateByActorID; + public string LastUpdateActorID + { + get { return m_lastUpdateByActorID; } + set { m_lastUpdateByActorID = value; } + } + + public void UpdateTimestamp() + { + m_lastUpdateTimeStamp = DateTime.Now.Ticks; + } + + public void SetLastUpdateActorID() + { + if (m_parentGroup != null) + { + m_lastUpdateByActorID = m_parentGroup.Scene.ActorSyncModule.ActorID; + } + else + { + m_log.Error("Prim " + UUID + " is not in a SceneObjectGroup yet"); + } + } + + private void SyncInfoUpdate() + { + //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, + // ScheduleFullUpdate() is called when m_parentGroup == null + if (m_parentGroup != null) + { + UpdateTimestamp(); + m_lastUpdateByActorID = m_parentGroup.Scene.ActorSyncModule.ActorID; + } + } + + #endregion + } } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 1b06550aa1..a01d1630a6 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -215,6 +215,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization sceneObject.AddPart(part); + //SYMMETRIC SYNC + //KittyL: 12/27/2010, added ActorID for symmetric synch model + part.SetLastUpdateActorID(); + // SceneObjectGroup.AddPart() tries to be smart and automatically set the LinkNum. // We override that here if (originalLinkNum != 0) @@ -324,6 +328,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization m_SOPXmlProcessors.Add("MediaUrl", ProcessMediaUrl); m_SOPXmlProcessors.Add("TextureAnimation", ProcessTextureAnimation); m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem); + + //SYMMETRIC SYNC + m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp); + m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID); + //end of SYMMETRIC SYNC + #endregion #region TaskInventoryXmlProcessors initialization @@ -681,6 +691,19 @@ namespace OpenSim.Region.Framework.Scenes.Serialization { obj.ParticleSystem = Convert.FromBase64String(reader.ReadElementContentAsString("ParticleSystem", String.Empty)); } + + //SYMMETRIC SYNC + private static void ProcessUpdateTimeStamp(SceneObjectPart obj, XmlTextReader reader) + { + obj.LastUpdateTimeStamp = reader.ReadElementContentAsLong("LastUpdateTimeStamp", string.Empty); + } + + private static void ProcessLastUpdateActorID(SceneObjectPart obj, XmlTextReader reader) + { + obj.LastUpdateActorID = reader.ReadElementContentAsString("LastUpdateActorID", string.Empty); + } + //end of SYMMETRIC SYNC + #endregion #region TaskInventoryXmlProcessors @@ -1161,6 +1184,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization WriteBytes(writer, "TextureAnimation", sop.TextureAnimation); WriteBytes(writer, "ParticleSystem", sop.ParticleSystem); + //SYMMETRIC SYNC + writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString()); + writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID); + //end of SYMMETRIC SYNC + writer.WriteEndElement(); }