From 9ca061b25a0943c3097f94b53c204294172e42d6 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Wed, 2 Feb 2011 15:46:12 -0800 Subject: [PATCH] Starting add SetXXX() functions to SceneObjectPart, where XXX is each property's name. Also fixed some bugs in InitializeBucketSyncInfo --- .../SymmetricSync/RegionSyncModule.cs | 88 ++++++++++++++- .../Framework/Scenes/SceneObjectGroup.cs | 2 +- .../Framework/Scenes/SceneObjectPart.cs | 102 +++++++++++++++--- .../Serialization/SceneObjectSerializer.cs | 22 ++-- 4 files changed, 186 insertions(+), 28 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index f2fe970005..125cb455d2 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -19,6 +19,8 @@ using System.Net.Sockets; using System.Threading; using System.Text; +using System.IO; +using System.Xml; using Mono.Addins; using OpenMetaverse.StructuredData; @@ -198,7 +200,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private Dictionary m_primUpdates = new Dictionary(); private object m_updateScenePresenceLock = new object(); private Dictionary m_presenceUpdates = new Dictionary(); - private int m_sendingUpdates; + private int m_sendingUpdates=0; private int m_maxNumOfPropertyBuckets; @@ -242,16 +244,21 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule case "IsPhysical": case "Flying": case "Buoyancy": - m_primPropertyBucketMap.Add(pName, generalBucketName); + m_primPropertyBucketMap.Add(pName, physicsBucketName); break; default: //all other properties belong to the "General" bucket. - m_primPropertyBucketMap.Add(pName, physicsBucketName); + m_primPropertyBucketMap.Add(pName, generalBucketName); break; } } } + private bool IsSyncingWithOtherActors() + { + return (m_syncConnectors.Count > 0); + } + public void QueueSceneObjectPartForUpdate(SceneObjectPart part) { //if the last update of the prim is caused by this actor itself, or if the actor is a relay node, then enqueue the update @@ -275,6 +282,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //SendSceneUpdates put each update into an outgoing queue of each SyncConnector public void SendSceneUpdates() { + if (!IsSyncingWithOtherActors()) + { + //no SyncConnector connected. Do nothing. + return; + } + // Existing value of 1 indicates that updates are currently being sent so skip updates this pass if (Interlocked.Exchange(ref m_sendingUpdates, 1) == 1) { @@ -389,6 +402,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public void SendTerrainUpdates(string lastUpdateActorID) { + if (!IsSyncingWithOtherActors()) + { + //no SyncConnector connected. Do nothing. + return; + } if(m_isSyncRelay || m_actorID.Equals(lastUpdateActorID)) { //m_scene.Heightmap should have been updated already by the caller, send it out @@ -406,7 +424,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //private void RegionSyncModule_OnObjectBeingRemovedFromScene(SceneObjectGroup sog) public void SendDeleteObject(SceneObjectGroup sog, bool softDelete) { - m_log.DebugFormat("SendDeleteObject called for object {0}", sog.UUID); + if (!IsSyncingWithOtherActors()) + { + //no SyncConnector connected. Do nothing. + return; + } + + m_log.DebugFormat(LogHeader+"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 //if (m_isSyncRelay || CheckObjectForSendingUpdate(sog)) @@ -428,6 +452,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { if(children.Count==0) return; + if (!IsSyncingWithOtherActors()) + { + //no SyncConnector connected. Do nothing. + return; + } + OSDMap data = new OSDMap(); string sogxml = SceneObjectSerializer.ToXml2Format(linkedGroup); data["linkedGroup"]=OSD.FromString(sogxml); @@ -449,6 +479,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { if (prims.Count==0 || beforeDelinkGroups.Count==0) return; + if (!IsSyncingWithOtherActors()) + { + //no SyncConnector connected. Do nothing. + return; + } + OSDMap data = new OSDMap(); data["partCount"] = OSD.FromInteger(prims.Count); int partNum = 0; @@ -486,6 +522,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs) { + if (!IsSyncingWithOtherActors()) + { + //no SyncConnector connected. Do nothing. + return; + } + switch (ev) { case EventManager.EventNames.NewScript: @@ -566,9 +608,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule Command cmdSyncStatus = new Command("status", CommandIntentions.COMMAND_HAZARDOUS, SyncStatus, "Displays synchronization status."); + //for debugging purpose + Command cmdSyncDebug = new Command("debug", CommandIntentions.COMMAND_HAZARDOUS, SyncDebug, "Trigger some debugging functions"); + m_commander.RegisterCommand("start", cmdSyncStart); m_commander.RegisterCommand("stop", cmdSyncStop); m_commander.RegisterCommand("status", cmdSyncStatus); + m_commander.RegisterCommand("debug", cmdSyncDebug); lock (m_scene) { @@ -794,7 +840,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } //Start symmetric synchronization initialization automatically - SyncStart(null); + //SyncStart(null); } private void StartLocalSyncListener() @@ -930,6 +976,38 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_log.Warn("[REGION SYNC MODULE]: SyncStatus() TO BE IMPLEMENTED !!!"); } + private void SyncDebug(Object[] args) + { + if (m_scene != null) + { + EntityBase[] entities = m_scene.GetEntities(); + foreach (EntityBase entity in entities) + { + if (entity is SceneObjectGroup) + { + //first test serialization + StringWriter sw = new StringWriter(); + XmlTextWriter writer = new XmlTextWriter(sw); + Dictionary bucketSyncInfoList = new Dictionary(); + BucketSyncInfo generalBucket = new BucketSyncInfo(DateTime.Now.Ticks, m_actorID, "General"); + bucketSyncInfoList.Add("General", generalBucket); + BucketSyncInfo physicsBucket = new BucketSyncInfo(DateTime.Now.Ticks, m_actorID, "Physics"); + bucketSyncInfoList.Add("Physics", physicsBucket); + SceneObjectSerializer.WriteBucketSyncInfo(writer, bucketSyncInfoList); + + string xmlString = sw.ToString(); + m_log.Debug("Serialized xml string: " + xmlString); + + //second, test de-serialization + XmlTextReader reader = new XmlTextReader(new StringReader(xmlString)); + SceneObjectPart part = new SceneObjectPart(); + SceneObjectSerializer.ProcessBucketSyncInfo(part, reader); + break; + } + } + } + } + //Start connections to each remote listener. //For now, there is only one remote listener. private bool StartSyncConnections() diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 432f83ceb8..8a951f1df8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -581,7 +581,7 @@ namespace OpenSim.Region.Framework.Scenes //ScheduleGroupForFullUpdate(); //SYMMETRIC SYNC - if (m_scene.RegionSyncClientModule != null) + if (m_scene.RegionSyncModule != null) { foreach (SceneObjectPart part in Parts) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 42cff1809c..5b728d86e8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -186,9 +186,13 @@ namespace OpenSim.Region.Framework.Scenes set { m_allowedDrop = value; - UpdateBucketSyncInfo("AllowedDrop"); + //UpdateBucketSyncInfo("AllowedDrop"); } } + public void SetAllowedDrop(bool value) + { + m_allowedDrop = value; + } public bool DIE_AT_EDGE; @@ -793,6 +797,10 @@ namespace OpenSim.Region.Framework.Scenes } set { + //SetGroupPosition(value); + //UpdateBucketSyncInfo("GroupPosition"); + + //Legacy Opensim code m_groupPosition = value; PhysicsActor actor = PhysActor; @@ -833,8 +841,54 @@ namespace OpenSim.Region.Framework.Scenes } } } + } } + //SYMMETRIC SYNC + public void SetGroupPosition(Vector3 value) + { + m_groupPosition = value; + + PhysicsActor actor = PhysActor; + if (actor != null) + { + try + { + // Root prim actually goes at Position + if (_parentID == 0) + { + actor.Position = value; + } + else + { + // To move the child prim in respect to the group position and rotation we have to calculate + actor.Position = GetWorldPosition(); + actor.Orientation = GetWorldRotation(); + } + + // Tell the physics engines that this prim changed. + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); + } + catch (Exception e) + { + m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); + } + } + + // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too + if (m_sitTargetAvatar != UUID.Zero) + { + if (m_parentGroup != null) // TODO can there be a SOP without a SOG? + { + ScenePresence avatar; + if (m_parentGroup.Scene.TryGetScenePresence(m_sitTargetAvatar, out avatar)) + { + avatar.ParentPosition = GetWorldPosition(); + } + } + } + } + public Vector3 OffsetPosition { @@ -5108,7 +5162,7 @@ namespace OpenSim.Region.Framework.Scenes - /* + private Object propertyUpdateLock = new Object(); //!!!!!! -- TODO: @@ -5236,7 +5290,7 @@ namespace OpenSim.Region.Framework.Scenes return partUpdateResult; } - */ + private bool UpdateCollisionSound(UUID updatedCollisionSound) @@ -5294,7 +5348,7 @@ namespace OpenSim.Region.Framework.Scenes //The following variables should be initialized when this SceneObjectPart is added into the local Scene. //private List SynchronizeUpdatesToScene = null; //public List BucketSyncInfoList - private Dictionary m_bucketSyncInfoList = null; + private Dictionary m_bucketSyncInfoList = new Dictionary(); public Dictionary BucketSyncInfoList { get { return m_bucketSyncInfoList; } @@ -5309,7 +5363,7 @@ namespace OpenSim.Region.Framework.Scenes private static Dictionary m_bucketUpdateLocks = new Dictionary(); private static string m_localActorID = ""; - private static int m_bucketCount = 0; + //private static int m_bucketCount = 0; //private delegate void BucketUpdateProcessor(int bucketIndex); private delegate void BucketUpdateProcessor(string bucketName); @@ -5320,7 +5374,7 @@ namespace OpenSim.Region.Framework.Scenes m_primPropertyBucketMap = propertyBucketMap; m_propertyBucketNames = bucketNames; m_localActorID = actorID; - m_bucketCount = propertyBucketMap.Count; + //m_bucketCount = bucketNames.Count; RegisterBucketUpdateProcessor(); } @@ -5373,29 +5427,51 @@ namespace OpenSim.Region.Framework.Scenes return; } long timeStamp = DateTime.Now.Ticks; - for (int i = 0; i < m_bucketCount; i++) + + m_log.Debug("InitializeBucketSyncInfo called at " + timeStamp); + + for (int i = 0; i < m_propertyBucketNames.Count; i++) { string bucketName = m_propertyBucketNames[i]; BucketSyncInfo syncInfo = new BucketSyncInfo(timeStamp, m_localActorID, bucketName); - m_bucketSyncInfoList.Add(bucketName, syncInfo); - m_bucketUpdateLocks.Add(bucketName, new Object()); + + //If the object is created by de-serialization, then it already has m_bucketSyncInfoList populated with the right number of buckets + if (m_bucketSyncInfoList.ContainsKey(bucketName)) + { + m_bucketSyncInfoList[bucketName] = syncInfo; + } + else + { + m_bucketSyncInfoList.Add(bucketName, syncInfo); + } + if (!m_bucketSyncInfoList.ContainsKey(bucketName)) + { + m_bucketUpdateLocks.Add(bucketName, new Object()); + } } } private void UpdateBucketSyncInfo(string propertyName) { - if (m_bucketSyncInfoList != null) + if (m_bucketSyncInfoList != null && m_bucketSyncInfoList.Count>0) { //int bucketIndex = m_primPropertyBucketMap[propertyName]; string bucketName = m_primPropertyBucketMap[propertyName]; long timeStamp = DateTime.Now.Ticks; - m_bucketSyncInfoList[bucketName].UpdateSyncInfo(timeStamp, m_localActorID); + if (m_bucketSyncInfoList.ContainsKey(bucketName)) + { + m_bucketSyncInfoList[bucketName].UpdateSyncInfo(timeStamp, m_localActorID); + } + else + { + m_log.Warn("No SyncInfo of bucket (name: " + bucketName + ") found"); + } } } - + /* public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart) { @@ -5452,7 +5528,7 @@ namespace OpenSim.Region.Framework.Scenes return partUpdateResult; } - + */ //private void UpdateBucketProperties(string bucketDescription, #endregion diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 5d610e733a..af94a67804 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -330,9 +330,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem); //SYMMETRIC SYNC - //m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp); - //m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID); - m_SOPXmlProcessors.Add("BucketSyncInfoList", ProcessBucketSyncInfo); + m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp); + m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID); + // m_SOPXmlProcessors.Add("BucketSyncInfoList", ProcessBucketSyncInfo); //end of SYMMETRIC SYNC #endregion @@ -418,6 +418,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization } #region SOPXmlProcessors + //SYMMETRIC SYNC NOTE: TODO -- assignments in de-serialization should directly set the values w/o triggering SceneObjectPart.UpdateBucketSyncInfo; + //That is, calling SetXXX(value) instead of "XXX = value". It's an code optimization to be done later. private static void ProcessAllowedDrop(SceneObjectPart obj, XmlTextReader reader) { obj.AllowedDrop = Util.ReadBoolean(reader); @@ -704,7 +706,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization obj.LastUpdateActorID = reader.ReadElementContentAsString("LastUpdateActorID", string.Empty); } - private static void ProcessBucketSyncInfo(SceneObjectPart obj, XmlTextReader reader) + public static void ProcessBucketSyncInfo(SceneObjectPart obj, XmlTextReader reader) { obj.BucketSyncInfoList = new Dictionary(); @@ -1236,19 +1238,20 @@ namespace OpenSim.Region.Framework.Scenes.Serialization WriteBytes(writer, "ParticleSystem", sop.ParticleSystem); //SYMMETRIC SYNC - //writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString()); - //writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID); - WriteBucketSyncInfo(writer, sop.BucketSyncInfoList); + writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString()); + writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID); + //WriteBucketSyncInfo(writer, sop.BucketSyncInfoList); //end of SYMMETRIC SYNC writer.WriteEndElement(); } //SYMMETRIC SYNC - static void WriteBucketSyncInfo(XmlTextWriter writer, Dictionary bucketSyncInfoList) + public static void WriteBucketSyncInfo(XmlTextWriter writer, Dictionary bucketSyncInfoList) { - if (bucketSyncInfoList.Count > 0) // otherwise skip this + if (bucketSyncInfoList!=null || bucketSyncInfoList.Count > 0) // otherwise skip this { + writer.WriteStartElement("BucketSyncInfoList"); foreach (KeyValuePair pair in bucketSyncInfoList) { @@ -1261,6 +1264,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization } writer.WriteEndElement(); // BucketSyncInfo + } }