From f36f1010b7cf48c4447b5bc409597645b53f8523 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Tue, 1 Feb 2011 10:07:20 -0800 Subject: [PATCH 01/22] Started to add code for concurrency control of updating objec properties on per bucket base. Added code to process to PrimPropertyBucketMap in RegionSyncModule and BucketSyncInfo in SceneObjectPart. --- .../SymmetricSync/RegionSyncModule.cs | 59 +++++++ .../Framework/Interfaces/IRegionSyncModule.cs | 1 + .../Framework/Scenes/SceneObjectPart.cs | 156 +++++++++++++++++- 3 files changed, 215 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index ecbae7927c..b26d2942d4 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -61,6 +61,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_isSyncRelay = m_sysConfig.GetBoolean("IsSyncRelay", false); m_isSyncListenerLocal = m_sysConfig.GetBoolean("IsSyncListenerLocal", false); + //Setup the PropertyBucketMap + PupolatePropertyBucketMap(m_sysConfig); + m_active = true; LogHeader += "-Actor " + m_actorID; @@ -176,6 +179,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule get { return m_isSyncRelay; } } + private Dictionary m_primPropertyBucketMap = new Dictionary(); + public Dictionary PrimPropertyBucketMap + { + get { return m_primPropertyBucketMap; } + } + public List PropertyBucketDescription = new List(); + private RegionSyncListener m_localSyncListener = null; private bool m_synced = false; @@ -186,6 +196,55 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private Dictionary m_presenceUpdates = new Dictionary(); private int m_sendingUpdates; + private int m_maxNumOfPropertyBuckets; + + //Read in configuration for which property-bucket each property belongs to, and the description of each bucket + private void PupolatePropertyBucketMap(IConfig config) + { + PupolatePropertyBuketMapByDefault(); + + } + + //If nothing configured in the config file, this is the default settings for grouping properties into different bucket + private void PupolatePropertyBuketMapByDefault() + { + //by default, there are two property buckets: the "General" bucket and the "Physics" bucket. + PropertyBucketDescription.Add("General"); + PropertyBucketDescription.Add("Physics"); + m_maxNumOfPropertyBuckets = 2; + + int generalBucketID = 0; + int physicsBucketID = 1; + + foreach (string pName in SceneObjectPart.PropertyList) + { + switch (pName){ + case "GroupPosition": + case "OffsetPosition": + case "Scale": + case "Velocity": + case "AngularVelocity": + case "RotationOffset": + case "Position": + case "Size": + case "Force": + case "RotationalVelocity": + case "PA_Acceleration": + case "Torque": + case "Orientation": + case "IsPhysical": + case "Flying": + case "Buoyancy": + m_primPropertyBucketMap.Add(pName, physicsBucketID); + break; + default: + //all other properties belong to the "General" bucket. + m_primPropertyBucketMap.Add(pName, generalBucketID); + break; + } + } + } + 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 diff --git a/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs index 5bd5957706..0b2fccb24b 100755 --- a/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs @@ -55,6 +55,7 @@ namespace OpenSim.Region.Framework.Interfaces string ActorID { get; } DSGActorTypes DSGActorType { get; set; } bool IsSyncRelay { get; } + Dictionary PrimPropertyBucketMap { get; } //Enqueue updates for scene-objects and scene-presences void QueueSceneObjectPartForUpdate(SceneObjectPart part); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 153fee1154..05140def97 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -107,6 +107,44 @@ namespace OpenSim.Region.Framework.Scenes #endregion Enumerations + //SYMMETRIC SYNC + + //Information for concurrency control of one bucket of prim proproperties. + public class BucketSyncInfo + { + private long m_lastUpdateTimeStamp; + private string m_lastUpdateActorID; + //lock for concurrent updates of the timestamp and actorID. + private Object m_updateLock = new Object(); + + public long LastUpdateTimeStamp + { + get { return m_lastUpdateTimeStamp; } + } + + public string LastUpdateActorID + { + get { return m_lastUpdateActorID; } + } + + public BucketSyncInfo(long timeStamp, string actorID) + { + m_lastUpdateTimeStamp = timeStamp; + m_lastUpdateActorID = actorID; + } + + public void UpdateSyncInfo(long timeStamp, string actorID) + { + lock (m_updateLock) + { + m_lastUpdateTimeStamp = timeStamp; + m_lastUpdateActorID = actorID; + } + } + + } + //end of SYMMETRIC SYNC + public class SceneObjectPart : IScriptHost, ISceneEntity { /// @@ -127,7 +165,18 @@ namespace OpenSim.Region.Framework.Scenes #region Fields - public bool AllowedDrop; + //SYMMETRIC SYNC + //public bool AllowedDrop; + private bool m_allowedDrop; + public bool AllowedDrop + { + get { return m_allowedDrop; } + set + { + m_allowedDrop = value; + UpdateBucketSyncInfo("AllowedDrop"); + } + } public bool DIE_AT_EDGE; @@ -4971,6 +5020,83 @@ namespace OpenSim.Region.Framework.Scenes } } + //The list of each prim's properties. This is the list of properties that matter in synchronizing prim copies on different actors. + //This list is created based on properties included in the serialization/deserialization process (see SceneObjectSerializer()) and the + //properties Physics Engine needs to synchronize to other actors. + public static List PropertyList = new List() + { + //Following properties copied from SceneObjectSerializer() + "AllowedDrop", + "CreatorID", + "CreatorData", + "FolderID", + "InventorySerial", + "TaskInventory", + "UUID", + "LocalId", + "Name", + "Material", + "PassTouches", + "RegionHandle", + "ScriptAccessPin", + "GroupPosition", + "OffsetPosition", + "RotationOffset", + "Velocity", + "AngularVelocity", + //"Acceleration", + "SOP_Acceleration", //SOP and PA read/write their own local copies of acceleration, so we distinguish the copies + "Description", + "Color", + "Text", + "SitName", + "TouchName", + "LinkNum", + "ClickAction", + "Shape", + "Scale", + "UpdateFlag", + "SitTargetOrientation", + "SitTargetPosition", + "SitTargetPositionLL", + "SitTargetOrientationLL", + "ParentID", + "CreationDate", + "Category", + "SalePrice", + "ObjectSaleType", + "OwnershipCost", + "GroupID", + "OwnerID", + "LastOwnerID", + "BaseMask", + "OwnerMask", + "GroupMask", + "EveryoneMask", + "NextOwnerMask", + "Flags", + "CollisionSound", + "CollisionSoundVolume", + "MediaUrl", + "TextureAnimation", + "ParticleSystem", + //Property names below copied from PhysicsActor, they are necessary in synchronization, but not covered the above properties + //Physics properties "Velocity" is covered above + "Position", + "Size", + "Force", + "RotationalVelocity", + "PA_Acceleration", + "Torque", + "Orientation", + "IsPhysical", + "Flying", + "Buoyancy", + }; + + + + private Object propertyUpdateLock = new Object(); //!!!!!! -- TODO: @@ -5150,6 +5276,34 @@ namespace OpenSim.Region.Framework.Scenes } + //The following three variables should be initialized when this SceneObjectPart is added into the local Scene. + private List m_bucketSyncInfo = null; + private Dictionary m_primPropertyBucketMap = null; + private string m_localActorID = ""; + + public void InitializeBucketSyncInfo(Dictionary propertyBucketMap, string actorID) + { + m_primPropertyBucketMap = propertyBucketMap; + m_localActorID = actorID; + int bucketNum = propertyBucketMap.Count; + long timeStamp = DateTime.Now.Ticks; + for (int i = 0; i < bucketNum; i++) + { + BucketSyncInfo syncInfo = new BucketSyncInfo(timeStamp, m_localActorID); + m_bucketSyncInfo.Add(syncInfo); + } + } + + private void UpdateBucketSyncInfo(string propertyName) + { + if (m_bucketSyncInfo != null) + { + int bucketIndex = m_primPropertyBucketMap[propertyName]; + long timeStamp = DateTime.Now.Ticks; + m_bucketSyncInfo[bucketIndex].UpdateSyncInfo(timeStamp, m_localActorID); + } + } + #endregion } From ce4c8e4b6f4d5b9c29e7b59a6eb66b7fe20effaa Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Tue, 1 Feb 2011 14:20:09 -0800 Subject: [PATCH 02/22] Added code to include serialization/deserialization of BucketSyncInfoList in each SceneObjectPart. --- .../SymmetricSync/RegionSyncModule.cs | 27 ++- .../Framework/Interfaces/IRegionSyncModule.cs | 10 +- .../Framework/Scenes/SceneObjectGroup.cs | 9 + .../Framework/Scenes/SceneObjectPart.cs | 181 ++++++++++++++++-- .../Serialization/SceneObjectSerializer.cs | 81 +++++++- 5 files changed, 278 insertions(+), 30 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index b26d2942d4..f2fe970005 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -179,12 +179,16 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule get { return m_isSyncRelay; } } - private Dictionary m_primPropertyBucketMap = new Dictionary(); - public Dictionary PrimPropertyBucketMap + private Dictionary m_primPropertyBucketMap = new Dictionary(); + public Dictionary PrimPropertyBucketMap { get { return m_primPropertyBucketMap; } } - public List PropertyBucketDescription = new List(); + private List m_propertyBucketDescription = new List(); + public List PropertyBucketDescription + { + get { return m_propertyBucketDescription; } + } private RegionSyncListener m_localSyncListener = null; private bool m_synced = false; @@ -201,21 +205,24 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //Read in configuration for which property-bucket each property belongs to, and the description of each bucket private void PupolatePropertyBucketMap(IConfig config) { + //We start with a default bucket map. Will add the code to read in configuration from config files later. PupolatePropertyBuketMapByDefault(); + //Pass the bucket information to SceneObjectPart. + SceneObjectPart.InitializeBucketInfo(m_primPropertyBucketMap, m_propertyBucketDescription, m_actorID); + } //If nothing configured in the config file, this is the default settings for grouping properties into different bucket private void PupolatePropertyBuketMapByDefault() { //by default, there are two property buckets: the "General" bucket and the "Physics" bucket. - PropertyBucketDescription.Add("General"); - PropertyBucketDescription.Add("Physics"); + string generalBucketName = "General"; + string physicsBucketName = "Physics"; + m_propertyBucketDescription.Add(generalBucketName); + m_propertyBucketDescription.Add(physicsBucketName); m_maxNumOfPropertyBuckets = 2; - int generalBucketID = 0; - int physicsBucketID = 1; - foreach (string pName in SceneObjectPart.PropertyList) { switch (pName){ @@ -235,11 +242,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule case "IsPhysical": case "Flying": case "Buoyancy": - m_primPropertyBucketMap.Add(pName, physicsBucketID); + m_primPropertyBucketMap.Add(pName, generalBucketName); break; default: //all other properties belong to the "General" bucket. - m_primPropertyBucketMap.Add(pName, generalBucketID); + m_primPropertyBucketMap.Add(pName, physicsBucketName); break; } } diff --git a/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs index 0b2fccb24b..812a98610d 100755 --- a/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs @@ -55,7 +55,15 @@ namespace OpenSim.Region.Framework.Interfaces string ActorID { get; } DSGActorTypes DSGActorType { get; set; } bool IsSyncRelay { get; } - Dictionary PrimPropertyBucketMap { get; } + + /// + /// The mapping of a property (identified by its name) to the index of a bucket. + /// + Dictionary PrimPropertyBucketMap { get; } + /// + /// The text description of the properties in each bucket, e.g. "General", "Physics" + /// + List PropertyBucketDescription { get; } //Enqueue updates for scene-objects and scene-presences void QueueSceneObjectPartForUpdate(SceneObjectPart part); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 605e591bf8..432f83ceb8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -579,6 +579,15 @@ namespace OpenSim.Region.Framework.Scenes // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled // for the same object with very different properties. The caller must schedule the update. //ScheduleGroupForFullUpdate(); + + //SYMMETRIC SYNC + if (m_scene.RegionSyncClientModule != null) + { + foreach (SceneObjectPart part in Parts) + { + part.InitializeBucketSyncInfo(); + } + } } public Vector3 GroupScale() diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 05140def97..42cff1809c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -116,6 +116,7 @@ namespace OpenSim.Region.Framework.Scenes private string m_lastUpdateActorID; //lock for concurrent updates of the timestamp and actorID. private Object m_updateLock = new Object(); + private string m_bucketName; public long LastUpdateTimeStamp { @@ -127,10 +128,21 @@ namespace OpenSim.Region.Framework.Scenes get { return m_lastUpdateActorID; } } - public BucketSyncInfo(long timeStamp, string actorID) + public string BucketName + { + get { return m_bucketName; } + } + + public BucketSyncInfo(string bucketName) + { + m_bucketName = bucketName; + } + + public BucketSyncInfo(long timeStamp, string actorID, string bucketName) { m_lastUpdateTimeStamp = timeStamp; m_lastUpdateActorID = actorID; + m_bucketName = bucketName; } public void UpdateSyncInfo(long timeStamp, string actorID) @@ -5096,11 +5108,12 @@ namespace OpenSim.Region.Framework.Scenes - + /* private Object propertyUpdateLock = new Object(); //!!!!!! -- TODO: //!!!!!! -- We should call UpdateXXX functions to update each property, cause some of such updates involves sanity checking. + public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart) { //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -5223,6 +5236,8 @@ namespace OpenSim.Region.Framework.Scenes return partUpdateResult; } + */ + private bool UpdateCollisionSound(UUID updatedCollisionSound) { @@ -5276,34 +5291,170 @@ namespace OpenSim.Region.Framework.Scenes } - //The following three variables should be initialized when this SceneObjectPart is added into the local Scene. - private List m_bucketSyncInfo = null; - private Dictionary m_primPropertyBucketMap = null; - private string m_localActorID = ""; + //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; + public Dictionary BucketSyncInfoList + { + get { return m_bucketSyncInfoList; } + set { m_bucketSyncInfoList = value; } + } + //TODO: serialization and deserialization processors to be added in SceneObjectSerializer - public void InitializeBucketSyncInfo(Dictionary propertyBucketMap, string actorID) + //The following variables are initialized when RegionSyncModule reads the config file for mapping of properties and buckets + private static Dictionary m_primPropertyBucketMap = null; + private static List m_propertyBucketNames = null; + //private static List m_bucketUpdateLocks = null; + private static Dictionary m_bucketUpdateLocks = new Dictionary(); + + private static string m_localActorID = ""; + private static int m_bucketCount = 0; + //private delegate void BucketUpdateProcessor(int bucketIndex); + private delegate void BucketUpdateProcessor(string bucketName); + + private static Dictionary m_bucketUpdateProcessors = new Dictionary(); + + public static void InitializeBucketInfo(Dictionary propertyBucketMap, List bucketNames, string actorID) { m_primPropertyBucketMap = propertyBucketMap; + m_propertyBucketNames = bucketNames; m_localActorID = actorID; - int bucketNum = propertyBucketMap.Count; - long timeStamp = DateTime.Now.Ticks; - for (int i = 0; i < bucketNum; i++) + m_bucketCount = propertyBucketMap.Count; + + RegisterBucketUpdateProcessor(); + } + + /// + /// Link each bucket with the function that applies updates to properties in the bucket. This is the "hard-coded" part + /// in the property-buckets implementation. When new buckets are implemented, the processing functions need to be modified accordingly. + /// + private static void RegisterBucketUpdateProcessor() + { + foreach (string bucketName in m_propertyBucketNames) { - BucketSyncInfo syncInfo = new BucketSyncInfo(timeStamp, m_localActorID); - m_bucketSyncInfo.Add(syncInfo); + switch (bucketName) + { + case "General": + m_bucketUpdateProcessors.Add(bucketName, GeneralBucketUpdateProcessor); + break; + case "Physics": + m_bucketUpdateProcessors.Add(bucketName, PhysicsBucketUpdateProcessor); + break; + default: + m_log.Warn("Bucket " + bucketName + "'s update processing function not defined yet"); + break; + } + } + } + + private static void GeneralBucketUpdateProcessor(string bucketName) + { + lock (m_bucketUpdateLocks[bucketName]) + { + + } + } + + private static void PhysicsBucketUpdateProcessor(string bucketName) + { + lock (m_bucketUpdateLocks[bucketName]) + { + + } + } + + //Should be called when the SceneObjectGroup this part is in is added to scene, see SceneObjectGroup.AttachToScene + public void InitializeBucketSyncInfo() + { + if (m_primPropertyBucketMap == null) + { + m_log.Error("Bucket Information has not been initilized. Return."); + return; + } + long timeStamp = DateTime.Now.Ticks; + for (int i = 0; i < m_bucketCount; 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()); } } private void UpdateBucketSyncInfo(string propertyName) { - if (m_bucketSyncInfo != null) + if (m_bucketSyncInfoList != null) { - int bucketIndex = m_primPropertyBucketMap[propertyName]; + //int bucketIndex = m_primPropertyBucketMap[propertyName]; + string bucketName = m_primPropertyBucketMap[propertyName]; long timeStamp = DateTime.Now.Ticks; - m_bucketSyncInfo[bucketIndex].UpdateSyncInfo(timeStamp, m_localActorID); + m_bucketSyncInfoList[bucketName].UpdateSyncInfo(timeStamp, m_localActorID); } } + + + + + public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart) + { + + ////////////////////Assumptions: //////////////////// + //(1) prim's UUID and LocalID shall not change (UUID is the unique identifies, LocalID is used to refer to the prim by, say scripts) + //(2) RegionHandle won't be updated -- each copy of Scene is hosted on a region with different region handle + //(3) ParentID won't be updated -- if the rootpart of the SceneObjectGroup changed, that will be updated in SceneObjectGroup.UpdateObjectProperties + + ////////////////////Furture enhancements://////////////////// + //For now, we only update the set of properties that are included in serialization, and some PhysicsActor properties + //See RegionSyncModule.PupolatePropertyBuketMapByDefault for the properties that are handled. + + if (updatedPart == null) + return Scene.ObjectUpdateResult.Error; + + //Compate the timestamp of each bucket and update the properties if needed + + Scene.ObjectUpdateResult partUpdateResult = Scene.ObjectUpdateResult.Unchanged; + + for (int i=0; i updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp) + { + //Our timestamp is more update to date, keep our values of the properties. Do not update anything. + continue; + } + + if (m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp == updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp) + { + if (!m_bucketSyncInfoList[bucketName].LastUpdateActorID.Equals(updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID)) + { + m_log.Warn("Different actors modified SceneObjetPart " + UUID + " with the same TimeStamp (" + m_bucketSyncInfoList[bucketName].LastUpdateActorID + + "," + updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID + ", CONFLICT RESOLUTION TO BE IMPLEMENTED!!!!"); + } + continue; + } + + //Second, if need to update local properties, call each bucket's update process + if (m_bucketUpdateProcessors.ContainsKey(bucketName)) + { + m_bucketUpdateProcessors[bucketName](bucketName); + partUpdateResult = Scene.ObjectUpdateResult.Updated; + } + else + { + m_log.Warn("No update processor for property bucket " + bucketName); + } + + + } + + 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 0596cee96d..5d610e733a 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -330,8 +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("LastUpdateTimeStamp", ProcessUpdateTimeStamp); + //m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID); + m_SOPXmlProcessors.Add("BucketSyncInfoList", ProcessBucketSyncInfo); //end of SYMMETRIC SYNC #endregion @@ -702,6 +703,55 @@ namespace OpenSim.Region.Framework.Scenes.Serialization { obj.LastUpdateActorID = reader.ReadElementContentAsString("LastUpdateActorID", string.Empty); } + + private static void ProcessBucketSyncInfo(SceneObjectPart obj, XmlTextReader reader) + { + obj.BucketSyncInfoList = new Dictionary(); + + if (reader.IsEmptyElement) + { + reader.Read(); + return; + } + string elementName = "BucketSyncInfoList"; + reader.ReadStartElement(elementName, String.Empty); + + while (reader.Name == "Bucket") + { + reader.ReadStartElement("Bucket", String.Empty); // Bucket + string bucketName=""; + long timeStamp = 0; + string actorID = ""; + while (reader.NodeType != XmlNodeType.EndElement) + { + + switch (reader.Name) + { + case "Name": + bucketName = reader.ReadElementContentAsString("Name", String.Empty); + break; + case "TimeStamp": + timeStamp = reader.ReadElementContentAsLong("TimeStamp", String.Empty); + break; + case "ActorID": + actorID = reader.ReadElementContentAsString("ActorID", String.Empty); + break; + default: + reader.ReadOuterXml(); + break; + + } + + } + reader.ReadEndElement(); + BucketSyncInfo bucketSyncInfo = new BucketSyncInfo(timeStamp, actorID, bucketName); + obj.BucketSyncInfoList.Add(bucketName, bucketSyncInfo); + } + + if (reader.NodeType == XmlNodeType.EndElement) + reader.ReadEndElement(); // BucketSyncInfoList + } + //end of SYMMETRIC SYNC #endregion @@ -1186,13 +1236,36 @@ namespace OpenSim.Region.Framework.Scenes.Serialization WriteBytes(writer, "ParticleSystem", sop.ParticleSystem); //SYMMETRIC SYNC - writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString()); - writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID); + //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) + { + if (bucketSyncInfoList.Count > 0) // otherwise skip this + { + writer.WriteStartElement("BucketSyncInfoList"); + foreach (KeyValuePair pair in bucketSyncInfoList) + { + BucketSyncInfo bucketSyncInfo = pair.Value; + writer.WriteStartElement("Bucket"); + writer.WriteElementString("Name", bucketSyncInfo.BucketName); + writer.WriteElementString("TimeStamp", bucketSyncInfo.LastUpdateTimeStamp.ToString()); + writer.WriteElementString("ActorID", bucketSyncInfo.LastUpdateActorID); + writer.WriteEndElement(); // Bucket + } + + writer.WriteEndElement(); // BucketSyncInfo + } + + } + //end of SYMMETRIC SYNC + static void WriteUUID(XmlTextWriter writer, string name, UUID id, Dictionary options) { writer.WriteStartElement(name); From 9ca061b25a0943c3097f94b53c204294172e42d6 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Wed, 2 Feb 2011 15:46:12 -0800 Subject: [PATCH 03/22] 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 + } } From c84551ae2ce487bb46add020916105c74730c51f Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Wed, 2 Feb 2011 16:44:05 -0800 Subject: [PATCH 04/22] Serialization/deserialization with BucketSyncInfoList works fine with a single object. Haven't tested with multi objects/linksets yet. --- .../Framework/Scenes/Serialization/SceneObjectSerializer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index af94a67804..f2ee8fe370 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -332,7 +332,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization //SYMMETRIC SYNC m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp); m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID); - // m_SOPXmlProcessors.Add("BucketSyncInfoList", ProcessBucketSyncInfo); + m_SOPXmlProcessors.Add("BucketSyncInfoList", ProcessBucketSyncInfo); //end of SYMMETRIC SYNC #endregion @@ -1240,7 +1240,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization //SYMMETRIC SYNC writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString()); writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID); - //WriteBucketSyncInfo(writer, sop.BucketSyncInfoList); + WriteBucketSyncInfo(writer, sop.BucketSyncInfoList); //end of SYMMETRIC SYNC writer.WriteEndElement(); From 62a9e0b7c4b1d568d4c2e4764b74a4066b1a4911 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Thu, 3 Feb 2011 17:21:00 -0800 Subject: [PATCH 05/22] No longer calling SyncInfoUpdate to update timestamp. Bucket based concurrency control now in place for a few physics properties whose SetXXX() functions have been implemented in SceneObjectPart. --- .../SymmetricSync/RegionSyncModule.cs | 34 ++++++- .../Framework/Scenes/Scene.Inventory.cs | 4 +- OpenSim/Region/Framework/Scenes/Scene.cs | 10 -- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 7 +- .../Framework/Scenes/SceneObjectGroup.cs | 41 +++++++++ .../Framework/Scenes/SceneObjectPart.cs | 92 ++++++++++++++----- .../Serialization/SceneObjectSerializer.cs | 10 +- 7 files changed, 153 insertions(+), 45 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index 125cb455d2..d289b0c913 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -262,7 +262,22 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule 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 - if (part.LastUpdateActorID.Equals(m_actorID) || m_isSyncRelay) + //if (part.LastUpdateActorID.Equals(m_actorID) || m_isSyncRelay) + bool updated = m_isSyncRelay; + + if (!updated) + { + foreach (KeyValuePair pair in part.BucketSyncInfoList) + { + if (pair.Value.LastUpdateActorID.Equals(m_actorID)) + { + updated = true; + break; + } + } + } + + if(updated) { lock (m_updateSceneObjectPartLock) { @@ -273,10 +288,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public void QueueScenePresenceForTerseUpdate(ScenePresence presence) { + /* lock (m_updateScenePresenceLock) { m_presenceUpdates[presence.UUID] = presence; } + * */ } //SendSceneUpdates put each update into an outgoing queue of each SyncConnector @@ -740,7 +757,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } /// - /// Check if we need to send out an update message for the given object. + /// Check if we need to send out an update message for the given object. For now, we have a very inefficient solution: + /// If any synchronization bucket in any part shows a property in that bucket has changed, we'll serialize and ship the whole object. /// /// /// @@ -749,10 +767,20 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //If any part in the object has the last update caused by this actor itself, then send the update foreach (SceneObjectPart part in sog.Parts) { + /* if (part.LastUpdateActorID.Equals(m_actorID)) { return true; } + * */ + + foreach (KeyValuePair pair in part.BucketSyncInfoList) + { + if (pair.Value.LastUpdateActorID.Equals(m_actorID)) + { + return true; + } + } } return false; @@ -840,7 +868,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } //Start symmetric synchronization initialization automatically - //SyncStart(null); + SyncStart(null); } private void StartLocalSyncListener() diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index cb3de01774..fa81d8c290 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1720,7 +1720,7 @@ namespace OpenSim.Region.Framework.Scenes * */ if (RegionSyncModule != null) { - part.SyncInfoUpdate(); + //part.SyncInfoUpdate(); EventManager.TriggerNewScript(remoteClient.AgentId, part, copyID); } else @@ -1798,7 +1798,7 @@ namespace OpenSim.Region.Framework.Scenes //part.ParentGroup.ResumeScripts(); if (RegionSyncModule != null) { - part.SyncInfoUpdate(); + //part.SyncInfoUpdate(); EventManager.TriggerNewScript(remoteClient.AgentId, part, taskItem.ItemID); } else diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index cf6428c8a6..9341c577e0 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2560,16 +2560,6 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); - //SYMMETRIC SYNC - //Set the ActorID and TimeStamp info for this latest update - /* - foreach (SceneObjectPart part in group.Parts) - { - part.SyncInfoUpdate(); - } - * - * */ - //Propagate the RemovedObject message if (RegionSyncModule != null) { diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index c3bace8447..74cabc011c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1599,7 +1599,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentScene.RegionSyncModule != null) { //Tell other actors to link the SceneObjectParts together as a new group. - parentGroup.SyncInfoUpdate(); + //parentGroup.SyncInfoUpdate(); m_parentScene.RegionSyncModule.SendLinkObject(parentGroup, root, children); } @@ -1747,6 +1747,7 @@ namespace OpenSim.Region.Framework.Scenes //SYMMETRIC SYNC //set timestamp + /* long timeStamp = DateTime.Now.Ticks; string actorID = m_parentScene.GetSyncActorID(); foreach (SceneObjectGroup sog in afterDelinkGroups) @@ -1756,6 +1757,7 @@ namespace OpenSim.Region.Framework.Scenes sog.SyncInfoUpdate(timeStamp, actorID); ; } } + * */ //Send out DelinkObject message to other actors to sychronize their object list m_parentScene.RegionSyncModule.SendDeLinkObject(prims, beforeDelinkGroups, afterDelinkGroups); @@ -2065,7 +2067,10 @@ namespace OpenSim.Region.Framework.Scenes } m_numPrim += children.Length; + //SYMMETRIC SYNC, sceneObject.AttachToScene(m_parentScene); + //sceneObject.AttachToSceneBySync(m_parentScene); + //end of SYMMETRIC SYNC, //SYMMETRIC SYNC, sceneObject.ScheduleGroupForFullUpdate_SyncInfoUnchanged(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 8a951f1df8..3a95d4356d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3868,6 +3868,7 @@ namespace OpenSim.Region.Framework.Scenes } + /* public void SyncInfoUpdate() { long timeStamp = DateTime.Now.Ticks; @@ -3885,6 +3886,46 @@ namespace OpenSim.Region.Framework.Scenes part.SyncInfoUpdate(timeStamp, actorID); } } + * */ + + /// + /// Attach this object to a scene after a new object is created due to receiving a sync message. + /// Code similar to AttachToScene, except that this does not invoke InitializeBucketSyncInfo of each part, + /// as that information is included in the incoming message. + /// + /// + public void AttachToSceneBySync(Scene scene) + { + m_scene = scene; + RegionHandle = m_scene.RegionInfo.RegionHandle; + + if (m_rootPart.Shape.PCode != 9 || m_rootPart.Shape.State == 0) + m_rootPart.ParentID = 0; + if (m_rootPart.LocalId == 0) + m_rootPart.LocalId = m_scene.AllocateLocalId(); + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + { + SceneObjectPart part = parts[i]; + if (Object.ReferenceEquals(part, m_rootPart)) + continue; + + if (part.LocalId == 0) + part.LocalId = m_scene.AllocateLocalId(); + + part.ParentID = m_rootPart.LocalId; + //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); + } + + ApplyPhysics(m_scene.m_physicalPrim); + + // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled + // for the same object with very different properties. The caller must schedule the update. + //ScheduleGroupForFullUpdate(); + + } + #endregion } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index dbde8f202c..ddc52ac2a9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -121,11 +121,13 @@ namespace OpenSim.Region.Framework.Scenes public long LastUpdateTimeStamp { get { return m_lastUpdateTimeStamp; } + set { m_lastUpdateTimeStamp = value; } } public string LastUpdateActorID { get { return m_lastUpdateActorID; } + set { m_lastUpdateActorID = value; } } public string BucketName @@ -3131,7 +3133,7 @@ namespace OpenSim.Region.Framework.Scenes //SYMMETRIC SYNC //update information (timestamp, actorID, etc) needed for synchronization across copies of Scene - SyncInfoUpdate(); + //SyncInfoUpdate(); //end of SYMMETRIC SYNC } @@ -3159,7 +3161,7 @@ namespace OpenSim.Region.Framework.Scenes //SYMMETRIC SYNC //update information (timestamp, actorID, etc) needed for synchronization across copies of Scene - SyncInfoUpdate(); + //SyncInfoUpdate(); //end of SYMMETRIC SYNC } @@ -5158,6 +5160,7 @@ namespace OpenSim.Region.Framework.Scenes //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_lastUpdateActorID=""; public string LastUpdateActorID { @@ -5169,6 +5172,7 @@ namespace OpenSim.Region.Framework.Scenes { m_lastUpdateTimeStamp = time; } + public void SetLastUpdateActorID() { @@ -5182,17 +5186,19 @@ 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() { @@ -5204,6 +5210,7 @@ namespace OpenSim.Region.Framework.Scenes SyncInfoUpdate(DateTime.Now.Ticks, m_parentGroup.Scene.GetSyncActorID()); } } + * */ //The list of each prim's properties. This is the list of properties that matter in synchronizing prim copies on different actors. //This list is created based on properties included in the serialization/deserialization process (see SceneObjectSerializer()) and the @@ -5281,7 +5288,7 @@ namespace OpenSim.Region.Framework.Scenes - + /* private Object propertyUpdateLock = new Object(); //!!!!!! -- TODO: @@ -5410,6 +5417,8 @@ namespace OpenSim.Region.Framework.Scenes return partUpdateResult; } + * */ + private bool UpdateCollisionSound(UUID updatedCollisionSound) @@ -5424,8 +5433,12 @@ namespace OpenSim.Region.Framework.Scenes public string DebugObjectPartProperties() { - string debugMsg = "UUID " + UUID + ", Name " + Name + ", localID " + LocalId + ", lastUpdateActorID " + LastUpdateActorID + ", lastUpdateTimeStamp " + LastUpdateTimeStamp; + string debugMsg = "UUID " + UUID + ", Name " + Name + ", localID " + LocalId; debugMsg += ", parentID " + ParentID + ", parentUUID " + ParentUUID; + foreach (KeyValuePair pair in m_bucketSyncInfoList) + { + debugMsg += ", Bucket " + pair.Key + ": TimeStamp - " + pair.Value.LastUpdateTimeStamp + ", ActorID - " + pair.Value.LastUpdateActorID; + } return debugMsg; } @@ -5484,9 +5497,10 @@ namespace OpenSim.Region.Framework.Scenes private static string m_localActorID = ""; //private static int m_bucketCount = 0; //private delegate void BucketUpdateProcessor(int bucketIndex); - private delegate void BucketUpdateProcessor(string bucketName); + private delegate void BucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName); - private static Dictionary m_bucketUpdateProcessors = new Dictionary(); + //private static Dictionary m_bucketUpdateProcessors = new Dictionary(); + private Dictionary m_bucketUpdateProcessors = new Dictionary(); public static void InitializeBucketInfo(Dictionary propertyBucketMap, List bucketNames, string actorID) { @@ -5495,14 +5509,17 @@ namespace OpenSim.Region.Framework.Scenes m_localActorID = actorID; //m_bucketCount = bucketNames.Count; - RegisterBucketUpdateProcessor(); + //RegisterBucketUpdateProcessor(); } /// - /// Link each bucket with the function that applies updates to properties in the bucket. This is the "hard-coded" part - /// in the property-buckets implementation. When new buckets are implemented, the processing functions need to be modified accordingly. + /// Link each bucket with the function that applies updates to properties in the bucket upon receiving sync messages. + /// This is the "hard-coded" part in the property-buckets implementation. When new buckets are implemented, + /// the processing functions need to be modified accordingly. /// - private static void RegisterBucketUpdateProcessor() + //private static void RegisterBucketUpdateProcessor() + private void RegisterBucketUpdateProcessor() + { foreach (string bucketName in m_propertyBucketNames) { @@ -5521,19 +5538,42 @@ namespace OpenSim.Region.Framework.Scenes } } - private static void GeneralBucketUpdateProcessor(string bucketName) + private void GeneralBucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName) { lock (m_bucketUpdateLocks[bucketName]) { - + m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp; + m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID; } } - private static void PhysicsBucketUpdateProcessor(string bucketName) + private void PhysicsBucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName) { lock (m_bucketUpdateLocks[bucketName]) { + SetGroupPosition(updatedPart.GroupPosition); + SetOffsetPosition(updatedPart.OffsetPosition); + SetScale(updatedPart.Scale); + SetVelocity(updatedPart.Velocity); + SetAngularVelocity(updatedPart.AngularVelocity); + SetRotationOffset(updatedPart.RotationOffset); + //implementation in PhysicsActor + /* + "Position": + "Size": + "Force": + "RotationalVelocity": + "PA_Acceleration": + "Torque": + "Orientation": + "IsPhysical": + "Flying": + "Buoyancy": + * */ + + m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp; + m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID; } } @@ -5556,19 +5596,22 @@ namespace OpenSim.Region.Framework.Scenes BucketSyncInfo syncInfo = new BucketSyncInfo(timeStamp, m_localActorID, bucketName); //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 + if (!m_bucketSyncInfoList.ContainsKey(bucketName)) + //if (m_bucketSyncInfoList.ContainsKey(bucketName)) + //{ + // m_bucketSyncInfoList[bucketName] = syncInfo; + //} + //else { m_bucketSyncInfoList.Add(bucketName, syncInfo); } - if (!m_bucketSyncInfoList.ContainsKey(bucketName)) + if (!m_bucketUpdateLocks.ContainsKey(bucketName)) { m_bucketUpdateLocks.Add(bucketName, new Object()); } } + + RegisterBucketUpdateProcessor(); } /// @@ -5595,8 +5638,6 @@ namespace OpenSim.Region.Framework.Scenes - /* - public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart) { @@ -5616,7 +5657,8 @@ namespace OpenSim.Region.Framework.Scenes Scene.ObjectUpdateResult partUpdateResult = Scene.ObjectUpdateResult.Unchanged; - for (int i=0; i updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp) @@ -5638,7 +5680,7 @@ namespace OpenSim.Region.Framework.Scenes //Second, if need to update local properties, call each bucket's update process if (m_bucketUpdateProcessors.ContainsKey(bucketName)) { - m_bucketUpdateProcessors[bucketName](bucketName); + m_bucketUpdateProcessors[bucketName](updatedPart, bucketName); partUpdateResult = Scene.ObjectUpdateResult.Updated; } else @@ -5652,7 +5694,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 b2f891078c..415be99c69 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -330,8 +330,8 @@ 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("LastUpdateTimeStamp", ProcessUpdateTimeStamp); + //m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID); m_SOPXmlProcessors.Add("BucketSyncInfoList", ProcessBucketSyncInfo); //end of SYMMETRIC SYNC @@ -703,6 +703,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization } //SYMMETRIC SYNC + /* private static void ProcessUpdateTimeStamp(SceneObjectPart obj, XmlTextReader reader) { obj.LastUpdateTimeStamp = reader.ReadElementContentAsLong("LastUpdateTimeStamp", string.Empty); @@ -712,6 +713,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization { obj.LastUpdateActorID = reader.ReadElementContentAsString("LastUpdateActorID", string.Empty); } + * */ public static void ProcessBucketSyncInfo(SceneObjectPart obj, XmlTextReader reader) { @@ -1245,8 +1247,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization WriteBytes(writer, "ParticleSystem", sop.ParticleSystem); //SYMMETRIC SYNC - writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString()); - writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID); + //writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString()); + //writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID); WriteBucketSyncInfo(writer, sop.BucketSyncInfoList); //end of SYMMETRIC SYNC From 4fe0c6d0d21953bd17ba2789d2e7919fbc888673 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Fri, 4 Feb 2011 11:09:00 -0800 Subject: [PATCH 06/22] Fixed a few bugs. Code now good for updating the physics properties implemented in SOG. Events propagation also seems working fine (chat, link/delink objects, delete, etc). --- .../Region/Framework/Scenes/SceneObjectPart.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ddc52ac2a9..e4c65a3ff4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -5579,6 +5579,7 @@ namespace OpenSim.Region.Framework.Scenes //Initialize and set the values of timestamp and actorID for each synchronization bucket. //Should be called when the SceneObjectGroup this part is in is added to scene, see SceneObjectGroup.AttachToScene. + private bool m_BucketUpdateProcessorRegistered = false; public void InitializeBucketSyncInfo() { if (m_primPropertyBucketMap == null) @@ -5593,16 +5594,12 @@ namespace OpenSim.Region.Framework.Scenes for (int i = 0; i < m_propertyBucketNames.Count; i++) { string bucketName = m_propertyBucketNames[i]; - BucketSyncInfo syncInfo = new BucketSyncInfo(timeStamp, m_localActorID, bucketName); - //If the object is created by de-serialization, then it already has m_bucketSyncInfoList populated with the right number of buckets + //If the object is created by de-serialization, then it already has m_bucketSyncInfoList populated with the right number of buckets. + //If the deserilaization is due to receiving a sync message, then m_bucketSyncInfoList should already be filled with sync info. if (!m_bucketSyncInfoList.ContainsKey(bucketName)) - //if (m_bucketSyncInfoList.ContainsKey(bucketName)) - //{ - // m_bucketSyncInfoList[bucketName] = syncInfo; - //} - //else { + BucketSyncInfo syncInfo = new BucketSyncInfo(timeStamp, m_localActorID, bucketName); m_bucketSyncInfoList.Add(bucketName, syncInfo); } if (!m_bucketUpdateLocks.ContainsKey(bucketName)) @@ -5611,7 +5608,11 @@ namespace OpenSim.Region.Framework.Scenes } } - RegisterBucketUpdateProcessor(); + if (!m_BucketUpdateProcessorRegistered) + { + RegisterBucketUpdateProcessor(); + m_BucketUpdateProcessorRegistered = true; + } } /// From 2ae8917c2e10f131021899833956514c4a413e19 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Fri, 4 Feb 2011 15:01:38 -0800 Subject: [PATCH 07/22] Modified/added set functions for SOP properties: "AllowedDrop" to "Material", as listed in SceneObjectSerializer(). --- .../Framework/Scenes/SceneObjectPart.cs | 56 ++++++++++++++-- .../Scenes/SceneObjectPartInventory.cs | 67 +++++++++++++++++-- 2 files changed, 114 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index e4c65a3ff4..093bd0b75c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -511,9 +511,16 @@ namespace OpenSim.Region.Framework.Scenes } set { - _creatorID = value; + SetCreatorID(value); + UpdateBucketSyncInfo("CreatorID"); + //_creatorID = value; } } + //SYMMETRIC SYNC + public void SetCreatorID(UUID value) + { + _creatorID = value; + } /// /// Data about the creator in the form profile_url;name @@ -521,7 +528,17 @@ namespace OpenSim.Region.Framework.Scenes public string CreatorData { get { return m_creatorData; } - set { m_creatorData = value; } + set + { + SetCreatorData(value); + UpdateBucketSyncInfo("CreatorData"); + //m_creatorData = value; + } + } + //SYMMETRIC SYNC + public void SetCreatorData(string value) + { + m_creatorData = value; } /// @@ -637,11 +654,22 @@ namespace OpenSim.Region.Framework.Scenes get { return m_name; } set { + /* m_name = value; if (PhysActor != null) { PhysActor.SOPName = value; } + * */ + } + } + //SYMMETRIC SYNC + public void SetName(string value) + { + m_name = value; + if (PhysActor != null) + { + PhysActor.SOPName = value; } } @@ -650,13 +678,27 @@ namespace OpenSim.Region.Framework.Scenes get { return (byte) m_material; } set { + SetMaterial(value); + UpdateBucketSyncInfo("Material"); + /* m_material = (Material)value; if (PhysActor != null) { PhysActor.SetMaterial((int)value); } + * */ } } + //SYMMETRIC SYNC + public void SetMaterial(byte value) + { + m_material = (Material)value; + if (PhysActor != null) + { + PhysActor.SetMaterial((int)value); + } + } + public bool PassTouches { @@ -3060,6 +3102,10 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.HasGroupChanged = true; ScheduleFullUpdate(); + + //SYMMETRIC SYNC + //Make sure we record down the timestamp info for synchronization purpose + UpdateBucketSyncInfo("Scale"); } public void RotLookAt(Quaternion target, float strength, float damping) @@ -5558,7 +5604,7 @@ namespace OpenSim.Region.Framework.Scenes SetAngularVelocity(updatedPart.AngularVelocity); SetRotationOffset(updatedPart.RotationOffset); - //implementation in PhysicsActor + //properties in Physics bucket whose update processors are in PhysicsActor /* "Position": "Size": @@ -5595,7 +5641,7 @@ namespace OpenSim.Region.Framework.Scenes { string bucketName = m_propertyBucketNames[i]; - //If the object is created by de-serialization, then it already has m_bucketSyncInfoList populated with the right number of buckets. + //If the object is created by de-serialization, then it may already have m_bucketSyncInfoList populated with the right number of buckets. //If the deserilaization is due to receiving a sync message, then m_bucketSyncInfoList should already be filled with sync info. if (!m_bucketSyncInfoList.ContainsKey(bucketName)) { @@ -5619,7 +5665,7 @@ namespace OpenSim.Region.Framework.Scenes /// Update the timestamp and actorID information of the bucket the given property belongs to. /// /// Name of the property. Make sure the spelling is consistent with what are defined in PropertyList - private void UpdateBucketSyncInfo(string propertyName) + public void UpdateBucketSyncInfo(string propertyName) { if (m_bucketSyncInfoList != null && m_bucketSyncInfoList.Count>0) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 67de34e1b0..69df8ec153 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -76,7 +76,19 @@ namespace OpenSim.Region.Framework.Scenes protected internal uint Serial { get { return m_inventorySerial; } - set { m_inventorySerial = value; } + set + { + SetSerial(value); + m_part.UpdateBucketSyncInfo("InventorySerial"); + //m_inventorySerial = value; + } + } + + //SYMMETRIC SYNC + protected void SetSerial(uint value) + { + m_inventorySerial = value; + } /// @@ -87,10 +99,19 @@ namespace OpenSim.Region.Framework.Scenes get { return m_items; } set { - m_items = value; - m_inventorySerial++; + SetItems(value); + m_part.UpdateBucketSyncInfo("TaskInventory"); + m_part.UpdateBucketSyncInfo("InventorySerial"); + //m_items = value; + //m_inventorySerial++; } } + //SYMMETRIC SYNC + protected void SetItems(TaskInventoryDictionary value) + { + m_items = value; + m_inventorySerial++; + } /// /// Constructor @@ -136,6 +157,10 @@ namespace OpenSim.Region.Framework.Scenes item.ResetIDs(m_part.UUID); m_items.Add(item.ItemID, item); } + + //SYMMETRIC SYNC + //No need to trigger UpdateBucketSyncInfo, as callers eventually will call SOG.AttachToScene and init BucketSyncInfo + } } @@ -152,6 +177,9 @@ namespace OpenSim.Region.Framework.Scenes item.ParentID = m_part.UUID; Items.Add(item.ItemID, item); } + + //SYMMETRIC SYNC + //No need to trigger UpdateBucketSyncInfo, this is called only when SOP.UUID is written, which is assumed not to change after being created. } } @@ -182,6 +210,9 @@ namespace OpenSim.Region.Framework.Scenes item.PermsGranter = UUID.Zero; } } + + //SYMMETRIC SYNC + m_part.UpdateBucketSyncInfo("TaskInventory"); } /// @@ -213,6 +244,12 @@ namespace OpenSim.Region.Framework.Scenes if (groupID != item.GroupID) item.GroupID = groupID; } + + //SYMMETRIC SYNC: need to test if we need to take different actions when this is attachment or not + //if (!m_part.ParentGroup.RootPart.IsAttachment) + //{ + m_part.UpdateBucketSyncInfo("TaskInventory"); + } /// @@ -543,7 +580,11 @@ namespace OpenSim.Region.Framework.Scenes m_part.ParentGroup.HasGroupChanged = true; //SYMMETRIC SYNC: add ScheduleFullUpdate to enable synchronization across actors - m_part.ScheduleFullUpdate(); + //m_part.ScheduleFullUpdate(); + + //SYMMETRIC SYNC + m_part.UpdateBucketSyncInfo("TaskInventory"); + m_part.UpdateBucketSyncInfo("InventorySerial"); //m_inventorySerial is also changed, } /// @@ -564,6 +605,9 @@ namespace OpenSim.Region.Framework.Scenes } m_inventorySerial++; } + + //SYMMETRIC SYNC: no UpdateBucketSyncInfo called here, since this function is called by loading objects from DB, and UpdateBucketSyncInfo + //will be called after all objects are loaded. } /// @@ -722,6 +766,10 @@ namespace OpenSim.Region.Framework.Scenes HasInventoryChanged = true; m_part.ParentGroup.HasGroupChanged = true; } + + //SYMMETRIC SYNC + m_part.UpdateBucketSyncInfo("TaskInventory"); + m_part.UpdateBucketSyncInfo("InventorySerial"); return true; } else @@ -765,6 +813,10 @@ namespace OpenSim.Region.Framework.Scenes m_part.ScheduleFullUpdate(); + //SYMMETRIC SYNC + m_part.UpdateBucketSyncInfo("TaskInventory"); + m_part.UpdateBucketSyncInfo("InventorySerial"); + return type; } @@ -1019,6 +1071,9 @@ namespace OpenSim.Region.Framework.Scenes item.OwnerChanged = true; item.PermsMask = 0; item.PermsGranter = UUID.Zero; + + //SYMMETRIC SYNC + m_part.UpdateBucketSyncInfo("TaskInventory"); } } } @@ -1035,6 +1090,10 @@ namespace OpenSim.Region.Framework.Scenes } m_inventorySerial++; HasInventoryChanged = true; + + //SYMMETRIC SYNC + m_part.UpdateBucketSyncInfo("TaskInventory"); + m_part.UpdateBucketSyncInfo("InventorySerial"); } public bool ContainsScripts() From c929348668a9d3cd5bd88bdf596948df00564d52 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Fri, 4 Feb 2011 17:05:08 -0800 Subject: [PATCH 08/22] Majority of SOP properties have set functions added. --- .../Framework/Scenes/SceneObjectPart.cs | 391 ++++++++++++++++-- 1 file changed, 360 insertions(+), 31 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 093bd0b75c..8f63e69e6b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -610,6 +610,11 @@ namespace OpenSim.Region.Framework.Scenes get { return m_inventory.Serial; } set { m_inventory.Serial = value; } } + //SYMMETRIC SYNC: implemented to be consistent with other properties. "m_inventory.Serial" set function will trigger UpdateBucketSyncInfo if appropriate + public void SetInventorySerial(uint value) + { + m_inventory.Serial = value; + } /// /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes @@ -619,6 +624,11 @@ namespace OpenSim.Region.Framework.Scenes get { return m_inventory.Items; } set { m_inventory.Items = value; } } + //SYMMETRIC SYNC: implemented to be consistent with other properties. "m_inventory.Items" set function will trigger UpdateBucketSyncInfo if appropriate + public void SetTaskInventory(TaskInventoryDictionary value) + { + m_inventory.Items = value; + } /// /// This is idential to the Flags property, except that the returned value is uint rather than PrimFlags @@ -705,11 +715,22 @@ namespace OpenSim.Region.Framework.Scenes get { return m_passTouches; } set { + SetPassTouches(value); + UpdateBucketSyncInfo("PassTouches"); + /* m_passTouches = value; if (ParentGroup != null) ParentGroup.HasGroupChanged = true; + * */ } } + //SYMMETRIC SYNC + public void SetPassTouches(bool value) + { + m_passTouches = value; + if (ParentGroup != null) + ParentGroup.HasGroupChanged = true; + } @@ -752,8 +773,20 @@ namespace OpenSim.Region.Framework.Scenes public int ScriptAccessPin { get { return m_scriptAccessPin; } - set { m_scriptAccessPin = (int)value; } + set + { + SetScriptAccessPin(value); + UpdateBucketSyncInfo("ScriptAccessPin"); + //m_scriptAccessPin = (int)value; + } } + //SYMMETRIC SYNC + public void SetScriptAccessPin(int value) + { + m_scriptAccessPin = (int)value; + } + + private SceneObjectPart m_PlaySoundMasterPrim = null; public SceneObjectPart PlaySoundMasterPrim { @@ -1171,7 +1204,17 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 Acceleration { get { return m_acceleration; } - set { m_acceleration = value; } + set + { + SetAcceleration(value); + UpdateBucketSyncInfo("Acceleration"); + //m_acceleration = value; + } + } + //SYMMETRIC SYNC + public void SetAcceleration(Vector3 value) + { + m_acceleration = value; } public string Description @@ -1179,12 +1222,26 @@ namespace OpenSim.Region.Framework.Scenes get { return m_description; } set { + SetDescription(value); + UpdateBucketSyncInfo("Description"); + /* m_description = value; PhysicsActor actor = PhysActor; if (actor != null) { actor.SOPDescription = value; } + * */ + } + } + //SYMMETRIC SYNC + public void SetDescription(string value) + { + m_description = value; + PhysicsActor actor = PhysActor; + if (actor != null) + { + actor.SOPDescription = value; } } @@ -1196,7 +1253,9 @@ namespace OpenSim.Region.Framework.Scenes get { return m_color; } set { - m_color = value; + SetColor(value); + UpdateBucketSyncInfo("Color"); + //m_color = value; /* ScheduleFullUpdate() need not be called b/c after * setting the color, the text will be set, so then @@ -1204,6 +1263,11 @@ namespace OpenSim.Region.Framework.Scenes //ScheduleFullUpdate(); } } + //SYMMETRIC SYNC + public void SetColor(Color value) + { + m_color = value; + } public string Text { @@ -1218,27 +1282,65 @@ namespace OpenSim.Region.Framework.Scenes } set { - m_text = value; + SetText(value, false); + UpdateBucketSyncInfo("Text"); + //m_text = value; } } + //SYMMETRIC SYNC + //SetText(string) has been defined, defined it as a different interface, the 2nd argument is not really useful + public void SetText(string value, bool bySync) + { + m_text = value; + } public string SitName { get { return m_sitName; } - set { m_sitName = value; } + set + { + SetSitName(value); + UpdateBucketSyncInfo("SitName"); + //m_sitName = value; + } + } + //SYMMETRIC SYNC + public void SetSitName(string value) + { + m_sitName = value; } public string TouchName { get { return m_touchName; } - set { m_touchName = value; } + set + { + SetTouchName(value); + UpdateBucketSyncInfo("TouchName"); + //m_touchName = value; + } + } + //SYMMETRIC SYNC + public void SetTouchName(string value) + { + m_touchName = value; } public int LinkNum { get { return m_linkNum; } - set { m_linkNum = value; } + set + { + SetLinkNum(value); + UpdateBucketSyncInfo("LinkNum"); + //m_linkNum = value; + } + } + //SYMMETRIC SYNC + public void SetLinkNum(int value) + { + m_linkNum = value; } public byte ClickAction @@ -1246,14 +1348,31 @@ namespace OpenSim.Region.Framework.Scenes get { return m_clickAction; } set { - m_clickAction = value; + SetClickAction(value); + UpdateBucketSyncInfo("ClickAction"); + //m_clickAction = value; } } + //SYMMETRIC SYNC + public void SetClickAction(byte value) + { + m_clickAction = value; + } public PrimitiveBaseShape Shape { get { return m_shape; } - set { m_shape = value; } + set + { + SetShape(value); + UpdateBucketSyncInfo("Shape"); + //m_shape = value; + } + } + //SYMMETRIC SYNC + public void SetShape(PrimitiveBaseShape value) + { + m_shape = value; } public Vector3 Scale @@ -1375,14 +1494,33 @@ namespace OpenSim.Region.Framework.Scenes public Quaternion SitTargetOrientation { get { return m_sitTargetOrientation; } - set { m_sitTargetOrientation = value; } + set + { + SetSitTargetOrientation(value); + UpdateBucketSyncInfo("SitTargetOrientation"); + //m_sitTargetOrientation = value; + } + } + //SYMMETRIC SYNC + public void SetSitTargetOrientation(Quaternion value) + { + m_sitTargetOrientation = value; } - public Vector3 SitTargetPosition { get { return m_sitTargetPosition; } - set { m_sitTargetPosition = value; } + set + { + SetSitTargetPosition(value); + UpdateBucketSyncInfo("SitTargetPosition"); + //m_sitTargetPosition = value; + } + } + //SYMMETRIC SYNC + public void SetSitTargetPosition(Vector3 value) + { + m_sitTargetPosition = value; } // This sort of sucks, but I'm adding these in to make some of @@ -1390,7 +1528,12 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 SitTargetPositionLL { get { return new Vector3(m_sitTargetPosition.X, m_sitTargetPosition.Y,m_sitTargetPosition.Z); } - set { m_sitTargetPosition = value; } + set + { + SetSitTargetPosition(value); + UpdateBucketSyncInfo("SitTargetPositionLL"); + //m_sitTargetPosition = value; + } } public Quaternion SitTargetOrientationLL @@ -1405,7 +1548,12 @@ namespace OpenSim.Region.Framework.Scenes ); } - set { m_sitTargetOrientation = new Quaternion(value.X, value.Y, value.Z, value.W); } + set + { + SetSitTargetOrientation(new Quaternion(value.X, value.Y, value.Z, value.W)); + UpdateBucketSyncInfo("SitTargetOrientationLL"); + //m_sitTargetOrientation = new Quaternion(value.X, value.Y, value.Z, value.W); + } } public bool Stopped @@ -1430,79 +1578,209 @@ namespace OpenSim.Region.Framework.Scenes public int CreationDate { get { return _creationDate; } - set { _creationDate = value; } + set + { + SetCreationDate(value); + UpdateBucketSyncInfo("CreationDate"); + //_creationDate = value; + } + } + //SYMMETRIC SYNC + public void SetCreationDate(int value) + { + _creationDate = value; } public uint Category { get { return _category; } - set { _category = value; } + set + { + SetCategory(value); + UpdateBucketSyncInfo("Category"); + //_category = value; + } + } + //SYMMETRIC SYNC + public void SetCategory(uint value) + { + _category = value; } public int SalePrice { get { return _salePrice; } - set { _salePrice = value; } + set + { + SetSalePrice(value); + UpdateBucketSyncInfo("SalePrice"); + //_salePrice = value; + } + } + //SYMMETRIC SYNC + public void SetSalePrice(int value) + { + _salePrice = value; } public byte ObjectSaleType { get { return _objectSaleType; } - set { _objectSaleType = value; } + set + { + SetObjectSaleType(value); + UpdateBucketSyncInfo("ObjectSaleType"); + //_objectSaleType = value; + } + } + //SYMMETRIC SYNC + public void SetObjectSaleType(byte value) + { + _objectSaleType = value; } public int OwnershipCost { get { return _ownershipCost; } - set { _ownershipCost = value; } + set + { + SetOwnershipCost(value); + UpdateBucketSyncInfo("OwnershipCost"); + // _ownershipCost = value; + } + } + //SYMMETRIC SYNC + public void SetOwnershipCost(int value) + { + _ownershipCost = value; } public UUID GroupID { get { return _groupID; } - set { _groupID = value; } + set + { + SetGroupID(value); + UpdateBucketSyncInfo("GroupID"); + //_groupID = value; + } + } + //SYMMETRIC SYNC + public void SetGroupID(UUID value) + { + _groupID = value; } public UUID OwnerID { get { return _ownerID; } - set { _ownerID = value; } + set + { + SetOwnerID(value); + UpdateBucketSyncInfo("OwnerID"); + // _ownerID = value; + } + } + //SYMMETRIC SYNC + public void SetOwnerID(UUID value) + { + _ownerID = value; } public UUID LastOwnerID { get { return _lastOwnerID; } - set { _lastOwnerID = value; } + set + { + SetLastOwnerID(value); + UpdateBucketSyncInfo("LastOwnerID"); + //_lastOwnerID = value; + } + } + //SYMMETRIC SYNC + public void SetLastOwnerID(UUID value) + { + _lastOwnerID = value; } public uint BaseMask { get { return _baseMask; } - set { _baseMask = value; } + set + { + SetBaseMask(value); + UpdateBucketSyncInfo("BaseMask"); + //_baseMask = value; + } + } + //SYMMETRIC SYNC + public void SetBaseMask(uint value) + { + _baseMask = value; } public uint OwnerMask { get { return _ownerMask; } - set { _ownerMask = value; } + set + { + SetOwnerMask(value); + UpdateBucketSyncInfo("OwnerMask"); + //_ownerMask = value; + } + } + //SYMMETRIC SYNC + public void SetOwnerMask(uint value) + { + _ownerMask = value; } public uint GroupMask { get { return _groupMask; } - set { _groupMask = value; } + set + { + SetGroupMask(value); + UpdateBucketSyncInfo("GroupMask"); + //_groupMask = value; + } + } + //SYMMETRIC SYNC + public void SetGroupMask(uint value) + { + _groupMask = value; } public uint EveryoneMask { get { return _everyoneMask; } - set { _everyoneMask = value; } + set + { + SetEveryoneMask(value); + UpdateBucketSyncInfo("EveryoneMask"); + //_everyoneMask = value; + } + } + //SYMMETRIC SYNC + public void SetEveryoneMask(uint value) + { + _everyoneMask = value; } public uint NextOwnerMask { get { return _nextOwnerMask; } - set { _nextOwnerMask = value; } + set + { + SetNextOwnerMask(value); + UpdateBucketSyncInfo("NextOwnerMask"); + //_nextOwnerMask = value; + } + } + //SYMMETRIC SYNC + public void SetNextOwnerMask(uint value) + { + _nextOwnerMask = value; } /// @@ -1513,11 +1791,18 @@ namespace OpenSim.Region.Framework.Scenes { get { return _flags; } set - { + { + SetFlags(value); + UpdateBucketSyncInfo("Flags"); // m_log.DebugFormat("[SOP]: Setting flags for {0} {1} to {2}", UUID, Name, value); - _flags = value; + //_flags = value; } } + //SYMMETRIC SYNC + public void SetFlags(PrimFlags value) + { + _flags = value; + } public UUID SitTargetAvatar @@ -3265,6 +3550,9 @@ namespace OpenSim.Region.Framework.Scenes m_shape = m_newshape; m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + + //SYMMETRIC SYNC + UpdateBucketSyncInfo("Shape"); } } } @@ -3831,7 +4119,10 @@ namespace OpenSim.Region.Framework.Scenes public void SetGroup(UUID groupID, IClientAPI client) { - _groupID = groupID; + //SYMMETRIC SYNC + //_groupID = groupID; + GroupID = groupID; + if (client != null) GetProperties(client); m_updateFlag = 2; @@ -3893,7 +4184,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void SetText(string text) { - Text = text; + //Text = text; + //SYMMETRIC SYNC: make set property calls consistent + m_text = text; ParentGroup.HasGroupChanged = true; ScheduleFullUpdate(); @@ -4474,6 +4767,9 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.HasGroupChanged = true; ScheduleFullUpdate(); + + //SYMMETRIC SYNC + UpdateBucketSyncInfo("Shape"); } public void UpdateGroupPosition(Vector3 pos) @@ -4539,20 +4835,28 @@ namespace OpenSim.Region.Framework.Scenes { _baseMask = ApplyMask(_baseMask, set, mask); Inventory.ApplyGodPermissions(_baseMask); + //SYMMETRIC SYNC + UpdateBucketSyncInfo("BaseMask"); } break; case 2: _ownerMask = ApplyMask(_ownerMask, set, mask) & baseMask; + //SYMMETRIC SYNC + UpdateBucketSyncInfo("OwnerMask"); break; case 4: _groupMask = ApplyMask(_groupMask, set, mask) & baseMask; + //SYMMETRIC SYNC + UpdateBucketSyncInfo("GroupMask"); break; case 8: _everyoneMask = ApplyMask(_everyoneMask, set, mask) & baseMask; + //SYMMETRIC SYNC + UpdateBucketSyncInfo("EveryoneMask"); break; case 16: _nextOwnerMask = ApplyMask(_nextOwnerMask, set, mask) & @@ -4564,6 +4868,9 @@ namespace OpenSim.Region.Framework.Scenes _nextOwnerMask |= (uint)PermissionMask.Move; + //SYMMETRIC SYNC + UpdateBucketSyncInfo("NextOwnerMask"); + break; } SendFullUpdateToAllClients(); @@ -4863,6 +5170,9 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.HasGroupChanged = true; TriggerScriptChangedEvent(Changed.SHAPE); ScheduleFullUpdate(); + + //SYMMETRIC SYNC + UpdateBucketSyncInfo("Shape"); } /// @@ -4910,6 +5220,9 @@ namespace OpenSim.Region.Framework.Scenes //ParentGroup.ScheduleGroupForFullUpdate(); //This is sparta ScheduleFullUpdate(); + + //SYMMETRIC SYNC + UpdateBucketSyncInfo("Shape"); } public void aggregateScriptEvents() @@ -5588,6 +5901,22 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_bucketUpdateLocks[bucketName]) { + SetAllowedDrop(updatedPart.AllowedDrop); + SetCreatorID(updatedPart.CreatorID); + SetCreatorData(updatedPart.CreatorData); + //FolderID skipped + SetInventorySerial(updatedPart.InventorySerial); + SetTaskInventory(updatedPart.TaskInventory); + //UUID skipped + //LocalId skipped + SetName(updatedPart.Name); + SetMaterial(updatedPart.Material); + SetPassTouches(updatedPart.PassTouches); + //RegionHandle skipped + + + SetShape(updatedPart.Shape); + m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp; m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID; } From 396486a93b5ebef8e1d0cff957c8ee2054563a1a Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Mon, 7 Feb 2011 09:45:16 -0800 Subject: [PATCH 09/22] Added set functions for the last a few properties in SOP. --- .../Framework/Scenes/SceneObjectPart.cs | 60 +++++++++++++++++-- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 8f63e69e6b..6ced51d4ef 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -819,14 +819,34 @@ namespace OpenSim.Region.Framework.Scenes public Byte[] TextureAnimation { get { return m_TextureAnimation; } - set { m_TextureAnimation = value; } + set + { + SetTextureAnimation(value); + UpdateBucketSyncInfo("TextureAnimation"); + //m_TextureAnimation = value; + } + } + //SYMMETRIC SYNC + public void SetTextureAnimation(Byte[] value) + { + m_TextureAnimation = value; } public Byte[] ParticleSystem { get { return m_particleSystem; } - set { m_particleSystem = value; } + set + { + SetParticleSystem(value); + UpdateBucketSyncInfo("ParticleSystem"); + //m_particleSystem = value; + } + } + //SYMMETRIC SYNC + public void SetParticleSystem(Byte[] value) + { + m_particleSystem = value; } @@ -1449,12 +1469,24 @@ namespace OpenSim.Region.Framework.Scenes set { + SetMediaUrl(value); + UpdateBucketSyncInfo("MediaUrl"); + /* m_mediaUrl = value; if (ParentGroup != null) ParentGroup.HasGroupChanged = true; + * */ } } + //SYMMETRIC SYNC + public void SetMediaUrl(string value) + { + m_mediaUrl = value; + + if (ParentGroup != null) + ParentGroup.HasGroupChanged = true; + } public bool CreateSelected @@ -1851,15 +1883,35 @@ namespace OpenSim.Region.Framework.Scenes get { return m_collisionSound; } set { - m_collisionSound = value; + SetCollisionSound(value); + UpdateBucketSyncInfo("CollisionSound"); + //m_collisionSound = value; aggregateScriptEvents(); } } + //SYMMETRIC SYNC + //CollisionSound is a special case. We won't call aggregateScriptEvents inside SetCollisionSound, + //so that when RegionSynModule triggers SOP.UpdateAllProperties, it calls SetCollisionSound + public void SetCollisionSound(UUID value) + { + m_collisionSound = value; + } + public float CollisionSoundVolume { get { return m_collisionSoundVolume; } - set { m_collisionSoundVolume = value; } + set + { + SetCollisionSoundVolume(value); + UpdateBucketSyncInfo("CollisionSoundVolume"); + //m_collisionSoundVolume = value; + } + } + //SYMMETRIC SYNC + public void SetCollisionSoundVolume(float value) + { + m_collisionSoundVolume = value; } #endregion Public Properties with only Get From 6cb8b01bef21b71857a1fa7438c1529db489bf4c Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Mon, 7 Feb 2011 14:15:33 -0800 Subject: [PATCH 10/22] Added m_syncEnabled in SceneObjectPart to guard again modifying any syncinfo (timestamp, etc) while deserializing and building SOP/SOG out of sync message. --- .../Framework/Scenes/SceneObjectPart.cs | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 8f63e69e6b..af9d853f16 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -776,7 +776,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetScriptAccessPin(value); - UpdateBucketSyncInfo("ScriptAccessPin"); + //UpdateBucketSyncInfo("ScriptAccessPin"); //m_scriptAccessPin = (int)value; } } @@ -1207,7 +1207,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetAcceleration(value); - UpdateBucketSyncInfo("Acceleration"); + //UpdateBucketSyncInfo("Acceleration"); //m_acceleration = value; } } @@ -1223,7 +1223,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetDescription(value); - UpdateBucketSyncInfo("Description"); + //UpdateBucketSyncInfo("Description"); /* m_description = value; PhysicsActor actor = PhysActor; @@ -1254,7 +1254,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetColor(value); - UpdateBucketSyncInfo("Color"); + //UpdateBucketSyncInfo("Color"); //m_color = value; /* ScheduleFullUpdate() need not be called b/c after @@ -1283,7 +1283,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetText(value, false); - UpdateBucketSyncInfo("Text"); + //UpdateBucketSyncInfo("Text"); //m_text = value; } } @@ -1301,7 +1301,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetSitName(value); - UpdateBucketSyncInfo("SitName"); + //UpdateBucketSyncInfo("SitName"); //m_sitName = value; } } @@ -1317,7 +1317,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetTouchName(value); - UpdateBucketSyncInfo("TouchName"); + //UpdateBucketSyncInfo("TouchName"); //m_touchName = value; } } @@ -5861,6 +5861,10 @@ namespace OpenSim.Region.Framework.Scenes //private static Dictionary m_bucketUpdateProcessors = new Dictionary(); private Dictionary m_bucketUpdateProcessors = new Dictionary(); + //Define this as a guard to not to fill in any sync info when not desired, i.e. while de-serializing and building SOP and SOG, where + //property set functions will be called and might trigger UpdateBucketSyncInfo() if not guarded carefully. + private bool m_syncEnabled = false; + public static void InitializeBucketInfo(Dictionary propertyBucketMap, List bucketNames, string actorID) { m_primPropertyBucketMap = propertyBucketMap; @@ -5988,6 +5992,8 @@ namespace OpenSim.Region.Framework.Scenes RegisterBucketUpdateProcessor(); m_BucketUpdateProcessorRegistered = true; } + + m_syncEnabled = true; } /// @@ -5996,7 +6002,7 @@ namespace OpenSim.Region.Framework.Scenes /// Name of the property. Make sure the spelling is consistent with what are defined in PropertyList public void UpdateBucketSyncInfo(string propertyName) { - if (m_bucketSyncInfoList != null && m_bucketSyncInfoList.Count>0) + if (m_syncEnabled && m_bucketSyncInfoList != null && m_bucketSyncInfoList.Count>0) { //int bucketIndex = m_primPropertyBucketMap[propertyName]; string bucketName = m_primPropertyBucketMap[propertyName]; From e9b831b8f4d1339be777b1bf988242e15660ff67 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Mon, 7 Feb 2011 17:16:26 -0800 Subject: [PATCH 11/22] 1. Updated SOP.InventorySerial and SOP.TaskInventory set functions, to make sure only local write accesses trigger UpdateBucketSyncInfo(). 2. LinkObjectsBySync(), DelinkObjectsBySync(), and functions they call into, all updated to set properties via calling SetXXX instead of by "XXX=", so that the set operations won't trigger UpdateBucketSyncInfo(). --- .../SymmetricSync/RegionSyncModule.cs | 4 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 7 ++- .../Framework/Scenes/SceneObjectGroup.cs | 29 ++++++++--- .../Framework/Scenes/SceneObjectPart.cs | 49 ++++++++++++++----- .../Scenes/SceneObjectPartInventory.cs | 8 +-- 5 files changed, 71 insertions(+), 26 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index d289b0c913..4e5c358f37 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -978,6 +978,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //save script state and stop script instances m_scene.EventManager.TriggerOnSymmetricSyncStop(); } + m_synced = true; } else { @@ -1059,11 +1060,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { syncConnector.StartCommThreads(); AddSyncConnector(syncConnector); + m_synced = true; } } - m_synced = true; - return true; } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 74cabc011c..d698e9eb42 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -2145,8 +2145,11 @@ namespace OpenSim.Region.Framework.Scenes // Make sure no child prim is set for sale // So that, on delink, no prims are unwittingly // left for sale and sold off - child.RootPart.ObjectSaleType = 0; - child.RootPart.SalePrice = 10; + //SYMMETRIC SYNC: need to copy value w/o trigger UpdateBucketSyncInfo + //child.RootPart.ObjectSaleType = 0; + //child.RootPart.SalePrice = 10; + child.RootPart.SetObjectSaleType(0); + child.RootPart.SetSalePrice(10); childGroups.Add(child); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 3a95d4356d..236a17f1d6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3694,6 +3694,9 @@ namespace OpenSim.Region.Framework.Scenes } //Similar actions with DelinkFromGroup, except that m_scene.AddNewSceneObjectBySync is called + //!!!!!!!!!!!!!!!!!!NOTE!!!!!!!!!!!!!!! + //All SOP properties below is set through calling SetXXX(value) instead of by "XXX=value", as such a value is being changed due to sync ( + //i.e. triggered by remote operation instead of by local operation public SceneObjectGroup DelinkFromGroupBySync(SceneObjectPart linkPart, bool sendEvents) { // m_log.DebugFormat( @@ -3714,7 +3717,8 @@ namespace OpenSim.Region.Framework.Scenes if (parts.Length == 1 && RootPart != null) { // Single prim left - RootPart.LinkNum = 0; + //RootPart.LinkNum = 0; + RootPart.SetLinkNum(0); } else { @@ -3722,13 +3726,18 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectPart part = parts[i]; if (part.LinkNum > linkPart.LinkNum) - part.LinkNum--; + { + //part.LinkNum--; + part.SetLinkNum(part.LinkNum--); + } } } } - linkPart.ParentID = 0; - linkPart.LinkNum = 0; + //linkPart.ParentID = 0; + //linkPart.LinkNum = 0; + linkPart.SetParentID(0); + linkPart.SetLinkNum(0); if (linkPart.PhysActor != null) { @@ -3742,11 +3751,15 @@ namespace OpenSim.Region.Framework.Scenes Vector3 axPos = linkPart.OffsetPosition; axPos *= parentRot; - linkPart.OffsetPosition = new Vector3(axPos.X, axPos.Y, axPos.Z); - linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition; - linkPart.OffsetPosition = new Vector3(0, 0, 0); + //linkPart.OffsetPosition = new Vector3(axPos.X, axPos.Y, axPos.Z); + //linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition; + //linkPart.OffsetPosition = new Vector3(0, 0, 0); + //linkPart.RotationOffset = worldRot; - linkPart.RotationOffset = worldRot; + linkPart.SetOffsetPosition(new Vector3(axPos.X, axPos.Y, axPos.Z)); + linkPart.SetGroupPosition(AbsolutePosition + linkPart.OffsetPosition); + linkPart.SetOffsetPosition(new Vector3(0, 0, 0)); + linkPart.SetRotationOffset(worldRot); SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index af9d853f16..ccfded4752 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -608,12 +608,18 @@ namespace OpenSim.Region.Framework.Scenes public uint InventorySerial { get { return m_inventory.Serial; } - set { m_inventory.Serial = value; } + set + { + SetInventorySerial(value); + UpdateBucketSyncInfo("InventorySerial"); + //m_inventory.Serial = value; + } } - //SYMMETRIC SYNC: implemented to be consistent with other properties. "m_inventory.Serial" set function will trigger UpdateBucketSyncInfo if appropriate + //SYMMETRIC SYNC: implemented to be consistent with other properties. "m_inventory.Serial" set function will trigger UpdateBucketSyncInfo, + //hence in SetInventorySerial we will call m_inventory.SetSerial to avoid triggering UpdateBucketSyncInfo(). public void SetInventorySerial(uint value) { - m_inventory.Serial = value; + m_inventory.SetSerial(value); } /// @@ -622,12 +628,18 @@ namespace OpenSim.Region.Framework.Scenes public TaskInventoryDictionary TaskInventory { get { return m_inventory.Items; } - set { m_inventory.Items = value; } + set + { + //SetTaskInventory(value); + //UpdateBucketSyncInfo("TaskInventory"); + //SYMMETRIC SYNC: "m_inventory.Items" set function will trigger UpdateBucketSyncInfo if appropriate + m_inventory.Items = value; + } } - //SYMMETRIC SYNC: implemented to be consistent with other properties. "m_inventory.Items" set function will trigger UpdateBucketSyncInfo if appropriate + //SYMMETRIC SYNC: implemented to be consistent with updating values of other properties (w/o triggering UpdateBucketSyncInfo); public void SetTaskInventory(TaskInventoryDictionary value) { - m_inventory.Items = value; + m_inventory.SetItems(value); } /// @@ -776,7 +788,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetScriptAccessPin(value); - //UpdateBucketSyncInfo("ScriptAccessPin"); + UpdateBucketSyncInfo("ScriptAccessPin"); //m_scriptAccessPin = (int)value; } } @@ -1317,7 +1329,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetTouchName(value); - //UpdateBucketSyncInfo("TouchName"); + UpdateBucketSyncInfo("TouchName"); //m_touchName = value; } } @@ -1349,7 +1361,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetClickAction(value); - UpdateBucketSyncInfo("ClickAction"); + //UpdateBucketSyncInfo("ClickAction"); //m_clickAction = value; } } @@ -1574,6 +1586,11 @@ namespace OpenSim.Region.Framework.Scenes get { return _parentID; } set { _parentID = value; } } + //SYMMETRIC SYNC: defined for consistency, for calling SetXXX in sync operations + public void SetParentID(uint value) + { + _parentID = value; + } public int CreationDate { @@ -5917,8 +5934,18 @@ namespace OpenSim.Region.Framework.Scenes SetMaterial(updatedPart.Material); SetPassTouches(updatedPart.PassTouches); //RegionHandle skipped - - + SetScriptAccessPin(updatedPart.ScriptAccessPin); + + //SetAcceleration(updatedPart.Acceleration); + //SetDescription(updatedPart.Description); + //SetColor(updatedPart.Color); + //SetText(updatedPart.Text); + //SetSitName(updatedPart.SitName); + + SetTouchName(updatedPart.TouchName); + SetLinkNum(updatedPart.LinkNum); + //SetClickAction(updatedPart.ClickAction); + SetShape(updatedPart.Shape); m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 69df8ec153..3a87dda99f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -85,7 +85,7 @@ namespace OpenSim.Region.Framework.Scenes } //SYMMETRIC SYNC - protected void SetSerial(uint value) + public void SetSerial(uint value) { m_inventorySerial = value; @@ -100,6 +100,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetItems(value); + m_inventorySerial++; m_part.UpdateBucketSyncInfo("TaskInventory"); m_part.UpdateBucketSyncInfo("InventorySerial"); //m_items = value; @@ -107,10 +108,11 @@ namespace OpenSim.Region.Framework.Scenes } } //SYMMETRIC SYNC - protected void SetItems(TaskInventoryDictionary value) + //This is inparticular for updating properties + public void SetItems(TaskInventoryDictionary value) { m_items = value; - m_inventorySerial++; + //m_inventorySerial++; } /// From 29053b19d884f5e603aae9bf110b3c4e7aa8018c Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Tue, 8 Feb 2011 10:08:09 -0800 Subject: [PATCH 12/22] Added set functions for the last a few properties. For some property assignments in SOP, changed from "m_xxx=" to "Xxx=" to trigger UpdateBucketSyncInfo() as desired. --- .../Framework/Scenes/SceneObjectPart.cs | 118 +++++++++++++----- 1 file changed, 90 insertions(+), 28 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ccfded4752..d8fc82b281 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -831,14 +831,34 @@ namespace OpenSim.Region.Framework.Scenes public Byte[] TextureAnimation { get { return m_TextureAnimation; } - set { m_TextureAnimation = value; } + set + { + SetTextureAnimation(value); + UpdateBucketSyncInfo("TextureAnimation"); + //m_TextureAnimation = value; + } + } + //SYMMETRIC SYNC + public void SetTextureAnimation(Byte[] value) + { + m_TextureAnimation = value; } public Byte[] ParticleSystem { get { return m_particleSystem; } - set { m_particleSystem = value; } + set + { + SetParticleSystem(value); + UpdateBucketSyncInfo("ParticleSystem"); + //m_particleSystem = value; + } + } + //SYMMETRIC SYNC + public void SetParticleSystem(Byte[] value) + { + m_particleSystem = value; } @@ -1461,12 +1481,24 @@ namespace OpenSim.Region.Framework.Scenes set { + SetMediaUrl(value); + UpdateBucketSyncInfo("MediaUrl"); + /* m_mediaUrl = value; if (ParentGroup != null) ParentGroup.HasGroupChanged = true; + * */ } } + //SYMMETRIC SYNC + public void SetMediaUrl(string value) + { + m_mediaUrl = value; + + if (ParentGroup != null) + ParentGroup.HasGroupChanged = true; + } public bool CreateSelected @@ -1868,15 +1900,35 @@ namespace OpenSim.Region.Framework.Scenes get { return m_collisionSound; } set { - m_collisionSound = value; + SetCollisionSound(value); + UpdateBucketSyncInfo("CollisionSound"); + //m_collisionSound = value; aggregateScriptEvents(); } } + //SYMMETRIC SYNC + //CollisionSound is a special case. We won't call aggregateScriptEvents inside SetCollisionSound, + //so that when RegionSynModule triggers SOP.UpdateAllProperties, it calls SetCollisionSound + public void SetCollisionSound(UUID value) + { + m_collisionSound = value; + } + public float CollisionSoundVolume { get { return m_collisionSoundVolume; } - set { m_collisionSoundVolume = value; } + set + { + SetCollisionSoundVolume(value); + UpdateBucketSyncInfo("CollisionSoundVolume"); + //m_collisionSoundVolume = value; + } + } + //SYMMETRIC SYNC + public void SetCollisionSoundVolume(float value) + { + m_collisionSoundVolume = value; } #endregion Public Properties with only Get @@ -1986,12 +2038,16 @@ namespace OpenSim.Region.Framework.Scenes public void AddNewParticleSystem(Primitive.ParticleSystem pSystem) { - m_particleSystem = pSystem.GetBytes(); + //SYMMETRIC SYNC + //m_particleSystem = pSystem.GetBytes(); + ParticleSystem = pSystem.GetBytes(); } public void RemoveParticleSystem() { - m_particleSystem = new byte[0]; + //SYMMETRIC SYNC + //m_particleSystem = new byte[0]; + ParticleSystem = new byte[0]; } /// Terse updates @@ -2028,7 +2084,9 @@ namespace OpenSim.Region.Framework.Scenes Utils.FloatToBytes(pTexAnim.Length).CopyTo(data, pos + 4); Utils.FloatToBytes(pTexAnim.Rate).CopyTo(data, pos + 8); - m_TextureAnimation = data; + //m_TextureAnimation = data; + //SYMMETRIC SYNC + TextureAnimation = data; } public void AdjustSoundGain(double volume) @@ -3564,12 +3622,12 @@ namespace OpenSim.Region.Framework.Scenes // Tricks physics engine into thinking we've changed the part shape. PrimitiveBaseShape m_newshape = m_shape.Copy(); PhysActor.Shape = m_newshape; - m_shape = m_newshape; - - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); //SYMMETRIC SYNC - UpdateBucketSyncInfo("Shape"); + //m_shape = m_newshape; + Shape = m_newshape; + + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); } } } @@ -4850,32 +4908,36 @@ namespace OpenSim.Region.Framework.Scenes case 1: if (god) { - _baseMask = ApplyMask(_baseMask, set, mask); - Inventory.ApplyGodPermissions(_baseMask); //SYMMETRIC SYNC - UpdateBucketSyncInfo("BaseMask"); + //_baseMask = ApplyMask(_baseMask, set, mask); + BaseMask = ApplyMask(_baseMask, set, mask); + Inventory.ApplyGodPermissions(_baseMask); + } break; case 2: - _ownerMask = ApplyMask(_ownerMask, set, mask) & - baseMask; //SYMMETRIC SYNC - UpdateBucketSyncInfo("OwnerMask"); + //_ownerMask = ApplyMask(_ownerMask, set, mask) & + // baseMask; + OwnerMask = ApplyMask(_ownerMask, set, mask) & baseMask; break; case 4: - _groupMask = ApplyMask(_groupMask, set, mask) & - baseMask; //SYMMETRIC SYNC - UpdateBucketSyncInfo("GroupMask"); + //_groupMask = ApplyMask(_groupMask, set, mask) & + // baseMask; + GroupMask = ApplyMask(_groupMask, set, mask) & + baseMask; break; case 8: - _everyoneMask = ApplyMask(_everyoneMask, set, mask) & - baseMask; //SYMMETRIC SYNC - UpdateBucketSyncInfo("EveryoneMask"); + //_everyoneMask = ApplyMask(_everyoneMask, set, mask) & + // baseMask; + EveryoneMask = ApplyMask(_everyoneMask, set, mask) & + baseMask; break; case 16: + //SYMMETRIC SYNC _nextOwnerMask = ApplyMask(_nextOwnerMask, set, mask) & baseMask; // Prevent the client from creating no mod, no copy @@ -4883,10 +4945,9 @@ namespace OpenSim.Region.Framework.Scenes if ((_nextOwnerMask & (uint)PermissionMask.Copy) == 0) _nextOwnerMask |= (uint)PermissionMask.Transfer; - _nextOwnerMask |= (uint)PermissionMask.Move; - - //SYMMETRIC SYNC - UpdateBucketSyncInfo("NextOwnerMask"); + //_nextOwnerMask |= (uint)PermissionMask.Move; + NextOwnerMask = _nextOwnerMask | (uint)PermissionMask.Move; + break; } @@ -5801,7 +5862,8 @@ namespace OpenSim.Region.Framework.Scenes { if (this.CollisionSound != updatedCollisionSound) { - m_collisionSound = updatedCollisionSound; + //m_collisionSound = updatedCollisionSound; + SetCollisionSound(updatedCollisionSound); return true; } return false; From e8e9a0fb43be02315ab46373f054bd3f7ed6f57d Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Tue, 8 Feb 2011 15:33:54 -0800 Subject: [PATCH 13/22] Enabled all synchronized properties to be updated by calling through SetXXX() to set values. --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- .../Framework/Scenes/SceneObjectGroup.cs | 150 ++++++++++++++++-- .../Framework/Scenes/SceneObjectPart.cs | 100 +++++++++--- 4 files changed, 222 insertions(+), 32 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 9341c577e0..282491b153 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -795,7 +795,7 @@ namespace OpenSim.Region.Framework.Scenes //Set the property values as in the incoming copy of the object group SceneObjectGroup localGroup = root.ParentGroup; - localGroup.UpdateObjectProperties(linkedGroup); + localGroup.UpdateObjectGroupBySync(linkedGroup); //debug /* diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index d698e9eb42..d75cad2931 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -2299,7 +2299,7 @@ namespace OpenSim.Region.Framework.Scenes } else { - localAfterGroup.UpdateObjectProperties(incomingAfterDelinkGroupsDictionary[localAfterGroup.UUID]); + localAfterGroup.UpdateObjectGroupBySync(incomingAfterDelinkGroupsDictionary[localAfterGroup.UUID]); } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 236a17f1d6..74ac1f2171 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -294,6 +294,11 @@ namespace OpenSim.Region.Framework.Scenes get { return m_rootPart.GroupPosition; } set { + SetAbsolutePosition(value); + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].UpdateBucketSyncInfo("GroupPosition"); + /* Vector3 val = value; //REGION SYNC touched @@ -328,6 +333,39 @@ namespace OpenSim.Region.Framework.Scenes //m_rootPart.GroupPosition.Z); //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); //} + * */ + } + } + public void SetAbsolutePosition(Vector3 value) + { + Vector3 val = value; + + //REGION SYNC touched + + //if ((m_scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || m_scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) + // || m_scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || m_scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) + // && !IsAttachmentCheckFull()) + if (m_scene.IsBorderCrossing(LocX, LocY, val) && !IsAttachmentCheckFull() && (!m_scene.LoadingPrims)) + { + m_scene.CrossPrimGroupIntoNewRegion(val, this, true); + } + //end REGION SYNC touched + if (RootPart.GetStatusSandbox()) + { + if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) + { + RootPart.ScriptSetPhysicsStatus(false); + Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"), + ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false); + return; + } + } + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + { + //parts[i].GroupPosition = val; + parts[i].SetGroupPosition(val); } } @@ -465,6 +503,20 @@ namespace OpenSim.Region.Framework.Scenes #region Constructors + //SYMMETRIC SYNC + public SceneObjectGroup(SceneObjectPart part, bool newGroupBySync) + { + if (!newGroupBySync) + { + SetRootPart(part); + } + else + { + SetRootPartBySync(part); + } + + } + /// /// Constructor /// @@ -3728,7 +3780,8 @@ namespace OpenSim.Region.Framework.Scenes if (part.LinkNum > linkPart.LinkNum) { //part.LinkNum--; - part.SetLinkNum(part.LinkNum--); + int linkNum = part.LinkNum - 1; + part.SetLinkNum(linkNum); } } } @@ -3761,7 +3814,9 @@ namespace OpenSim.Region.Framework.Scenes linkPart.SetOffsetPosition(new Vector3(0, 0, 0)); linkPart.SetRotationOffset(worldRot); - SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart); + //SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart); + bool newGroupBySync = true; + SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart, newGroupBySync); m_scene.AddNewSceneObjectBySync(objectGroup, true); @@ -3777,7 +3832,23 @@ namespace OpenSim.Region.Framework.Scenes return objectGroup; } + /// + /// Set a part to act as the root part for this scene object, in which SetLinkNum() is called instead of "LinkNum=". + /// + /// + public void SetRootPartBySync(SceneObjectPart part) + { + if (part == null) + throw new ArgumentNullException("Cannot give SceneObjectGroup a null root SceneObjectPart"); + part.SetParent(this); + m_rootPart = part; + if (!IsAttachment) + part.ParentID = 0; + part.SetLinkNum(0); + + m_parts.Add(m_rootPart.UUID, m_rootPart); + } public void ScheduleGroupForFullUpdate_SyncInfoUnchanged() { @@ -3806,21 +3877,27 @@ namespace OpenSim.Region.Framework.Scenes Vector3 oldGroupPosition = linkPart.GroupPosition; Quaternion oldRootRotation = linkPart.RotationOffset; - linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition; - linkPart.GroupPosition = AbsolutePosition; + //linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition; + //linkPart.GroupPosition = AbsolutePosition; + linkPart.SetOffsetPosition(linkPart.GroupPosition - AbsolutePosition); + linkPart.SetGroupPosition(AbsolutePosition); Vector3 axPos = linkPart.OffsetPosition; Quaternion parentRot = m_rootPart.RotationOffset; axPos *= Quaternion.Inverse(parentRot); - linkPart.OffsetPosition = axPos; + //linkPart.OffsetPosition = axPos; + linkPart.SetOffsetPosition(axPos); Quaternion oldRot = linkPart.RotationOffset; Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot; - linkPart.RotationOffset = newRot; + //linkPart.RotationOffset = newRot; + linkPart.SetRotationOffset(newRot); + //ParentID is only valid locally, so remote value is ignored and no syncinfo will be modified linkPart.ParentID = m_rootPart.LocalId; if (m_rootPart.LinkNum == 0) - m_rootPart.LinkNum = 1; + //m_rootPart.LinkNum = 1; + m_rootPart.SetLinkNum(1); lock (m_parts.SyncRoot) { @@ -3836,11 +3913,13 @@ namespace OpenSim.Region.Framework.Scenes if (part.LinkNum != 1) { // Don't update root prim link number - part.LinkNum += objectGroup.PrimCount; + //part.LinkNum += objectGroup.PrimCount; + part.SetLinkNum(objectGroup.PrimCount); } } - linkPart.LinkNum = 2; + //linkPart.LinkNum = 2; + linkPart.SetLinkNum(2); linkPart.SetParent(this); linkPart.CreateSelected = true; @@ -3859,7 +3938,7 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectPart part = ogParts[i]; if (part.UUID != objectGroup.m_rootPart.UUID) - LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); + LinkNonRootPartBySync(part, oldGroupPosition, oldRootRotation, linkNum++); part.ClearUndoState(); } } @@ -3877,10 +3956,59 @@ namespace OpenSim.Region.Framework.Scenes // Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the // position of linkset prims. IF YOU CHANGE THIS, YOU MUST TEST colliding with just linked and // unmoved prims! - ResetChildPrimPhysicsPositions(); + //ResetChildPrimPhysicsPositions(); + //EntityBase sogBase = (EntityBase)this; + //sogBase.AbsolutePosition = AbsolutePosition; + SetAbsolutePosition(AbsolutePosition); } + private void LinkNonRootPartBySync(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation, int linkNum) + { + Quaternion parentRot = oldGroupRotation; + Quaternion oldRot = part.RotationOffset; + Quaternion worldRot = parentRot * oldRot; + + parentRot = oldGroupRotation; + + Vector3 axPos = part.OffsetPosition; + + axPos *= parentRot; + //part.OffsetPosition = axPos; + //part.GroupPosition = oldGroupPosition + part.OffsetPosition; + //part.OffsetPosition = Vector3.Zero; + //part.RotationOffset = worldRot; + part.SetOffsetPosition(axPos); + part.SetGroupPosition(oldGroupPosition + part.OffsetPosition); + part.SetOffsetPosition(Vector3.Zero); + part.SetRotationOffset(worldRot); + + part.SetParent(this); + part.ParentID = m_rootPart.LocalId; + + m_parts.Add(part.UUID, part); + + //part.LinkNum = linkNum; + part.SetLinkNum(linkNum); + + //part.OffsetPosition = part.GroupPosition - AbsolutePosition; + part.SetOffsetPosition(part.GroupPosition - AbsolutePosition); + + Quaternion rootRotation = m_rootPart.RotationOffset; + + Vector3 pos = part.OffsetPosition; + pos *= Quaternion.Inverse(rootRotation); + //part.OffsetPosition = pos; + part.SetOffsetPosition(pos); + + parentRot = m_rootPart.RotationOffset; + oldRot = part.RotationOffset; + Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot; + //part.RotationOffset = newRot; + part.SetRotationOffset(newRot); + } + + /* public void SyncInfoUpdate() { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index d8fc82b281..4edfdf93c7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -335,7 +335,24 @@ namespace OpenSim.Region.Framework.Scenes public bool IgnoreUndoUpdate = false; - public PrimFlags LocalFlags; + //SYMMETRIC SYNC + //public PrimFlags LocalFlags; + private PrimFlags m_localFlags; + public PrimFlags LocalFlags + { + get { return m_localFlags; } + set + { + SetLocalFlags(value); + UpdateBucketSyncInfo("LocalFlags"); + } + } + public void SetLocalFlags(PrimFlags value) + { + m_localFlags = value; + } + + private float m_damage = -1.0f; private byte[] m_TextureAnimation; private byte m_clickAction; @@ -675,7 +692,9 @@ namespace OpenSim.Region.Framework.Scenes { get { return m_name; } set - { + { + SetName(value); + UpdateBucketSyncInfo("Name"); /* m_name = value; if (PhysActor != null) @@ -1239,7 +1258,8 @@ namespace OpenSim.Region.Framework.Scenes set { SetAcceleration(value); - //UpdateBucketSyncInfo("Acceleration"); + + UpdateBucketSyncInfo("Acceleration"); //m_acceleration = value; } } @@ -1255,7 +1275,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetDescription(value); - //UpdateBucketSyncInfo("Description"); + UpdateBucketSyncInfo("Description"); /* m_description = value; PhysicsActor actor = PhysActor; @@ -1286,7 +1306,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetColor(value); - //UpdateBucketSyncInfo("Color"); + UpdateBucketSyncInfo("Color"); //m_color = value; /* ScheduleFullUpdate() need not be called b/c after @@ -1315,7 +1335,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetText(value, false); - //UpdateBucketSyncInfo("Text"); + UpdateBucketSyncInfo("Text"); //m_text = value; } } @@ -1333,7 +1353,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetSitName(value); - //UpdateBucketSyncInfo("SitName"); + UpdateBucketSyncInfo("SitName"); //m_sitName = value; } } @@ -1381,7 +1401,7 @@ namespace OpenSim.Region.Framework.Scenes set { SetClickAction(value); - //UpdateBucketSyncInfo("ClickAction"); + UpdateBucketSyncInfo("ClickAction"); //m_clickAction = value; } } @@ -1579,6 +1599,11 @@ namespace OpenSim.Region.Framework.Scenes //m_sitTargetPosition = value; } } + //SYMMETRIC SYNC + public void SetSitTargetPositionLL(Vector3 value) + { + m_sitTargetPosition = value; + } public Quaternion SitTargetOrientationLL { @@ -1599,6 +1624,11 @@ namespace OpenSim.Region.Framework.Scenes //m_sitTargetOrientation = new Quaternion(value.X, value.Y, value.Z, value.W); } } + //SYMMETRIC SYNC + public void SetSitTargetOrientationLL(Quaternion value) + { + m_sitTargetOrientation = value; + } public bool Stopped { @@ -5673,8 +5703,8 @@ namespace OpenSim.Region.Framework.Scenes "RotationOffset", "Velocity", "AngularVelocity", - //"Acceleration", - "SOP_Acceleration", //SOP and PA read/write their own local copies of acceleration, so we distinguish the copies + "Acceleration", //This is the property maintained in SOP. SOP and PA read/write their own local copies of acceleration, so we distinguish the copies + //"SOP_Acceleration", //SOP and PA read/write their own local copies of acceleration, so we distinguish the copies "Description", "Color", "Text", @@ -5997,21 +6027,53 @@ namespace OpenSim.Region.Framework.Scenes SetPassTouches(updatedPart.PassTouches); //RegionHandle skipped SetScriptAccessPin(updatedPart.ScriptAccessPin); - - //SetAcceleration(updatedPart.Acceleration); - //SetDescription(updatedPart.Description); - //SetColor(updatedPart.Color); - //SetText(updatedPart.Text); - //SetSitName(updatedPart.SitName); - + SetAcceleration(updatedPart.Acceleration); + SetDescription(updatedPart.Description); + SetColor(updatedPart.Color); + SetText(updatedPart.Text); + SetSitName(updatedPart.SitName); SetTouchName(updatedPart.TouchName); SetLinkNum(updatedPart.LinkNum); - //SetClickAction(updatedPart.ClickAction); - + SetClickAction(updatedPart.ClickAction); SetShape(updatedPart.Shape); + //UpdateFlag skipped: It's a flag meanful locally, especially in scheduling updates to viewers. + //Only in one place will it cause updating some "last" variables (see SendScheduledUpdates). + SetSitTargetOrientation(updatedPart.SitTargetOrientation); + SetSitTargetPosition(updatedPart.SitTargetPosition); + SetSitTargetPositionLL(updatedPart.SitTargetPositionLL); + SetSitTargetOrientationLL(updatedPart.SitTargetOrientationLL); + //ParentID skipped, the value is assigned locally and only meaningful locally (LinkObjects and LinkObjectsBySync will set it appropriately)\ + SetCreationDate(updatedPart.CreationDate); + SetCategory(updatedPart.Category); + SetSalePrice(updatedPart.SalePrice); + SetObjectSaleType(updatedPart.ObjectSaleType); + SetOwnershipCost(updatedPart.OwnershipCost); + SetGroupID(updatedPart.GroupID); + SetOwnerID(updatedPart.OwnerID); + SetLastOwnerID(updatedPart.LastOwnerID); + SetBaseMask(updatedPart.BaseMask); + SetOwnerMask(updatedPart.OwnerMask); + SetGroupMask(updatedPart.GroupMask); + SetEveryoneMask(updatedPart.EveryoneMask); + SetNextOwnerMask(updatedPart.NextOwnerMask); + SetFlags(updatedPart.Flags); + //Treat CollisionSound in a different way, so that if any property needs to be changed due to aggregateScriptEvents(), timestamp can be updated after + //the current copying-property-values-from-remote-sync-message is done. + bool collisionSoundUpdated = UpdateCollisionSound(updatedPart.CollisionSound); + SetCollisionSoundVolume(updatedPart.CollisionSoundVolume); + SetMediaUrl(updatedPart.MediaUrl); + SetTextureAnimation(updatedPart.TextureAnimation); + SetParticleSystem(updatedPart.ParticleSystem); + m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp; m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID; + + if (collisionSoundUpdated) + { + //If the local actor is Script Engine, it will catch this evnet and trigger aggregateScriptEvents() + m_parentGroup.Scene.EventManager.TriggerAggregateScriptEvents(this); + } } } From 2dc857b31d9e70b2652ecda2acadb11c917988d6 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Tue, 8 Feb 2011 15:55:00 -0800 Subject: [PATCH 14/22] Added code to serialization/deserialize LocalFlags. Need further testing to see if it's necessary. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 1 + .../Scenes/Serialization/SceneObjectSerializer.cs | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 4edfdf93c7..489b94a80a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -5734,6 +5734,7 @@ namespace OpenSim.Region.Framework.Scenes "EveryoneMask", "NextOwnerMask", "Flags", + "LocalFlags", "CollisionSound", "CollisionSoundVolume", "MediaUrl", diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 415be99c69..4189c1fc88 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -330,6 +330,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem); //SYMMETRIC SYNC + m_SOPXmlProcessors.Add("LocalFlags", ProcessLocalFlags); //m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp); //m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID); m_SOPXmlProcessors.Add("BucketSyncInfoList", ProcessBucketSyncInfo); @@ -713,7 +714,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization { obj.LastUpdateActorID = reader.ReadElementContentAsString("LastUpdateActorID", string.Empty); } - * */ + * */ + + private static void ProcessLocalFlags(SceneObjectPart obj, XmlTextReader reader) + { + obj.LocalFlags = Util.ReadEnum(reader, "LocalFlags"); + } public static void ProcessBucketSyncInfo(SceneObjectPart obj, XmlTextReader reader) { @@ -1236,8 +1242,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("EveryoneMask", sop.EveryoneMask.ToString()); writer.WriteElementString("NextOwnerMask", sop.NextOwnerMask.ToString()); //SYMMETRIC SYNC: also serialize SceneObjectPart:LocalFlags, so that it can be propogated across actors - //WriteFlags(writer, "Flags", sop.Flags.ToString(), options); - WriteFlags(writer, "Flags", sop.GetEffectiveObjectFlags().ToString(), options); + WriteFlags(writer, "Flags", sop.Flags.ToString(), options); + WriteFlags(writer, "LocalFlags", sop.LocalFlags.ToString(), options); + //writer.WriteElementString("Flags", sop.Flags.ToString()); + //writer.WriteElementString("LocalFlags", sop.Flags.ToString()); //end SYMMETRIC SYNC WriteUUID(writer, "CollisionSound", sop.CollisionSound, options); writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString()); From 3cd1ec8752782f86603bcb2f78dbdb2868376fbc Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Wed, 9 Feb 2011 17:17:16 -0800 Subject: [PATCH 15/22] Renamed SOP and SOPInventory as SOPBase and SOPInventoryBase, and define new SOP and SOPInventory. The latters will invoke UpdateBucketSyncInfo the set functions of their properties, while the base classes won't. --- .../SymmetricSync/RegionSyncModule.cs | 2 +- .../Framework/Interfaces/ISceneViewer.cs | 3 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 11 +- .../Framework/Scenes/SceneObjectGroup.cs | 152 ++- .../Framework/Scenes/SceneObjectPart.cs | 1073 +++-------------- .../Scenes/SceneObjectPartInventory.cs | 97 +- .../Region/Framework/Scenes/SceneViewer.cs | 5 +- .../Serialization/SceneObjectSerializer.cs | 28 +- .../Framework/Scenes/Types/UpdateQueue.cs | 2 +- 9 files changed, 334 insertions(+), 1039 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index 4e5c358f37..a593538ca6 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -211,7 +211,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule PupolatePropertyBuketMapByDefault(); //Pass the bucket information to SceneObjectPart. - SceneObjectPart.InitializeBucketInfo(m_primPropertyBucketMap, m_propertyBucketDescription, m_actorID); + SceneObjectPart.InitializePropertyBucketInfo(m_primPropertyBucketMap, m_propertyBucketDescription, m_actorID); } diff --git a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs index 7251d57f69..bf80a32a47 100644 --- a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs +++ b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs @@ -34,7 +34,8 @@ namespace OpenSim.Region.Framework.Interfaces { void Reset(); void Close(); - void QueuePartForUpdate(SceneObjectPart part); + //void QueuePartForUpdate(SceneObjectPart part); + void QueuePartForUpdate(SceneObjectPartBase part); void SendPrimUpdates(); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index d75cad2931..e58f5e881c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -2148,8 +2148,15 @@ namespace OpenSim.Region.Framework.Scenes //SYMMETRIC SYNC: need to copy value w/o trigger UpdateBucketSyncInfo //child.RootPart.ObjectSaleType = 0; //child.RootPart.SalePrice = 10; - child.RootPart.SetObjectSaleType(0); - child.RootPart.SetSalePrice(10); + //child.RootPart.SetObjectSaleType(0); + //child.RootPart.SetSalePrice(10); + //child.RootPart.SetProperty("ObjectSaleType", 0); + //child.RootPart.SetProperty("SalePrice", 10); + + //casting SOP to SOPBase to make sure we call SOPBase.Property set function, not the SOP.Property set function + SceneObjectPartBase rootPart = (SceneObjectPartBase)child.RootPart; + rootPart.ObjectSaleType = 0; + rootPart.SalePrice = 10; childGroups.Add(child); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 74ac1f2171..80a93e7540 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -294,11 +294,12 @@ namespace OpenSim.Region.Framework.Scenes get { return m_rootPart.GroupPosition; } set { + /* SetAbsolutePosition(value); SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) parts[i].UpdateBucketSyncInfo("GroupPosition"); - /* + */ Vector3 val = value; //REGION SYNC touched @@ -333,7 +334,7 @@ namespace OpenSim.Region.Framework.Scenes //m_rootPart.GroupPosition.Z); //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); //} - * */ + } } public void SetAbsolutePosition(Vector3 value) @@ -364,8 +365,8 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { - //parts[i].GroupPosition = val; - parts[i].SetGroupPosition(val); + parts[i].GroupPosition = val; + //parts[i].SetGroupPosition(val); } } @@ -3749,12 +3750,13 @@ namespace OpenSim.Region.Framework.Scenes //!!!!!!!!!!!!!!!!!!NOTE!!!!!!!!!!!!!!! //All SOP properties below is set through calling SetXXX(value) instead of by "XXX=value", as such a value is being changed due to sync ( //i.e. triggered by remote operation instead of by local operation - public SceneObjectGroup DelinkFromGroupBySync(SceneObjectPart linkPart, bool sendEvents) + public SceneObjectGroup DelinkFromGroupBySync(SceneObjectPart delinkPart, bool sendEvents) { -// m_log.DebugFormat( -// "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}", -// linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID); - + // m_log.DebugFormat( + // "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}", + // linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID); + + SceneObjectPartBase linkPart = (SceneObjectPartBase)delinkPart; linkPart.ClearUndoState(); Quaternion worldRot = linkPart.GetWorldRotation(); @@ -3770,27 +3772,27 @@ namespace OpenSim.Region.Framework.Scenes { // Single prim left //RootPart.LinkNum = 0; - RootPart.SetLinkNum(0); + //RootPart.SetProperty("LinkNum", 0); + ((SceneObjectPartBase)RootPart).LinkNum = 0; } else { for (int i = 0; i < parts.Length; i++) { - SceneObjectPart part = parts[i]; + SceneObjectPartBase part = (SceneObjectPartBase)parts[i]; if (part.LinkNum > linkPart.LinkNum) { - //part.LinkNum--; - int linkNum = part.LinkNum - 1; - part.SetLinkNum(linkNum); + part.LinkNum--; + //int linkNum = part.LinkNum - 1; + //part.SetProperty("LinkNum", linkNum); } } } } - //linkPart.ParentID = 0; - //linkPart.LinkNum = 0; - linkPart.SetParentID(0); - linkPart.SetLinkNum(0); + linkPart.ParentID = 0; //ParentID is a value set only locally and ignored in synchronization, so no need to call SetProperty to set its value + linkPart.LinkNum = 0; + //linkPart.SetParentID(0); if (linkPart.PhysActor != null) { @@ -3804,19 +3806,23 @@ namespace OpenSim.Region.Framework.Scenes Vector3 axPos = linkPart.OffsetPosition; axPos *= parentRot; - //linkPart.OffsetPosition = new Vector3(axPos.X, axPos.Y, axPos.Z); - //linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition; - //linkPart.OffsetPosition = new Vector3(0, 0, 0); - //linkPart.RotationOffset = worldRot; + linkPart.OffsetPosition = new Vector3(axPos.X, axPos.Y, axPos.Z); + linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition; + linkPart.OffsetPosition = new Vector3(0, 0, 0); + linkPart.RotationOffset = worldRot; - linkPart.SetOffsetPosition(new Vector3(axPos.X, axPos.Y, axPos.Z)); - linkPart.SetGroupPosition(AbsolutePosition + linkPart.OffsetPosition); - linkPart.SetOffsetPosition(new Vector3(0, 0, 0)); - linkPart.SetRotationOffset(worldRot); + //linkPart.SetOffsetPosition(new Vector3(axPos.X, axPos.Y, axPos.Z)); + //linkPart.SetGroupPosition(AbsolutePosition + linkPart.OffsetPosition); + //linkPart.SetOffsetPosition(new Vector3(0, 0, 0)); + //linkPart.SetRotationOffset(worldRot); + //linkPart.SetProperty("OffsetPosition", new Vector3(axPos.X, axPos.Y, axPos.Z)); + //linkPart.SetProperty("GroupPosition", AbsolutePosition + linkPart.OffsetPosition); + //linkPart.SetProperty("OffsetPosition", new Vector3(0, 0, 0)); + //linkPart.SetProperty("RotationOffset", worldRot); //SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart); bool newGroupBySync = true; - SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart, newGroupBySync); + SceneObjectGroup objectGroup = new SceneObjectGroup(delinkPart, newGroupBySync); m_scene.AddNewSceneObjectBySync(objectGroup, true); @@ -3833,7 +3839,7 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Set a part to act as the root part for this scene object, in which SetLinkNum() is called instead of "LinkNum=". + /// Set a part to act as the root part for this scene object, in which SetProperty("LinkNum",) is called instead of "LinkNum=". /// /// public void SetRootPartBySync(SceneObjectPart part) @@ -3845,7 +3851,7 @@ namespace OpenSim.Region.Framework.Scenes m_rootPart = part; if (!IsAttachment) part.ParentID = 0; - part.SetLinkNum(0); + part.SetProperty("LinkNum", 0); m_parts.Add(m_rootPart.UUID, m_rootPart); } @@ -3872,36 +3878,40 @@ namespace OpenSim.Region.Framework.Scenes public void LinkToGroupBySync(SceneObjectGroup objectGroup) { - SceneObjectPart linkPart = objectGroup.m_rootPart; - + SceneObjectPartBase linkPart = (SceneObjectPartBase)objectGroup.m_rootPart; + Vector3 oldGroupPosition = linkPart.GroupPosition; Quaternion oldRootRotation = linkPart.RotationOffset; - //linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition; - //linkPart.GroupPosition = AbsolutePosition; - linkPart.SetOffsetPosition(linkPart.GroupPosition - AbsolutePosition); - linkPart.SetGroupPosition(AbsolutePosition); + linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition; + linkPart.GroupPosition = AbsolutePosition; + //linkPart.SetOffsetPosition(linkPart.GroupPosition - AbsolutePosition); + //linkPart.SetGroupPosition(AbsolutePosition); + //linkPart.SetProperty("OffsetPosition", linkPart.GroupPosition - AbsolutePosition); + //linkPart.SetProperty("GroupPosition", AbsolutePosition); Vector3 axPos = linkPart.OffsetPosition; Quaternion parentRot = m_rootPart.RotationOffset; axPos *= Quaternion.Inverse(parentRot); - //linkPart.OffsetPosition = axPos; - linkPart.SetOffsetPosition(axPos); + linkPart.OffsetPosition = axPos; + //linkPart.SetOffsetPosition(axPos); + //linkPart.SetProperty("OffsetPosition", axPos); Quaternion oldRot = linkPart.RotationOffset; Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot; - //linkPart.RotationOffset = newRot; - linkPart.SetRotationOffset(newRot); + linkPart.RotationOffset = newRot; + //linkPart.SetRotationOffset(newRot); + //linkPart.SetProperty("RotationOffset", newRot); //ParentID is only valid locally, so remote value is ignored and no syncinfo will be modified linkPart.ParentID = m_rootPart.LocalId; if (m_rootPart.LinkNum == 0) - //m_rootPart.LinkNum = 1; - m_rootPart.SetLinkNum(1); + ((SceneObjectPartBase)m_rootPart).LinkNum = 1; + //m_rootPart.SetProperty("LinkNum",1); lock (m_parts.SyncRoot) { - m_parts.Add(linkPart.UUID, linkPart); + m_parts.Add(linkPart.UUID, (SceneObjectPart) linkPart); // Insert in terms of link numbers, the new links // before the current ones (with the exception of @@ -3909,17 +3919,17 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { - SceneObjectPart part = parts[i]; + SceneObjectPartBase part = (SceneObjectPartBase)parts[i]; if (part.LinkNum != 1) { // Don't update root prim link number - //part.LinkNum += objectGroup.PrimCount; - part.SetLinkNum(objectGroup.PrimCount); + part.LinkNum += objectGroup.PrimCount; + //part.SetProperty("LinkNum",objectGroup.PrimCount); } } - //linkPart.LinkNum = 2; - linkPart.SetLinkNum(2); + linkPart.LinkNum = 2; + //linkPart.SetProperty("LinkNum",2); linkPart.SetParent(this); linkPart.CreateSelected = true; @@ -3963,49 +3973,57 @@ namespace OpenSim.Region.Framework.Scenes } - private void LinkNonRootPartBySync(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation, int linkNum) + private void LinkNonRootPartBySync(SceneObjectPart linkPart, Vector3 oldGroupPosition, Quaternion oldGroupRotation, int linkNum) { Quaternion parentRot = oldGroupRotation; - Quaternion oldRot = part.RotationOffset; + Quaternion oldRot = linkPart.RotationOffset; Quaternion worldRot = parentRot * oldRot; parentRot = oldGroupRotation; - Vector3 axPos = part.OffsetPosition; + Vector3 axPos = linkPart.OffsetPosition; + SceneObjectPartBase part = (SceneObjectPartBase)linkPart; axPos *= parentRot; - //part.OffsetPosition = axPos; - //part.GroupPosition = oldGroupPosition + part.OffsetPosition; - //part.OffsetPosition = Vector3.Zero; - //part.RotationOffset = worldRot; - part.SetOffsetPosition(axPos); - part.SetGroupPosition(oldGroupPosition + part.OffsetPosition); - part.SetOffsetPosition(Vector3.Zero); - part.SetRotationOffset(worldRot); + part.OffsetPosition = axPos; + part.GroupPosition = oldGroupPosition + part.OffsetPosition; + part.OffsetPosition = Vector3.Zero; + part.RotationOffset = worldRot; + //part.SetOffsetPosition(axPos); + //part.SetGroupPosition(oldGroupPosition + part.OffsetPosition); + //part.SetOffsetPosition(Vector3.Zero); + //part.SetRotationOffset(worldRot); + //part.SetProperty("OffsetPosition", axPos); + //part.SetProperty("GroupPosition", oldGroupPosition + part.OffsetPosition); + //part.SetProperty("OffsetPosition", Vector3.Zero); + //part.SetProperty("RotationOffset", worldRot); part.SetParent(this); part.ParentID = m_rootPart.LocalId; - m_parts.Add(part.UUID, part); + m_parts.Add(part.UUID, linkPart); - //part.LinkNum = linkNum; - part.SetLinkNum(linkNum); + part.LinkNum = linkNum; + //part.SetProperty("LinkNum",linkNum); - //part.OffsetPosition = part.GroupPosition - AbsolutePosition; - part.SetOffsetPosition(part.GroupPosition - AbsolutePosition); + part.OffsetPosition = part.GroupPosition - AbsolutePosition; + //part.SetOffsetPosition(part.GroupPosition - AbsolutePosition); + //part.SetProperty("OffsetPosition", part.GroupPosition - AbsolutePosition); Quaternion rootRotation = m_rootPart.RotationOffset; Vector3 pos = part.OffsetPosition; pos *= Quaternion.Inverse(rootRotation); - //part.OffsetPosition = pos; - part.SetOffsetPosition(pos); + part.OffsetPosition = pos; + //part.SetOffsetPosition(pos); + //part.SetProperty("OffsetPosition", pos); parentRot = m_rootPart.RotationOffset; oldRot = part.RotationOffset; Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot; - //part.RotationOffset = newRot; - part.SetRotationOffset(newRot); + part.RotationOffset = newRot; + //part.SetRotationOffset(newRot); + //part.SetProperty("RotationOffset", newRot); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 489b94a80a..d2929fe0a8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -107,66 +107,15 @@ namespace OpenSim.Region.Framework.Scenes #endregion Enumerations - //SYMMETRIC SYNC - - //Information for concurrency control of one bucket of prim proproperties. - public class BucketSyncInfo - { - private long m_lastUpdateTimeStamp; - private string m_lastUpdateActorID; - //lock for concurrent updates of the timestamp and actorID. - private Object m_updateLock = new Object(); - private string m_bucketName; - - public long LastUpdateTimeStamp - { - get { return m_lastUpdateTimeStamp; } - set { m_lastUpdateTimeStamp = value; } - } - - public string LastUpdateActorID - { - get { return m_lastUpdateActorID; } - set { m_lastUpdateActorID = value; } - } - - public string BucketName - { - get { return m_bucketName; } - } - - public BucketSyncInfo(string bucketName) - { - m_bucketName = bucketName; - } - - public BucketSyncInfo(long timeStamp, string actorID, string bucketName) - { - m_lastUpdateTimeStamp = timeStamp; - m_lastUpdateActorID = actorID; - m_bucketName = bucketName; - } - - public void UpdateSyncInfo(long timeStamp, string actorID) - { - lock (m_updateLock) - { - m_lastUpdateTimeStamp = timeStamp; - m_lastUpdateActorID = actorID; - } - } - - } - //end of SYMMETRIC SYNC - - public class SceneObjectPart : IScriptHost, ISceneEntity + //public class SceneObjectPart : IScriptHost, ISceneEntity + public abstract class SceneObjectPartBase : IScriptHost, ISceneEntity { /// /// Denote all sides of the prim /// public const int ALL_SIDES = -1; - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// /// Is this sop a root part? @@ -187,15 +136,9 @@ namespace OpenSim.Region.Framework.Scenes get { return m_allowedDrop; } set { - //m_allowedDrop = value; - SetAllowedDrop(value); - UpdateBucketSyncInfo("AllowedDrop"); + m_allowedDrop = value; } } - public void SetAllowedDrop(bool value) - { - m_allowedDrop = value; - } public bool DIE_AT_EDGE; @@ -327,7 +270,8 @@ namespace OpenSim.Region.Framework.Scenes { get { return m_inventory; } } - protected SceneObjectPartInventory m_inventory; + //protected SceneObjectPartInventory m_inventory; + protected SceneObjectPartInventoryBase m_inventory; public bool Undoing; @@ -335,24 +279,7 @@ namespace OpenSim.Region.Framework.Scenes public bool IgnoreUndoUpdate = false; - //SYMMETRIC SYNC - //public PrimFlags LocalFlags; - private PrimFlags m_localFlags; - public PrimFlags LocalFlags - { - get { return m_localFlags; } - set - { - SetLocalFlags(value); - UpdateBucketSyncInfo("LocalFlags"); - } - } - public void SetLocalFlags(PrimFlags value) - { - m_localFlags = value; - } - - + public PrimFlags LocalFlags; private float m_damage = -1.0f; private byte[] m_TextureAnimation; private byte m_clickAction; @@ -435,14 +362,16 @@ namespace OpenSim.Region.Framework.Scenes /// /// No arg constructor called by region restore db code /// - public SceneObjectPart() + //public SceneObjectPart() + public SceneObjectPartBase() { // It's not necessary to persist this m_TextureAnimation = Utils.EmptyBytes; m_particleSystem = Utils.EmptyBytes; Rezzed = DateTime.UtcNow; - m_inventory = new SceneObjectPartInventory(this); + //m_inventory = new SceneObjectPartInventory(this); + m_inventory = new SceneObjectPartInventoryBase(this); } /// @@ -453,7 +382,8 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - public SceneObjectPart( + //public SceneObjectPart( + public SceneObjectPartBase( UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, Quaternion rotationOffset, Vector3 offsetPosition) { @@ -492,7 +422,8 @@ namespace OpenSim.Region.Framework.Scenes TrimPermissions(); //m_undo = new UndoStack(ParentGroup.GetSceneMaxUndo()); - m_inventory = new SceneObjectPartInventory(this); + //m_inventory = new SceneObjectPartInventory(this); + m_inventory = new SceneObjectPartInventoryBase(this); } #endregion Constructors @@ -528,16 +459,9 @@ namespace OpenSim.Region.Framework.Scenes } set { - SetCreatorID(value); - UpdateBucketSyncInfo("CreatorID"); - //_creatorID = value; + _creatorID = value; } } - //SYMMETRIC SYNC - public void SetCreatorID(UUID value) - { - _creatorID = value; - } /// /// Data about the creator in the form profile_url;name @@ -545,17 +469,7 @@ namespace OpenSim.Region.Framework.Scenes public string CreatorData { get { return m_creatorData; } - set - { - SetCreatorData(value); - UpdateBucketSyncInfo("CreatorData"); - //m_creatorData = value; - } - } - //SYMMETRIC SYNC - public void SetCreatorData(string value) - { - m_creatorData = value; + set { m_creatorData = value; } } /// @@ -625,18 +539,7 @@ namespace OpenSim.Region.Framework.Scenes public uint InventorySerial { get { return m_inventory.Serial; } - set - { - SetInventorySerial(value); - UpdateBucketSyncInfo("InventorySerial"); - //m_inventory.Serial = value; - } - } - //SYMMETRIC SYNC: implemented to be consistent with other properties. "m_inventory.Serial" set function will trigger UpdateBucketSyncInfo, - //hence in SetInventorySerial we will call m_inventory.SetSerial to avoid triggering UpdateBucketSyncInfo(). - public void SetInventorySerial(uint value) - { - m_inventory.SetSerial(value); + set { m_inventory.Serial = value; } } /// @@ -645,18 +548,7 @@ namespace OpenSim.Region.Framework.Scenes public TaskInventoryDictionary TaskInventory { get { return m_inventory.Items; } - set - { - //SetTaskInventory(value); - //UpdateBucketSyncInfo("TaskInventory"); - //SYMMETRIC SYNC: "m_inventory.Items" set function will trigger UpdateBucketSyncInfo if appropriate - m_inventory.Items = value; - } - } - //SYMMETRIC SYNC: implemented to be consistent with updating values of other properties (w/o triggering UpdateBucketSyncInfo); - public void SetTaskInventory(TaskInventoryDictionary value) - { - m_inventory.SetItems(value); + set { m_inventory.Items = value; } } /// @@ -692,25 +584,12 @@ namespace OpenSim.Region.Framework.Scenes { get { return m_name; } set - { - SetName(value); - UpdateBucketSyncInfo("Name"); - /* + { m_name = value; if (PhysActor != null) { PhysActor.SOPName = value; } - * */ - } - } - //SYMMETRIC SYNC - public void SetName(string value) - { - m_name = value; - if (PhysActor != null) - { - PhysActor.SOPName = value; } } @@ -719,49 +598,24 @@ namespace OpenSim.Region.Framework.Scenes get { return (byte) m_material; } set { - SetMaterial(value); - UpdateBucketSyncInfo("Material"); - /* m_material = (Material)value; if (PhysActor != null) { PhysActor.SetMaterial((int)value); } - * */ } } - //SYMMETRIC SYNC - public void SetMaterial(byte value) - { - m_material = (Material)value; - if (PhysActor != null) - { - PhysActor.SetMaterial((int)value); - } - } - public bool PassTouches { get { return m_passTouches; } set { - SetPassTouches(value); - UpdateBucketSyncInfo("PassTouches"); - /* m_passTouches = value; if (ParentGroup != null) ParentGroup.HasGroupChanged = true; - * */ } } - //SYMMETRIC SYNC - public void SetPassTouches(bool value) - { - m_passTouches = value; - if (ParentGroup != null) - ParentGroup.HasGroupChanged = true; - } @@ -804,20 +658,8 @@ namespace OpenSim.Region.Framework.Scenes public int ScriptAccessPin { get { return m_scriptAccessPin; } - set - { - SetScriptAccessPin(value); - UpdateBucketSyncInfo("ScriptAccessPin"); - //m_scriptAccessPin = (int)value; - } + set { m_scriptAccessPin = (int)value; } } - //SYMMETRIC SYNC - public void SetScriptAccessPin(int value) - { - m_scriptAccessPin = (int)value; - } - - private SceneObjectPart m_PlaySoundMasterPrim = null; public SceneObjectPart PlaySoundMasterPrim { @@ -850,34 +692,14 @@ namespace OpenSim.Region.Framework.Scenes public Byte[] TextureAnimation { get { return m_TextureAnimation; } - set - { - SetTextureAnimation(value); - UpdateBucketSyncInfo("TextureAnimation"); - //m_TextureAnimation = value; - } - } - //SYMMETRIC SYNC - public void SetTextureAnimation(Byte[] value) - { - m_TextureAnimation = value; + set { m_TextureAnimation = value; } } public Byte[] ParticleSystem { get { return m_particleSystem; } - set - { - SetParticleSystem(value); - UpdateBucketSyncInfo("ParticleSystem"); - //m_particleSystem = value; - } - } - //SYMMETRIC SYNC - public void SetParticleSystem(Byte[] value) - { - m_particleSystem = value; + set { m_particleSystem = value; } } @@ -926,11 +748,6 @@ namespace OpenSim.Region.Framework.Scenes } set { - SetGroupPosition(value); - UpdateBucketSyncInfo("GroupPosition"); - - /* - //Legacy Opensim code m_groupPosition = value; PhysicsActor actor = PhysActor; @@ -971,63 +788,14 @@ 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 { get { return m_offsetPosition; } set { - SetOffsetPosition(value); - UpdateBucketSyncInfo("OffsetPosition"); - /* StoreUndoState(); m_offsetPosition = value; @@ -1043,26 +811,6 @@ namespace OpenSim.Region.Framework.Scenes m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); } } - * */ - } - } - //SYMMETRIC SYNC - public void SetOffsetPosition(Vector3 value) - { - StoreUndoState(); - m_offsetPosition = value; - - if (ParentGroup != null && !ParentGroup.IsDeleted) - { - PhysicsActor actor = PhysActor; - if (_parentID != 0 && actor != null) - { - actor.Position = GetWorldPosition(); - actor.Orientation = GetWorldRotation(); - - // Tell the physics engines that this prim changed. - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); - } } } @@ -1104,9 +852,6 @@ namespace OpenSim.Region.Framework.Scenes set { - SetRotationOffset(value); - UpdateBucketSyncInfo("RotationOffset"); - /* StoreUndoState(); m_rotationOffset = value; @@ -1136,43 +881,9 @@ namespace OpenSim.Region.Framework.Scenes m_log.Error("[SCENEOBJECTPART]: ROTATIONOFFSET" + ex.Message); } } - * */ } } - //SYMMETRIC SYNC - public void SetRotationOffset(Quaternion value) - { - StoreUndoState(); - m_rotationOffset = value; - - PhysicsActor actor = PhysActor; - if (actor != null) - { - try - { - // Root prim gets value directly - if (_parentID == 0) - { - actor.Orientation = value; - //m_log.Info("[PART]: RO1:" + actor.Orientation.ToString()); - } - else - { - // Child prim we have to calculate it's world rotationwel - Quaternion resultingrotation = GetWorldRotation(); - actor.Orientation = resultingrotation; - //m_log.Info("[PART]: RO2:" + actor.Orientation.ToString()); - } - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); - //} - } - catch (Exception ex) - { - m_log.Error("[SCENEOBJECTPART]: ROTATIONOFFSET" + ex.Message); - } - } - } /// public Vector3 Velocity @@ -1193,9 +904,6 @@ namespace OpenSim.Region.Framework.Scenes set { - SetVelocity(value); - UpdateBucketSyncInfo("Velocity"); - /* m_velocity = value; PhysicsActor actor = PhysActor; @@ -1207,22 +915,6 @@ namespace OpenSim.Region.Framework.Scenes m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); } } - * */ - } - } - //SYMMETRIC SYNC - public void SetVelocity(Vector3 value) - { - m_velocity = value; - - PhysicsActor actor = PhysActor; - if (actor != null) - { - if (actor.IsPhysical) - { - actor.Velocity = value; - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); - } } } @@ -1238,35 +930,14 @@ namespace OpenSim.Region.Framework.Scenes } return m_angularVelocity; } - set - { - SetAngularVelocity(value); - UpdateBucketSyncInfo("AngularVelocity"); - //m_angularVelocity = value; - } - } - //SYMMETRIC SYNC - public void SetAngularVelocity(Vector3 value) - { - m_angularVelocity = value; + set { m_angularVelocity = value; } } /// public Vector3 Acceleration { get { return m_acceleration; } - set - { - SetAcceleration(value); - - UpdateBucketSyncInfo("Acceleration"); - //m_acceleration = value; - } - } - //SYMMETRIC SYNC - public void SetAcceleration(Vector3 value) - { - m_acceleration = value; + set { m_acceleration = value; } } public string Description @@ -1274,26 +945,12 @@ namespace OpenSim.Region.Framework.Scenes get { return m_description; } set { - SetDescription(value); - UpdateBucketSyncInfo("Description"); - /* m_description = value; PhysicsActor actor = PhysActor; if (actor != null) { actor.SOPDescription = value; } - * */ - } - } - //SYMMETRIC SYNC - public void SetDescription(string value) - { - m_description = value; - PhysicsActor actor = PhysActor; - if (actor != null) - { - actor.SOPDescription = value; } } @@ -1305,9 +962,7 @@ namespace OpenSim.Region.Framework.Scenes get { return m_color; } set { - SetColor(value); - UpdateBucketSyncInfo("Color"); - //m_color = value; + m_color = value; /* ScheduleFullUpdate() need not be called b/c after * setting the color, the text will be set, so then @@ -1315,11 +970,6 @@ namespace OpenSim.Region.Framework.Scenes //ScheduleFullUpdate(); } } - //SYMMETRIC SYNC - public void SetColor(Color value) - { - m_color = value; - } public string Text { @@ -1334,65 +984,27 @@ namespace OpenSim.Region.Framework.Scenes } set { - SetText(value, false); - UpdateBucketSyncInfo("Text"); - //m_text = value; + m_text = value; } } - //SYMMETRIC SYNC - //SetText(string) has been defined, defined it as a different interface, the 2nd argument is not really useful - public void SetText(string value, bool bySync) - { - m_text = value; - } public string SitName { get { return m_sitName; } - set - { - SetSitName(value); - UpdateBucketSyncInfo("SitName"); - //m_sitName = value; - } - } - //SYMMETRIC SYNC - public void SetSitName(string value) - { - m_sitName = value; + set { m_sitName = value; } } public string TouchName { get { return m_touchName; } - set - { - SetTouchName(value); - UpdateBucketSyncInfo("TouchName"); - //m_touchName = value; - } - } - //SYMMETRIC SYNC - public void SetTouchName(string value) - { - m_touchName = value; + set { m_touchName = value; } } public int LinkNum { get { return m_linkNum; } - set - { - SetLinkNum(value); - UpdateBucketSyncInfo("LinkNum"); - //m_linkNum = value; - } - } - //SYMMETRIC SYNC - public void SetLinkNum(int value) - { - m_linkNum = value; + set { m_linkNum = value; } } public byte ClickAction @@ -1400,31 +1012,14 @@ namespace OpenSim.Region.Framework.Scenes get { return m_clickAction; } set { - SetClickAction(value); - UpdateBucketSyncInfo("ClickAction"); - //m_clickAction = value; + m_clickAction = value; } } - //SYMMETRIC SYNC - public void SetClickAction(byte value) - { - m_clickAction = value; - } public PrimitiveBaseShape Shape { get { return m_shape; } - set - { - SetShape(value); - UpdateBucketSyncInfo("Shape"); - //m_shape = value; - } - } - //SYMMETRIC SYNC - public void SetShape(PrimitiveBaseShape value) - { - m_shape = value; + set { m_shape = value; } } public Vector3 Scale @@ -1432,9 +1027,6 @@ namespace OpenSim.Region.Framework.Scenes get { return m_shape.Scale; } set { - SetScale(value); - UpdateBucketSyncInfo("Scale"); - /* StoreUndoState(); if (m_shape != null) { @@ -1454,33 +1046,8 @@ namespace OpenSim.Region.Framework.Scenes } } TriggerScriptChangedEvent(Changed.SCALE); - * */ } } - //SYMMETRIC SYNC - public void SetScale(Vector3 value) - { - StoreUndoState(); - if (m_shape != null) - { - m_shape.Scale = value; - - PhysicsActor actor = PhysActor; - if (actor != null && m_parentGroup != null) - { - if (m_parentGroup.Scene != null) - { - if (m_parentGroup.Scene.PhysicsScene != null) - { - actor.Size = m_shape.Scale; - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); - } - } - } - } - TriggerScriptChangedEvent(Changed.SCALE); - } - public byte UpdateFlag { @@ -1501,24 +1068,12 @@ namespace OpenSim.Region.Framework.Scenes set { - SetMediaUrl(value); - UpdateBucketSyncInfo("MediaUrl"); - /* m_mediaUrl = value; if (ParentGroup != null) ParentGroup.HasGroupChanged = true; - * */ } } - //SYMMETRIC SYNC - public void SetMediaUrl(string value) - { - m_mediaUrl = value; - - if (ParentGroup != null) - ParentGroup.HasGroupChanged = true; - } public bool CreateSelected @@ -1558,33 +1113,14 @@ namespace OpenSim.Region.Framework.Scenes public Quaternion SitTargetOrientation { get { return m_sitTargetOrientation; } - set - { - SetSitTargetOrientation(value); - UpdateBucketSyncInfo("SitTargetOrientation"); - //m_sitTargetOrientation = value; - } - } - //SYMMETRIC SYNC - public void SetSitTargetOrientation(Quaternion value) - { - m_sitTargetOrientation = value; + set { m_sitTargetOrientation = value; } } + public Vector3 SitTargetPosition { get { return m_sitTargetPosition; } - set - { - SetSitTargetPosition(value); - UpdateBucketSyncInfo("SitTargetPosition"); - //m_sitTargetPosition = value; - } - } - //SYMMETRIC SYNC - public void SetSitTargetPosition(Vector3 value) - { - m_sitTargetPosition = value; + set { m_sitTargetPosition = value; } } // This sort of sucks, but I'm adding these in to make some of @@ -1592,17 +1128,7 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 SitTargetPositionLL { get { return new Vector3(m_sitTargetPosition.X, m_sitTargetPosition.Y,m_sitTargetPosition.Z); } - set - { - SetSitTargetPosition(value); - UpdateBucketSyncInfo("SitTargetPositionLL"); - //m_sitTargetPosition = value; - } - } - //SYMMETRIC SYNC - public void SetSitTargetPositionLL(Vector3 value) - { - m_sitTargetPosition = value; + set { m_sitTargetPosition = value; } } public Quaternion SitTargetOrientationLL @@ -1617,17 +1143,7 @@ namespace OpenSim.Region.Framework.Scenes ); } - set - { - SetSitTargetOrientation(new Quaternion(value.X, value.Y, value.Z, value.W)); - UpdateBucketSyncInfo("SitTargetOrientationLL"); - //m_sitTargetOrientation = new Quaternion(value.X, value.Y, value.Z, value.W); - } - } - //SYMMETRIC SYNC - public void SetSitTargetOrientationLL(Quaternion value) - { - m_sitTargetOrientation = value; + set { m_sitTargetOrientation = new Quaternion(value.X, value.Y, value.Z, value.W); } } public bool Stopped @@ -1648,218 +1164,83 @@ namespace OpenSim.Region.Framework.Scenes get { return _parentID; } set { _parentID = value; } } - //SYMMETRIC SYNC: defined for consistency, for calling SetXXX in sync operations - public void SetParentID(uint value) - { - _parentID = value; - } public int CreationDate { get { return _creationDate; } - set - { - SetCreationDate(value); - UpdateBucketSyncInfo("CreationDate"); - //_creationDate = value; - } - } - //SYMMETRIC SYNC - public void SetCreationDate(int value) - { - _creationDate = value; + set { _creationDate = value; } } public uint Category { get { return _category; } - set - { - SetCategory(value); - UpdateBucketSyncInfo("Category"); - //_category = value; - } - } - //SYMMETRIC SYNC - public void SetCategory(uint value) - { - _category = value; + set { _category = value; } } public int SalePrice { get { return _salePrice; } - set - { - SetSalePrice(value); - UpdateBucketSyncInfo("SalePrice"); - //_salePrice = value; - } - } - //SYMMETRIC SYNC - public void SetSalePrice(int value) - { - _salePrice = value; + set { _salePrice = value; } } public byte ObjectSaleType { get { return _objectSaleType; } - set - { - SetObjectSaleType(value); - UpdateBucketSyncInfo("ObjectSaleType"); - //_objectSaleType = value; - } - } - //SYMMETRIC SYNC - public void SetObjectSaleType(byte value) - { - _objectSaleType = value; + set { _objectSaleType = value; } } public int OwnershipCost { get { return _ownershipCost; } - set - { - SetOwnershipCost(value); - UpdateBucketSyncInfo("OwnershipCost"); - // _ownershipCost = value; - } - } - //SYMMETRIC SYNC - public void SetOwnershipCost(int value) - { - _ownershipCost = value; + set { _ownershipCost = value; } } public UUID GroupID { get { return _groupID; } - set - { - SetGroupID(value); - UpdateBucketSyncInfo("GroupID"); - //_groupID = value; - } - } - //SYMMETRIC SYNC - public void SetGroupID(UUID value) - { - _groupID = value; + set { _groupID = value; } } public UUID OwnerID { get { return _ownerID; } - set - { - SetOwnerID(value); - UpdateBucketSyncInfo("OwnerID"); - // _ownerID = value; - } - } - //SYMMETRIC SYNC - public void SetOwnerID(UUID value) - { - _ownerID = value; + set { _ownerID = value; } } public UUID LastOwnerID { get { return _lastOwnerID; } - set - { - SetLastOwnerID(value); - UpdateBucketSyncInfo("LastOwnerID"); - //_lastOwnerID = value; - } - } - //SYMMETRIC SYNC - public void SetLastOwnerID(UUID value) - { - _lastOwnerID = value; + set { _lastOwnerID = value; } } public uint BaseMask { get { return _baseMask; } - set - { - SetBaseMask(value); - UpdateBucketSyncInfo("BaseMask"); - //_baseMask = value; - } - } - //SYMMETRIC SYNC - public void SetBaseMask(uint value) - { - _baseMask = value; + set { _baseMask = value; } } public uint OwnerMask { get { return _ownerMask; } - set - { - SetOwnerMask(value); - UpdateBucketSyncInfo("OwnerMask"); - //_ownerMask = value; - } - } - //SYMMETRIC SYNC - public void SetOwnerMask(uint value) - { - _ownerMask = value; + set { _ownerMask = value; } } public uint GroupMask { get { return _groupMask; } - set - { - SetGroupMask(value); - UpdateBucketSyncInfo("GroupMask"); - //_groupMask = value; - } - } - //SYMMETRIC SYNC - public void SetGroupMask(uint value) - { - _groupMask = value; + set { _groupMask = value; } } public uint EveryoneMask { get { return _everyoneMask; } - set - { - SetEveryoneMask(value); - UpdateBucketSyncInfo("EveryoneMask"); - //_everyoneMask = value; - } - } - //SYMMETRIC SYNC - public void SetEveryoneMask(uint value) - { - _everyoneMask = value; + set { _everyoneMask = value; } } public uint NextOwnerMask { get { return _nextOwnerMask; } - set - { - SetNextOwnerMask(value); - UpdateBucketSyncInfo("NextOwnerMask"); - //_nextOwnerMask = value; - } - } - //SYMMETRIC SYNC - public void SetNextOwnerMask(uint value) - { - _nextOwnerMask = value; + set { _nextOwnerMask = value; } } /// @@ -1870,18 +1251,11 @@ namespace OpenSim.Region.Framework.Scenes { get { return _flags; } set - { - SetFlags(value); - UpdateBucketSyncInfo("Flags"); + { // m_log.DebugFormat("[SOP]: Setting flags for {0} {1} to {2}", UUID, Name, value); - //_flags = value; + _flags = value; } } - //SYMMETRIC SYNC - public void SetFlags(PrimFlags value) - { - _flags = value; - } public UUID SitTargetAvatar @@ -1930,35 +1304,15 @@ namespace OpenSim.Region.Framework.Scenes get { return m_collisionSound; } set { - SetCollisionSound(value); - UpdateBucketSyncInfo("CollisionSound"); - //m_collisionSound = value; + m_collisionSound = value; aggregateScriptEvents(); } } - //SYMMETRIC SYNC - //CollisionSound is a special case. We won't call aggregateScriptEvents inside SetCollisionSound, - //so that when RegionSynModule triggers SOP.UpdateAllProperties, it calls SetCollisionSound - public void SetCollisionSound(UUID value) - { - m_collisionSound = value; - } - public float CollisionSoundVolume { get { return m_collisionSoundVolume; } - set - { - SetCollisionSoundVolume(value); - UpdateBucketSyncInfo("CollisionSoundVolume"); - //m_collisionSoundVolume = value; - } - } - //SYMMETRIC SYNC - public void SetCollisionSoundVolume(float value) - { - m_collisionSoundVolume = value; + set { m_collisionSoundVolume = value; } } #endregion Public Properties with only Get @@ -2055,7 +1409,7 @@ namespace OpenSim.Region.Framework.Scenes }); // REGION SYNC if (m_parentGroup.Scene.IsSyncedServer()) - m_parentGroup.Scene.RegionSyncServerModule.QueuePartForUpdate(this); + m_parentGroup.Scene.RegionSyncServerModule.QueuePartForUpdate((SceneObjectPart)this); } /// @@ -2063,21 +1417,17 @@ namespace OpenSim.Region.Framework.Scenes /// public void AddFullUpdateToAvatar(ScenePresence presence) { - presence.SceneViewer.QueuePartForUpdate(this); + presence.SceneViewer.QueuePartForUpdate((SceneObjectPart)this); } public void AddNewParticleSystem(Primitive.ParticleSystem pSystem) { - //SYMMETRIC SYNC - //m_particleSystem = pSystem.GetBytes(); - ParticleSystem = pSystem.GetBytes(); + m_particleSystem = pSystem.GetBytes(); } public void RemoveParticleSystem() { - //SYMMETRIC SYNC - //m_particleSystem = new byte[0]; - ParticleSystem = new byte[0]; + m_particleSystem = new byte[0]; } /// Terse updates @@ -2089,12 +1439,12 @@ namespace OpenSim.Region.Framework.Scenes }); // REGION SYNC if (m_parentGroup.Scene.IsSyncedServer()) - m_parentGroup.Scene.RegionSyncServerModule.QueuePartForUpdate(this); + m_parentGroup.Scene.RegionSyncServerModule.QueuePartForUpdate((SceneObjectPart)this); } public void AddTerseUpdateToAvatar(ScenePresence presence) { - presence.SceneViewer.QueuePartForUpdate(this); + presence.SceneViewer.QueuePartForUpdate((SceneObjectPart)this); } public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim) @@ -2114,9 +1464,7 @@ namespace OpenSim.Region.Framework.Scenes Utils.FloatToBytes(pTexAnim.Length).CopyTo(data, pos + 4); Utils.FloatToBytes(pTexAnim.Rate).CopyTo(data, pos + 8); - //m_TextureAnimation = data; - //SYMMETRIC SYNC - TextureAnimation = data; + m_TextureAnimation = data; } public void AdjustSoundGain(double volume) @@ -2370,7 +1718,7 @@ namespace OpenSim.Region.Framework.Scenes dupe.DoPhysicsPropertyUpdate(UsePhysics, true); } - ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); + ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, (SceneObjectPart) this, userExposed); // m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); @@ -3492,10 +2840,6 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.HasGroupChanged = true; ScheduleFullUpdate(); - - //SYMMETRIC SYNC - //Make sure we record down the timestamp info for synchronization purpose - UpdateBucketSyncInfo("Scale"); } public void RotLookAt(Quaternion target, float strength, float damping) @@ -3652,10 +2996,7 @@ namespace OpenSim.Region.Framework.Scenes // Tricks physics engine into thinking we've changed the part shape. PrimitiveBaseShape m_newshape = m_shape.Copy(); PhysActor.Shape = m_newshape; - - //SYMMETRIC SYNC - //m_shape = m_newshape; - Shape = m_newshape; + m_shape = m_newshape; m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); } @@ -3824,7 +3165,7 @@ namespace OpenSim.Region.Framework.Scenes //SYMMETRIC SYNC if (m_parentGroup.Scene.RegionSyncModule == null) return; - m_parentGroup.Scene.RegionSyncModule.QueueSceneObjectPartForUpdate(this); + m_parentGroup.Scene.RegionSyncModule.QueueSceneObjectPartForUpdate((SceneObjectPart)this); //end of SYMMETRIC SYNC } @@ -3881,7 +3222,7 @@ namespace OpenSim.Region.Framework.Scenes soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, radius); else soundModule.PlayAttachedSound(soundID, ownerID, objectID, volume, position, flags, radius); - ParentGroup.PlaySoundMasterPrim = this; + ParentGroup.PlaySoundMasterPrim = (SceneObjectPart)this; ownerID = _ownerID; objectID = ParentGroup.RootPart.UUID; parentID = GetRootPartUUID(); @@ -3908,7 +3249,7 @@ namespace OpenSim.Region.Framework.Scenes } else { - ParentGroup.PlaySoundSlavePrims.Add(this); + ParentGroup.PlaySoundSlavePrims.Add((SceneObjectPart)this); } } else @@ -4224,10 +3565,7 @@ namespace OpenSim.Region.Framework.Scenes public void SetGroup(UUID groupID, IClientAPI client) { - //SYMMETRIC SYNC - //_groupID = groupID; - GroupID = groupID; - + _groupID = groupID; if (client != null) GetProperties(client); m_updateFlag = 2; @@ -4289,9 +3627,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void SetText(string text) { - //Text = text; - //SYMMETRIC SYNC: make set property calls consistent - m_text = text; + Text = text; ParentGroup.HasGroupChanged = true; ScheduleFullUpdate(); @@ -4342,14 +3678,14 @@ namespace OpenSim.Region.Framework.Scenes UndoState last = m_undo.Peek(); if (last != null) { - if (last.Compare(this)) + if (last.Compare((SceneObjectPart)this)) return; } } if (m_parentGroup.GetSceneMaxUndo() > 0) { - UndoState nUndo = new UndoState(this); + UndoState nUndo = new UndoState((SceneObjectPart)this); m_undo.Push(nUndo); } @@ -4802,7 +4138,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void ToXml(XmlTextWriter xmlWriter) { - SceneObjectSerializer.SOPToXml2(xmlWriter, this, new Dictionary()); + SceneObjectSerializer.SOPToXml2(xmlWriter, (SceneObjectPart)this, new Dictionary()); } public void TriggerScriptChangedEvent(Changed val) @@ -4829,12 +4165,12 @@ namespace OpenSim.Region.Framework.Scenes UndoState nUndo = null; if (m_parentGroup.GetSceneMaxUndo() > 0) { - nUndo = new UndoState(this); + nUndo = new UndoState((SceneObjectPart)this); } UndoState goback = m_undo.Pop(); if (goback != null) { - goback.PlaybackState(this); + goback.PlaybackState((SceneObjectPart)this); if (nUndo != null) m_redo.Push(nUndo); } @@ -4848,13 +4184,13 @@ namespace OpenSim.Region.Framework.Scenes { if (m_parentGroup.GetSceneMaxUndo() > 0) { - UndoState nUndo = new UndoState(this); + UndoState nUndo = new UndoState((SceneObjectPart)this); m_undo.Push(nUndo); } UndoState gofwd = m_redo.Pop(); if (gofwd != null) - gofwd.PlayfwdState(this); + gofwd.PlayfwdState((SceneObjectPart)this); } } @@ -4872,9 +4208,6 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.HasGroupChanged = true; ScheduleFullUpdate(); - - //SYMMETRIC SYNC - UpdateBucketSyncInfo("Shape"); } public void UpdateGroupPosition(Vector3 pos) @@ -4938,36 +4271,24 @@ namespace OpenSim.Region.Framework.Scenes case 1: if (god) { - //SYMMETRIC SYNC - //_baseMask = ApplyMask(_baseMask, set, mask); - BaseMask = ApplyMask(_baseMask, set, mask); + _baseMask = ApplyMask(_baseMask, set, mask); Inventory.ApplyGodPermissions(_baseMask); - } break; case 2: - //SYMMETRIC SYNC - //_ownerMask = ApplyMask(_ownerMask, set, mask) & - // baseMask; - OwnerMask = ApplyMask(_ownerMask, set, mask) & baseMask; + _ownerMask = ApplyMask(_ownerMask, set, mask) & + baseMask; break; case 4: - //SYMMETRIC SYNC - //_groupMask = ApplyMask(_groupMask, set, mask) & - // baseMask; - GroupMask = ApplyMask(_groupMask, set, mask) & + _groupMask = ApplyMask(_groupMask, set, mask) & baseMask; break; case 8: - //SYMMETRIC SYNC - //_everyoneMask = ApplyMask(_everyoneMask, set, mask) & - // baseMask; - EveryoneMask = ApplyMask(_everyoneMask, set, mask) & + _everyoneMask = ApplyMask(_everyoneMask, set, mask) & baseMask; break; case 16: - //SYMMETRIC SYNC _nextOwnerMask = ApplyMask(_nextOwnerMask, set, mask) & baseMask; // Prevent the client from creating no mod, no copy @@ -4975,9 +4296,7 @@ namespace OpenSim.Region.Framework.Scenes if ((_nextOwnerMask & (uint)PermissionMask.Copy) == 0) _nextOwnerMask |= (uint)PermissionMask.Transfer; - //_nextOwnerMask |= (uint)PermissionMask.Move; - NextOwnerMask = _nextOwnerMask | (uint)PermissionMask.Move; - + _nextOwnerMask |= (uint)PermissionMask.Move; break; } @@ -5278,9 +4597,6 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.HasGroupChanged = true; TriggerScriptChangedEvent(Changed.SHAPE); ScheduleFullUpdate(); - - //SYMMETRIC SYNC - UpdateBucketSyncInfo("Shape"); } /// @@ -5328,9 +4644,6 @@ namespace OpenSim.Region.Framework.Scenes //ParentGroup.ScheduleGroupForFullUpdate(); //This is sparta ScheduleFullUpdate(); - - //SYMMETRIC SYNC - UpdateBucketSyncInfo("Shape"); } public void aggregateScriptEvents() @@ -5639,7 +4952,6 @@ namespace OpenSim.Region.Framework.Scenes { m_lastUpdateTimeStamp = time; } - public void SetLastUpdateActorID() { @@ -5653,19 +4965,17 @@ 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() { @@ -5677,7 +4987,7 @@ namespace OpenSim.Region.Framework.Scenes SyncInfoUpdate(DateTime.Now.Ticks, m_parentGroup.Scene.GetSyncActorID()); } } - * */ + */ //The list of each prim's properties. This is the list of properties that matter in synchronizing prim copies on different actors. //This list is created based on properties included in the serialization/deserialization process (see SceneObjectSerializer()) and the @@ -5703,8 +5013,8 @@ namespace OpenSim.Region.Framework.Scenes "RotationOffset", "Velocity", "AngularVelocity", - "Acceleration", //This is the property maintained in SOP. SOP and PA read/write their own local copies of acceleration, so we distinguish the copies - //"SOP_Acceleration", //SOP and PA read/write their own local copies of acceleration, so we distinguish the copies + //"Acceleration", + "SOP_Acceleration", //SOP and PA read/write their own local copies of acceleration, so we distinguish the copies "Description", "Color", "Text", @@ -5734,7 +5044,6 @@ namespace OpenSim.Region.Framework.Scenes "EveryoneMask", "NextOwnerMask", "Flags", - "LocalFlags", "CollisionSound", "CollisionSoundVolume", "MediaUrl", @@ -5756,12 +5065,12 @@ namespace OpenSim.Region.Framework.Scenes - /* + private Object propertyUpdateLock = new Object(); + /* //!!!!!! -- TODO: //!!!!!! -- We should call UpdateXXX functions to update each property, cause some of such updates involves sanity checking. - public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart) { //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -5884,32 +5193,18 @@ namespace OpenSim.Region.Framework.Scenes return partUpdateResult; } - - * */ - - + * */ private bool UpdateCollisionSound(UUID updatedCollisionSound) { if (this.CollisionSound != updatedCollisionSound) { - //m_collisionSound = updatedCollisionSound; - SetCollisionSound(updatedCollisionSound); + m_collisionSound = updatedCollisionSound; return true; } return false; } - public string DebugObjectPartProperties() - { - string debugMsg = "UUID " + UUID + ", Name " + Name + ", localID " + LocalId; - debugMsg += ", parentID " + ParentID + ", parentUUID " + ParentUUID; - foreach (KeyValuePair pair in m_bucketSyncInfoList) - { - debugMsg += ", Bucket " + pair.Key + ": TimeStamp - " + pair.Value.LastUpdateTimeStamp + ", ActorID - " + pair.Value.LastUpdateActorID; - } - return debugMsg; - } /// /// Schedules this prim for a full update, without changing the timestamp or actorID (info on when and who modified any property). @@ -5946,6 +5241,78 @@ namespace OpenSim.Region.Framework.Scenes } + + + #endregion + + } + + //SYMMETRIC SYNC + + //Information for concurrency control of one bucket of prim proproperties. + public class BucketSyncInfo + { + private long m_lastUpdateTimeStamp; + private string m_lastUpdateActorID; + //lock for concurrent updates of the timestamp and actorID. + private Object m_updateLock = new Object(); + private string m_bucketName; + + public long LastUpdateTimeStamp + { + get { return m_lastUpdateTimeStamp; } + set { m_lastUpdateTimeStamp = value; } + } + + public string LastUpdateActorID + { + get { return m_lastUpdateActorID; } + set { m_lastUpdateActorID = value; } + } + + public string BucketName + { + get { return m_bucketName; } + } + + public BucketSyncInfo(string bucketName) + { + m_bucketName = bucketName; + } + + public BucketSyncInfo(long timeStamp, string actorID, string bucketName) + { + m_lastUpdateTimeStamp = timeStamp; + m_lastUpdateActorID = actorID; + m_bucketName = bucketName; + } + + public void UpdateSyncInfo(long timeStamp, string actorID) + { + lock (m_updateLock) + { + m_lastUpdateTimeStamp = timeStamp; + m_lastUpdateActorID = actorID; + } + } + + } + + + public class SceneObjectPart : SceneObjectPartBase + { + public SceneObjectPart() + : base() + { + } + + public SceneObjectPart( + UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, + Quaternion rotationOffset, Vector3 offsetPosition) + : base(ownerID, shape, groupPosition, rotationOffset, offsetPosition) + { + } + //The following variables should be initialized when this SceneObjectPart is added into the local Scene. //private List SynchronizeUpdatesToScene = null; //public List BucketSyncInfoList @@ -5975,7 +5342,7 @@ namespace OpenSim.Region.Framework.Scenes //property set functions will be called and might trigger UpdateBucketSyncInfo() if not guarded carefully. private bool m_syncEnabled = false; - public static void InitializeBucketInfo(Dictionary propertyBucketMap, List bucketNames, string actorID) + public static void InitializePropertyBucketInfo(Dictionary propertyBucketMap, List bucketNames, string actorID) { m_primPropertyBucketMap = propertyBucketMap; m_propertyBucketNames = bucketNames; @@ -5985,6 +5352,17 @@ namespace OpenSim.Region.Framework.Scenes //RegisterBucketUpdateProcessor(); } + public string DebugObjectPartProperties() + { + string debugMsg = "UUID " + UUID + ", Name " + Name + ", localID " + LocalId; + debugMsg += ", parentID " + ParentID + ", parentUUID " + ParentUUID; + foreach (KeyValuePair pair in m_bucketSyncInfoList) + { + debugMsg += ", Bucket " + pair.Key + ": TimeStamp - " + pair.Value.LastUpdateTimeStamp + ", ActorID - " + pair.Value.LastUpdateActorID; + } + return debugMsg; + } + /// /// Link each bucket with the function that applies updates to properties in the bucket upon receiving sync messages. /// This is the "hard-coded" part in the property-buckets implementation. When new buckets are implemented, @@ -5992,7 +5370,6 @@ namespace OpenSim.Region.Framework.Scenes /// //private static void RegisterBucketUpdateProcessor() private void RegisterBucketUpdateProcessor() - { foreach (string bucketName in m_propertyBucketNames) { @@ -6015,66 +5392,7 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_bucketUpdateLocks[bucketName]) { - SetAllowedDrop(updatedPart.AllowedDrop); - SetCreatorID(updatedPart.CreatorID); - SetCreatorData(updatedPart.CreatorData); - //FolderID skipped - SetInventorySerial(updatedPart.InventorySerial); - SetTaskInventory(updatedPart.TaskInventory); - //UUID skipped - //LocalId skipped - SetName(updatedPart.Name); - SetMaterial(updatedPart.Material); - SetPassTouches(updatedPart.PassTouches); - //RegionHandle skipped - SetScriptAccessPin(updatedPart.ScriptAccessPin); - SetAcceleration(updatedPart.Acceleration); - SetDescription(updatedPart.Description); - SetColor(updatedPart.Color); - SetText(updatedPart.Text); - SetSitName(updatedPart.SitName); - SetTouchName(updatedPart.TouchName); - SetLinkNum(updatedPart.LinkNum); - SetClickAction(updatedPart.ClickAction); - SetShape(updatedPart.Shape); - //UpdateFlag skipped: It's a flag meanful locally, especially in scheduling updates to viewers. - //Only in one place will it cause updating some "last" variables (see SendScheduledUpdates). - SetSitTargetOrientation(updatedPart.SitTargetOrientation); - SetSitTargetPosition(updatedPart.SitTargetPosition); - SetSitTargetPositionLL(updatedPart.SitTargetPositionLL); - SetSitTargetOrientationLL(updatedPart.SitTargetOrientationLL); - //ParentID skipped, the value is assigned locally and only meaningful locally (LinkObjects and LinkObjectsBySync will set it appropriately)\ - SetCreationDate(updatedPart.CreationDate); - SetCategory(updatedPart.Category); - SetSalePrice(updatedPart.SalePrice); - SetObjectSaleType(updatedPart.ObjectSaleType); - SetOwnershipCost(updatedPart.OwnershipCost); - SetGroupID(updatedPart.GroupID); - SetOwnerID(updatedPart.OwnerID); - SetLastOwnerID(updatedPart.LastOwnerID); - SetBaseMask(updatedPart.BaseMask); - SetOwnerMask(updatedPart.OwnerMask); - SetGroupMask(updatedPart.GroupMask); - SetEveryoneMask(updatedPart.EveryoneMask); - SetNextOwnerMask(updatedPart.NextOwnerMask); - SetFlags(updatedPart.Flags); - //Treat CollisionSound in a different way, so that if any property needs to be changed due to aggregateScriptEvents(), timestamp can be updated after - //the current copying-property-values-from-remote-sync-message is done. - bool collisionSoundUpdated = UpdateCollisionSound(updatedPart.CollisionSound); - SetCollisionSoundVolume(updatedPart.CollisionSoundVolume); - SetMediaUrl(updatedPart.MediaUrl); - SetTextureAnimation(updatedPart.TextureAnimation); - SetParticleSystem(updatedPart.ParticleSystem); - - m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp; - m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID; - - if (collisionSoundUpdated) - { - //If the local actor is Script Engine, it will catch this evnet and trigger aggregateScriptEvents() - m_parentGroup.Scene.EventManager.TriggerAggregateScriptEvents(this); - } } } @@ -6082,29 +5400,6 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_bucketUpdateLocks[bucketName]) { - SetGroupPosition(updatedPart.GroupPosition); - SetOffsetPosition(updatedPart.OffsetPosition); - SetScale(updatedPart.Scale); - SetVelocity(updatedPart.Velocity); - SetAngularVelocity(updatedPart.AngularVelocity); - SetRotationOffset(updatedPart.RotationOffset); - - //properties in Physics bucket whose update processors are in PhysicsActor - /* - "Position": - "Size": - "Force": - "RotationalVelocity": - "PA_Acceleration": - "Torque": - "Orientation": - "IsPhysical": - "Flying": - "Buoyancy": - * */ - - m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp; - m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID; } } @@ -6154,7 +5449,7 @@ namespace OpenSim.Region.Framework.Scenes /// Name of the property. Make sure the spelling is consistent with what are defined in PropertyList public void UpdateBucketSyncInfo(string propertyName) { - if (m_syncEnabled && m_bucketSyncInfoList != null && m_bucketSyncInfoList.Count>0) + if (m_syncEnabled && m_bucketSyncInfoList != null && m_bucketSyncInfoList.Count > 0) { //int bucketIndex = m_primPropertyBucketMap[propertyName]; string bucketName = m_primPropertyBucketMap[propertyName]; @@ -6170,7 +5465,7 @@ namespace OpenSim.Region.Framework.Scenes } } - + public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart) { @@ -6222,16 +5517,26 @@ namespace OpenSim.Region.Framework.Scenes m_log.Warn("No update processor for property bucket " + bucketName); } - + } return partUpdateResult; } - - //private void UpdateBucketProperties(string bucketDescription, - #endregion + public void SetProperty(string pName, object value) + { + switch (pName) + { + case "LinkNum": + base.LinkNum = (int)value; + break; + default: + break; + } + } } + + //end of SYMMETRIC SYNC } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 3a87dda99f..1d1e66c826 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -41,7 +41,8 @@ using OpenSim.Region.Framework.Scenes.Serialization; namespace OpenSim.Region.Framework.Scenes { - public class SceneObjectPartInventory : IEntityInventory + //public class SceneObjectPartInventory : IEntityInventory + public class SceneObjectPartInventoryBase : IEntityInventory { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -52,7 +53,8 @@ namespace OpenSim.Region.Framework.Scenes /// /// The part to which the inventory belongs. /// - private SceneObjectPart m_part; + //private SceneObjectPart m_part; + private SceneObjectPartBase m_part; /// /// Serial count for inventory file , used to tell if inventory has changed @@ -76,19 +78,7 @@ namespace OpenSim.Region.Framework.Scenes protected internal uint Serial { get { return m_inventorySerial; } - set - { - SetSerial(value); - m_part.UpdateBucketSyncInfo("InventorySerial"); - //m_inventorySerial = value; - } - } - - //SYMMETRIC SYNC - public void SetSerial(uint value) - { - m_inventorySerial = value; - + set { m_inventorySerial = value; } } /// @@ -99,21 +89,10 @@ namespace OpenSim.Region.Framework.Scenes get { return m_items; } set { - SetItems(value); + m_items = value; m_inventorySerial++; - m_part.UpdateBucketSyncInfo("TaskInventory"); - m_part.UpdateBucketSyncInfo("InventorySerial"); - //m_items = value; - //m_inventorySerial++; } } - //SYMMETRIC SYNC - //This is inparticular for updating properties - public void SetItems(TaskInventoryDictionary value) - { - m_items = value; - //m_inventorySerial++; - } /// /// Constructor @@ -121,7 +100,8 @@ namespace OpenSim.Region.Framework.Scenes /// /// A /// - public SceneObjectPartInventory(SceneObjectPart part) + //public SceneObjectPartInventory(SceneObjectPart part) + public SceneObjectPartInventoryBase(SceneObjectPartBase part) { m_part = part; } @@ -159,10 +139,6 @@ namespace OpenSim.Region.Framework.Scenes item.ResetIDs(m_part.UUID); m_items.Add(item.ItemID, item); } - - //SYMMETRIC SYNC - //No need to trigger UpdateBucketSyncInfo, as callers eventually will call SOG.AttachToScene and init BucketSyncInfo - } } @@ -179,9 +155,6 @@ namespace OpenSim.Region.Framework.Scenes item.ParentID = m_part.UUID; Items.Add(item.ItemID, item); } - - //SYMMETRIC SYNC - //No need to trigger UpdateBucketSyncInfo, this is called only when SOP.UUID is written, which is assumed not to change after being created. } } @@ -212,9 +185,6 @@ namespace OpenSim.Region.Framework.Scenes item.PermsGranter = UUID.Zero; } } - - //SYMMETRIC SYNC - m_part.UpdateBucketSyncInfo("TaskInventory"); } /// @@ -246,12 +216,6 @@ namespace OpenSim.Region.Framework.Scenes if (groupID != item.GroupID) item.GroupID = groupID; } - - //SYMMETRIC SYNC: need to test if we need to take different actions when this is attachment or not - //if (!m_part.ParentGroup.RootPart.IsAttachment) - //{ - m_part.UpdateBucketSyncInfo("TaskInventory"); - } /// @@ -582,11 +546,7 @@ namespace OpenSim.Region.Framework.Scenes m_part.ParentGroup.HasGroupChanged = true; //SYMMETRIC SYNC: add ScheduleFullUpdate to enable synchronization across actors - //m_part.ScheduleFullUpdate(); - - //SYMMETRIC SYNC - m_part.UpdateBucketSyncInfo("TaskInventory"); - m_part.UpdateBucketSyncInfo("InventorySerial"); //m_inventorySerial is also changed, + m_part.ScheduleFullUpdate(); } /// @@ -607,9 +567,6 @@ namespace OpenSim.Region.Framework.Scenes } m_inventorySerial++; } - - //SYMMETRIC SYNC: no UpdateBucketSyncInfo called here, since this function is called by loading objects from DB, and UpdateBucketSyncInfo - //will be called after all objects are loaded. } /// @@ -768,10 +725,6 @@ namespace OpenSim.Region.Framework.Scenes HasInventoryChanged = true; m_part.ParentGroup.HasGroupChanged = true; } - - //SYMMETRIC SYNC - m_part.UpdateBucketSyncInfo("TaskInventory"); - m_part.UpdateBucketSyncInfo("InventorySerial"); return true; } else @@ -815,10 +768,6 @@ namespace OpenSim.Region.Framework.Scenes m_part.ScheduleFullUpdate(); - //SYMMETRIC SYNC - m_part.UpdateBucketSyncInfo("TaskInventory"); - m_part.UpdateBucketSyncInfo("InventorySerial"); - return type; } @@ -1073,9 +1022,6 @@ namespace OpenSim.Region.Framework.Scenes item.OwnerChanged = true; item.PermsMask = 0; item.PermsGranter = UUID.Zero; - - //SYMMETRIC SYNC - m_part.UpdateBucketSyncInfo("TaskInventory"); } } } @@ -1092,10 +1038,6 @@ namespace OpenSim.Region.Framework.Scenes } m_inventorySerial++; HasInventoryChanged = true; - - //SYMMETRIC SYNC - m_part.UpdateBucketSyncInfo("TaskInventory"); - m_part.UpdateBucketSyncInfo("InventorySerial"); } public bool ContainsScripts() @@ -1233,4 +1175,25 @@ namespace OpenSim.Region.Framework.Scenes } #endregion REGION SYNC } + + #region SYMMETRIC SYNC + public class SceneObjectPartInventory : SceneObjectPartInventoryBase + { + private SceneObjectPart m_part; + public SceneObjectPartInventory(SceneObjectPart part):base((SceneObjectPartBase) part) + { + m_part = part; + } + + new protected internal uint Serial + { + get { return base.Serial; } + set + { + base.Serial = value; + //m_part.UpdateBucketSyncInfo("InventorySerial"); + } + } + } + #endregion } diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index b44a0100a4..d3b4f94bfa 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -57,11 +57,12 @@ 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) + public void QueuePartForUpdate(SceneObjectPartBase part) { lock (m_partsUpdateQueue) { - m_partsUpdateQueue.Enqueue(part); + m_partsUpdateQueue.Enqueue((SceneObjectPart)part); } } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 4189c1fc88..9659845567 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -423,8 +423,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization //That is, calling SetXXX(value) instead of using "XXX = value". private static void ProcessAllowedDrop(SceneObjectPart obj, XmlTextReader reader) { - //obj.AllowedDrop = Util.ReadBoolean(reader); - obj.SetAllowedDrop(Util.ReadBoolean(reader)); + obj.AllowedDrop = Util.ReadBoolean(reader); + //obj.SetAllowedDrop(Util.ReadBoolean(reader)); } private static void ProcessCreatorID(SceneObjectPart obj, XmlTextReader reader) @@ -489,32 +489,32 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessGroupPosition(SceneObjectPart obj, XmlTextReader reader) { - //obj.GroupPosition = Util.ReadVector(reader, "GroupPosition"); - obj.SetGroupPosition(Util.ReadVector(reader, "GroupPosition")); + obj.GroupPosition = Util.ReadVector(reader, "GroupPosition"); + //obj.SetGroupPosition(Util.ReadVector(reader, "GroupPosition")); } private static void ProcessOffsetPosition(SceneObjectPart obj, XmlTextReader reader) { - //obj.OffsetPosition = Util.ReadVector(reader, "OffsetPosition"); ; - obj.SetOffsetPosition(Util.ReadVector(reader, "OffsetPosition")); + obj.OffsetPosition = Util.ReadVector(reader, "OffsetPosition"); ; + //obj.SetOffsetPosition(Util.ReadVector(reader, "OffsetPosition")); } private static void ProcessRotationOffset(SceneObjectPart obj, XmlTextReader reader) { - //obj.RotationOffset = Util.ReadQuaternion(reader, "RotationOffset"); - obj.SetRotationOffset(Util.ReadQuaternion(reader, "RotationOffset")); + obj.RotationOffset = Util.ReadQuaternion(reader, "RotationOffset"); + //obj.SetRotationOffset(Util.ReadQuaternion(reader, "RotationOffset")); } private static void ProcessVelocity(SceneObjectPart obj, XmlTextReader reader) { - //obj.Velocity = Util.ReadVector(reader, "Velocity"); - obj.SetVelocity(Util.ReadVector(reader, "Velocity")); + obj.Velocity = Util.ReadVector(reader, "Velocity"); + //obj.SetVelocity(Util.ReadVector(reader, "Velocity")); } private static void ProcessAngularVelocity(SceneObjectPart obj, XmlTextReader reader) { - //obj.AngularVelocity = Util.ReadVector(reader, "AngularVelocity"); - obj.SetVelocity(Util.ReadVector(reader, "AngularVelocity")); + obj.AngularVelocity = Util.ReadVector(reader, "AngularVelocity"); + //obj.SetVelocity(Util.ReadVector(reader, "AngularVelocity")); } private static void ProcessAcceleration(SceneObjectPart obj, XmlTextReader reader) @@ -573,8 +573,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader) { - //obj.Scale = Util.ReadVector(reader, "Scale"); - obj.SetScale(Util.ReadVector(reader, "Scale")); + obj.Scale = Util.ReadVector(reader, "Scale"); + //obj.SetScale(Util.ReadVector(reader, "Scale")); } private static void ProcessUpdateFlag(SceneObjectPart obj, XmlTextReader reader) diff --git a/OpenSim/Region/Framework/Scenes/Types/UpdateQueue.cs b/OpenSim/Region/Framework/Scenes/Types/UpdateQueue.cs index 213e954c1f..ad26e8159f 100644 --- a/OpenSim/Region/Framework/Scenes/Types/UpdateQueue.cs +++ b/OpenSim/Region/Framework/Scenes/Types/UpdateQueue.cs @@ -62,7 +62,7 @@ namespace OpenSim.Region.Framework.Scenes.Types } } - public void Enqueue(SceneObjectPart part) + public void Enqueue(SceneObjectPart part) { lock (m_syncObject) { From 1da933041cd4363508a7959f6dacd802c0f7ad19 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Thu, 10 Feb 2011 11:37:34 -0800 Subject: [PATCH 16/22] Started to added new access functions of SOP properties. --- .../Framework/Scenes/SceneObjectGroup.cs | 3 +- .../Framework/Scenes/SceneObjectPart.cs | 374 +++++------------- 2 files changed, 101 insertions(+), 276 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 80a93e7540..fc6fa035ea 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3851,7 +3851,8 @@ namespace OpenSim.Region.Framework.Scenes m_rootPart = part; if (!IsAttachment) part.ParentID = 0; - part.SetProperty("LinkNum", 0); +// part.SetProperty("LinkNum", 0); + ((SceneObjectPartBase)part).LinkNum = 0; m_parts.Add(m_rootPart.UUID, m_rootPart); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index d2929fe0a8..d8461c0664 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -352,7 +352,7 @@ namespace OpenSim.Region.Framework.Scenes private bool m_forceMouselook; // TODO: Collision sound should have default. - private UUID m_collisionSound; + protected UUID m_collisionSound; private float m_collisionSoundVolume; #endregion Fields @@ -4938,273 +4938,6 @@ namespace OpenSim.Region.Framework.Scenes 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_lastUpdateActorID=""; - public string LastUpdateActorID - { - get { return m_lastUpdateActorID; } - set { m_lastUpdateActorID = value; } - } - - public void UpdateTimestamp(long time) - { - m_lastUpdateTimeStamp = time; - } - - public void SetLastUpdateActorID() - { - if (m_parentGroup != null) - { - m_lastUpdateActorID = m_parentGroup.Scene.GetSyncActorID(); - } - else - { - m_log.Error("Prim " + UUID + " is not in a SceneObjectGroup yet"); - } - } - - 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() - { - //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 && m_parentGroup.Scene != null && m_parentGroup.Scene.ActorSyncModule != null) - { - SyncInfoUpdate(DateTime.Now.Ticks, m_parentGroup.Scene.GetSyncActorID()); - } - } - */ - - //The list of each prim's properties. This is the list of properties that matter in synchronizing prim copies on different actors. - //This list is created based on properties included in the serialization/deserialization process (see SceneObjectSerializer()) and the - //properties Physics Engine needs to synchronize to other actors. - public static List PropertyList = new List() - { - //Following properties copied from SceneObjectSerializer() - "AllowedDrop", - "CreatorID", - "CreatorData", - "FolderID", - "InventorySerial", - "TaskInventory", - "UUID", - "LocalId", - "Name", - "Material", - "PassTouches", - "RegionHandle", - "ScriptAccessPin", - "GroupPosition", - "OffsetPosition", - "RotationOffset", - "Velocity", - "AngularVelocity", - //"Acceleration", - "SOP_Acceleration", //SOP and PA read/write their own local copies of acceleration, so we distinguish the copies - "Description", - "Color", - "Text", - "SitName", - "TouchName", - "LinkNum", - "ClickAction", - "Shape", - "Scale", - "UpdateFlag", - "SitTargetOrientation", - "SitTargetPosition", - "SitTargetPositionLL", - "SitTargetOrientationLL", - "ParentID", - "CreationDate", - "Category", - "SalePrice", - "ObjectSaleType", - "OwnershipCost", - "GroupID", - "OwnerID", - "LastOwnerID", - "BaseMask", - "OwnerMask", - "GroupMask", - "EveryoneMask", - "NextOwnerMask", - "Flags", - "CollisionSound", - "CollisionSoundVolume", - "MediaUrl", - "TextureAnimation", - "ParticleSystem", - //Property names below copied from PhysicsActor, they are necessary in synchronization, but not covered the above properties - //Physics properties "Velocity" is covered above - "Position", - "Size", - "Force", - "RotationalVelocity", - "PA_Acceleration", - "Torque", - "Orientation", - "IsPhysical", - "Flying", - "Buoyancy", - }; - - - - - private Object propertyUpdateLock = new Object(); - - /* - //!!!!!! -- TODO: - //!!!!!! -- We should call UpdateXXX functions to update each property, cause some of such updates involves sanity checking. - public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart) - { - //////////////////////////////////////////////////////////////////////////////////////////////////// - //NOTE!!!: So far this function is written with Script Engine updating local Scene cache in mind. - //////////////////////////////////////////////////////////////////////////////////////////////////// - - ////////////////////Assumptions: //////////////////// - //(1) prim's UUID and LocalID shall not change (UUID is the unique identifies, LocalID is used to refer to the prim by, say scripts) - //(2) RegionHandle won't be updated -- each copy of Scene is hosted on a region with different region handle - //(3) ParentID won't be updated -- if the rootpart of the SceneObjectGroup changed, that will be updated in SceneObjectGroup.UpdateObjectProperties - - ////////////////////Furture enhancements://////////////////// - //For now, we only update the set of properties that are included in serialization. - //See SceneObjectSerializer for the properties that are included in a serialized SceneObjectPart. - //Later on, we may implement update functions that allow updating certain properties or certain buckets of properties. - - if (updatedPart == null) - return Scene.ObjectUpdateResult.Error; - - if (m_lastUpdateTimeStamp > updatedPart.LastUpdateTimeStamp) - { - //Our timestamp is more update to date, keep our values of the properties. Do not update anything. - return Scene.ObjectUpdateResult.Unchanged; - } - - if (m_lastUpdateTimeStamp == updatedPart.LastUpdateTimeStamp) - { - //if (m_parentGroup.Scene.GetActorID() != updatedPart.LastUpdatedByActorID) - if (m_lastUpdateActorID != updatedPart.LastUpdateActorID) - { - m_log.Warn("Different actors modified SceneObjetPart " + UUID + " with the same TimeStamp, CONFLICT RESOLUTION TO BE IMPLEMENTED!!!!"); - return Scene.ObjectUpdateResult.Unchanged; - } - - //My own update was relayed back. Don't relay it. - return Scene.ObjectUpdateResult.Unchanged; - } - - //Otherwise, our timestamp is less up to date, update the prim with the received copy - - Scene.ObjectUpdateResult partUpdateResult = Scene.ObjectUpdateResult.Updated; - bool collisionSoundUpdated = false; - lock (propertyUpdateLock) - { - - //See SceneObjectSerializer for the properties that are included in a serialized SceneObjectPart. - this.AllowedDrop = updatedPart.AllowedDrop; - this.CreatorID = updatedPart.CreatorID; - this.CreatorData = updatedPart.CreatorData; - this.FolderID = updatedPart.FolderID; - this.InventorySerial = updatedPart.InventorySerial; - this.TaskInventory = updatedPart.TaskInventory; - //Following two properties, UUID and LocalId, shall not be updated. - //this.UUID - //this.LocalId - this.Name = updatedPart.Name; - this.Material = updatedPart.Material; - this.PassTouches = updatedPart.PassTouches; - //RegionHandle shall not be copied, since updatedSog is sent by a different actor, which has a different local region - //this.RegionHandle - this.ScriptAccessPin = updatedPart.ScriptAccessPin; - this.GroupPosition = updatedPart.GroupPosition; - this.OffsetPosition = updatedPart.OffsetPosition; - this.RotationOffset = updatedPart.RotationOffset; - this.Velocity = updatedPart.Velocity; - this.AngularVelocity = updatedPart.AngularVelocity; - this.Acceleration = updatedPart.Acceleration; - this.Description = updatedPart.Description; - this.Color = updatedPart.Color; - this.Text = updatedPart.Text; - this.SitName = updatedPart.SitName; - this.TouchName = updatedPart.TouchName; - this.LinkNum = updatedPart.LinkNum; - this.ClickAction = updatedPart.ClickAction; - this.Shape = updatedPart.Shape; - this.Scale = updatedPart.Scale; - this.UpdateFlag = updatedPart.UpdateFlag; - this.SitTargetOrientation = updatedPart.SitTargetOrientation; - this.SitTargetPosition = updatedPart.SitTargetPosition; - this.SitTargetPositionLL = updatedPart.SitTargetPositionLL; - this.SitTargetOrientationLL = updatedPart.SitTargetOrientationLL; - //ParentID should still point to the rootpart in the local sog, do not update. If the root part changed, we will update it in SceneObjectGroup.UpdateObjectProperties() - //this.ParentID; - this.CreationDate = updatedPart.CreationDate; - this.Category = updatedPart.Category; - this.SalePrice = updatedPart.SalePrice; - this.ObjectSaleType = updatedPart.ObjectSaleType; - this.OwnershipCost = updatedPart.OwnershipCost; - this.GroupID = updatedPart.GroupID; - this.OwnerID = updatedPart.OwnerID; - this.LastOwnerID = updatedPart.LastOwnerID; - this.BaseMask = updatedPart.BaseMask; - this.OwnerMask = updatedPart.OwnerMask; - this.GroupMask = updatedPart.GroupMask; - this.EveryoneMask = updatedPart.EveryoneMask; - this.NextOwnerMask = updatedPart.NextOwnerMask; - this.Flags = updatedPart.Flags; - - //We will update CollisionSound with special care so that it does not lead to ScheduleFullUpdate of this part, to make the actor think it just made an update and - //need to propogate that update to other actors. - //this.CollisionSound = updatedPart.CollisionSound; - collisionSoundUpdated = UpdateCollisionSound(updatedPart.CollisionSound); - - this.CollisionSoundVolume = updatedPart.CollisionSoundVolume; - this.MediaUrl = updatedPart.MediaUrl; - this.TextureAnimation = updatedPart.TextureAnimation; - this.ParticleSystem = updatedPart.ParticleSystem; - - //Update the timestamp and LastUpdatedByActorID first. - this.m_lastUpdateActorID = updatedPart.LastUpdateActorID; - this.m_lastUpdateTimeStamp = updatedPart.LastUpdateTimeStamp; - } - - if (collisionSoundUpdated) - { - m_parentGroup.Scene.EventManager.TriggerAggregateScriptEvents(this); - } - - //m_log.Debug("SceneObjectPart Name-" +Name+", UUID-"+UUID+" localID-" + m_localId + " updated"); - - return partUpdateResult; - } - * */ - - private bool UpdateCollisionSound(UUID updatedCollisionSound) - { - if (this.CollisionSound != updatedCollisionSound) - { - m_collisionSound = updatedCollisionSound; - return true; - } - return false; - } - /// /// Schedules this prim for a full update, without changing the timestamp or actorID (info on when and who modified any property). @@ -5342,6 +5075,81 @@ namespace OpenSim.Region.Framework.Scenes //property set functions will be called and might trigger UpdateBucketSyncInfo() if not guarded carefully. private bool m_syncEnabled = false; + //The list of each prim's properties. This is the list of properties that matter in synchronizing prim copies on different actors. + //This list is created based on properties included in the serialization/deserialization process (see SceneObjectSerializer()) and the + //properties Physics Engine needs to synchronize to other actors. + public static List PropertyList = new List() + { + //Following properties copied from SceneObjectSerializer() + "AllowedDrop", + "CreatorID", + "CreatorData", + "FolderID", + "InventorySerial", + "TaskInventory", + "UUID", + "LocalId", + "Name", + "Material", + "PassTouches", + "RegionHandle", + "ScriptAccessPin", + "GroupPosition", + "OffsetPosition", + "RotationOffset", + "Velocity", + "AngularVelocity", + //"Acceleration", + "SOP_Acceleration", //SOP and PA read/write their own local copies of acceleration, so we distinguish the copies + "Description", + "Color", + "Text", + "SitName", + "TouchName", + "LinkNum", + "ClickAction", + "Shape", + "Scale", + "UpdateFlag", + "SitTargetOrientation", + "SitTargetPosition", + "SitTargetPositionLL", + "SitTargetOrientationLL", + "ParentID", + "CreationDate", + "Category", + "SalePrice", + "ObjectSaleType", + "OwnershipCost", + "GroupID", + "OwnerID", + "LastOwnerID", + "BaseMask", + "OwnerMask", + "GroupMask", + "EveryoneMask", + "NextOwnerMask", + "Flags", + "CollisionSound", + "CollisionSoundVolume", + "MediaUrl", + "TextureAnimation", + "ParticleSystem", + //Property names below copied from PhysicsActor, they are necessary in synchronization, but not covered the above properties + //Physics properties "Velocity" is covered above + "Position", + "Size", + "Force", + "RotationalVelocity", + "PA_Acceleration", + "Torque", + "Orientation", + "IsPhysical", + "Flying", + "Buoyancy", + }; + + public static void InitializePropertyBucketInfo(Dictionary propertyBucketMap, List bucketNames, string actorID) { m_primPropertyBucketMap = propertyBucketMap; @@ -5524,18 +5332,34 @@ namespace OpenSim.Region.Framework.Scenes } - public void SetProperty(string pName, object value) + #region new property access functions + //(only properties relevant for synchronization purpose are implemented here) + + public bool AllowedDrop { - switch (pName) + get { return base.AllowedDrop; } + set { - case "LinkNum": - base.LinkNum = (int)value; - break; - default: - break; + base.AllowedDrop = value; + UpdateBucketSyncInfo("AllowedDrop"); } } + + + #endregion //new property access functions + + + private bool UpdateCollisionSound(UUID updatedCollisionSound) + { + if (this.CollisionSound != updatedCollisionSound) + { + m_collisionSound = updatedCollisionSound; + return true; + } + return false; + } + } //end of SYMMETRIC SYNC From 88e42011af4efd3ee974654ccd44547f1930e2f8 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Thu, 10 Feb 2011 15:30:27 -0800 Subject: [PATCH 17/22] In current SOP class, overrode functions in SOPBase that modified values of Shape or properties of Shape. --- .../Framework/Scenes/SceneObjectPart.cs | 104 +++++++++++++++++- 1 file changed, 98 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index d8461c0664..ba64878cbb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2981,7 +2981,8 @@ namespace OpenSim.Region.Framework.Scenes } - public void SculptTextureCallback(UUID textureID, AssetBase texture) + //public void SculptTextureCallback(UUID textureID, AssetBase texture) + public virtual void SculptTextureCallback(UUID textureID, AssetBase texture) { if (m_shape.SculptEntry) { @@ -3273,7 +3274,8 @@ namespace OpenSim.Region.Framework.Scenes }); } - public void SetAttachmentPoint(uint AttachmentPoint) + //public void SetAttachmentPoint(uint AttachmentPoint) + public virtual void SetAttachmentPoint(uint AttachmentPoint) { this.AttachmentPoint = AttachmentPoint; @@ -3289,7 +3291,8 @@ namespace OpenSim.Region.Framework.Scenes // save the attachment point. //if (AttachmentPoint != 0) //{ - m_shape.State = (byte)AttachmentPoint; + m_shape.State = (byte)AttachmentPoint; + //} } @@ -4208,6 +4211,7 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.HasGroupChanged = true; ScheduleFullUpdate(); + } public void UpdateGroupPosition(Vector3 pos) @@ -4559,7 +4563,8 @@ namespace OpenSim.Region.Framework.Scenes /// Update the shape of this part. /// /// - public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock) + //public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock) + public virtual void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock) { m_shape.PathBegin = shapeBlock.PathBegin; m_shape.PathEnd = shapeBlock.PathEnd; @@ -4634,7 +4639,8 @@ namespace OpenSim.Region.Framework.Scenes /// Update the texture entry for this part. /// /// - public void UpdateTextureEntry(byte[] textureEntry) + //public void UpdateTextureEntry(byte[] textureEntry) + public virtual void UpdateTextureEntry(byte[] textureEntry) { m_shape.TextureEntry = textureEntry; TriggerScriptChangedEvent(Changed.TEXTURE); @@ -5196,18 +5202,51 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// Update the properties of this SOP with the values in updatedPart. + /// + /// + /// + private void GeneralBucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName) { + //NOTE!!!!!!!! Need to cast the local copy to SceneObjectPartBase in order not to trigger UpdateBucketSyncInfo(), + //since the property updates inside this function are not due to local operations. + SceneObjectPartBase localPart = (SceneObjectPartBase)this; + lock (m_bucketUpdateLocks[bucketName]) { + localPart.AllowedDrop = updatedPart.AllowedDrop; + localPart.Shape = updatedPart.Shape; + + bool collisionSoundUpdated = UpdateCollisionSound(updatedPart.CollisionSound); + + + m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp; + m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID; + + if (collisionSoundUpdated) + { + //If the local actor is Script Engine, it will catch this evnet and trigger aggregateScriptEvents() + m_parentGroup.Scene.EventManager.TriggerAggregateScriptEvents(this); + } } } private void PhysicsBucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName) { + //NOTE!!!!!!!! Need to cast the local copy to SceneObjectPartBase in order not to trigger UpdateBucketSyncInfo(), + //since the property updates inside this function are not due to local operations. + SceneObjectPartBase localPart = (SceneObjectPartBase)this; + lock (m_bucketUpdateLocks[bucketName]) { + localPart.GroupPosition = updatedPart.GroupPosition; + + m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp; + m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID; + } } @@ -5335,7 +5374,7 @@ namespace OpenSim.Region.Framework.Scenes #region new property access functions //(only properties relevant for synchronization purpose are implemented here) - public bool AllowedDrop + new public bool AllowedDrop { get { return base.AllowedDrop; } set @@ -5345,7 +5384,60 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// The position of the entire group that this prim belongs to. + /// + new public Vector3 GroupPosition + { + get { return base.GroupPosition; } + set + { + base.GroupPosition = value; + UpdateBucketSyncInfo("GroupPosition"); + } + } + new public PrimitiveBaseShape Shape + { + get { return base.Shape; } + set + { + base.Shape = value; + UpdateBucketSyncInfo("Shape"); + } + } + + //For functions that update SOP properties, override them so that when they are called from SOPBase (but the object itself is an instance of SOP) + //the following implementations will be called instead of the same name functions in SOPBase. + public override void SculptTextureCallback(UUID textureID, AssetBase texture) + { + base.SculptTextureCallback(textureID, texture); + UpdateBucketSyncInfo("Shape"); + } + + public override void SetAttachmentPoint(uint AttachmentPoint) + { + base.SetAttachmentPoint(AttachmentPoint); + UpdateBucketSyncInfo("Shape"); + } + + public void UpdateExtraParam(ushort type, bool inUse, byte[] data) + { + base.UpdateExtraParam(type, inUse, data); + UpdateBucketSyncInfo("Shape"); + } + + public override void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock) + { + base.UpdateShape(shapeBlock); + UpdateBucketSyncInfo("Shape"); + } + + public override void UpdateTextureEntry(byte[] textureEntry) + { + base.UpdateTextureEntry(textureEntry); + UpdateBucketSyncInfo("Shape"); + } #endregion //new property access functions From 5ef659520e337eb3d3cf3c66969dd185e36fe74d Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Thu, 10 Feb 2011 17:06:15 -0800 Subject: [PATCH 18/22] Access to sop.Shape.Scale replaced by sop.Scale. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 8 +++++--- .../Region/Framework/Scenes/SceneObjectPart.cs | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index e58f5e881c..f43e12669f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -374,7 +374,8 @@ namespace OpenSim.Region.Framework.Scenes if (scale.Z > m_parentScene.m_maxNonphys) scale.Z = m_parentScene.m_maxNonphys; - part.Shape.Scale = scale; + //part.Shape.Scale = scale; + part.Scale = scale; } } m_numPrim += children.Length; @@ -2053,7 +2054,8 @@ namespace OpenSim.Region.Framework.Scenes { foreach (SceneObjectPart part in children) { - Vector3 scale = part.Shape.Scale; + SceneObjectPartBase partBase = (SceneObjectPartBase)part; + Vector3 scale = partBase.Scale; if (scale.X > m_parentScene.m_maxNonphys) scale.X = m_parentScene.m_maxNonphys; @@ -2062,7 +2064,7 @@ namespace OpenSim.Region.Framework.Scenes if (scale.Z > m_parentScene.m_maxNonphys) scale.Z = m_parentScene.m_maxNonphys; - part.Shape.Scale = scale; + part.Scale = scale; } } m_numPrim += children.Length; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ba64878cbb..ffbb7d0100 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -5397,6 +5397,18 @@ namespace OpenSim.Region.Framework.Scenes } } + new public Vector3 OffsetPosition + { + get { return base.OffsetPosition; } + set + { + base.OffsetPosition = value; + UpdateBucketSyncInfo("OffsetPosition"); + } + } + + + new public PrimitiveBaseShape Shape { get { return base.Shape; } @@ -5439,6 +5451,12 @@ namespace OpenSim.Region.Framework.Scenes UpdateBucketSyncInfo("Shape"); } + public override void Resize(Vector3 scale) + { + base.Resize(scale); + UpdateBucketSyncInfo("Scale"); + } + #endregion //new property access functions From 7a331b6a8ff10731a9f5a2f6be82d70a4391c9cc Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Fri, 11 Feb 2011 15:31:13 -0800 Subject: [PATCH 19/22] Switched to use ScheduleFullUpdates() and ScheduleTerseUpdates() as the funnel to catch any property updates, so as to update bucket's sync timestamp correctly. Code good for compilation, runtime not tested yet. --- .../Avatar/Attachments/AttachmentsModule.cs | 5 +- .../ObjectCaps/UploadObjectAssetModule.cs | 3 +- .../EntityTransfer/EntityTransferModule.cs | 3 +- .../InventoryAccess/InventoryAccessModule.cs | 6 +- .../RegionSyncModule/RegionSyncClient.cs | 2 +- .../SceneToScriptEngineConnector.cs | 3 +- .../SymmetricSync/RegionSyncModule.cs | 35 +- .../World/Media/Moap/MoapModule.cs | 10 +- .../World/Objects/BuySell/BuySellModule.cs | 3 +- .../Framework/Interfaces/IRegionSyncModule.cs | 2 +- .../Framework/Scenes/Scene.Inventory.cs | 6 +- .../Framework/Scenes/Scene.PacketHandlers.cs | 5 +- OpenSim/Region/Framework/Scenes/Scene.cs | 6 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 27 +- .../Framework/Scenes/SceneObjectGroup.cs | 54 +- .../Framework/Scenes/SceneObjectPart.cs | 491 +++++++++++------- .../Scenes/SceneObjectPartInventory.cs | 8 +- OpenSim/Region/Framework/Scenes/UndoState.cs | 13 +- .../ContentManagementSystem/CMModel.cs | 3 +- .../TreePopulator/TreePopulatorModule.cs | 3 +- .../Shared/Api/Implementation/LSL_Api.cs | 144 +++-- .../Shared/Api/Implementation/OSSL_Api.cs | 3 +- 22 files changed, 521 insertions(+), 314 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index ff262648e5..0c815d284d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -591,7 +591,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } so.AbsolutePosition = AttachOffset; - so.RootPart.AttachedPos = AttachOffset; + so.RootPart.AttachedPos = AttachOffset; so.RootPart.IsAttachment = true; so.RootPart.SetParentLocalId(avatar.LocalId); @@ -611,7 +611,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } so.IsSelected = false; // fudge.... - so.ScheduleGroupForFullUpdate(); + //so.ScheduleGroupForFullUpdate(); + so.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //just force it to sychronize all properties } // In case it is later dropped again, don't let diff --git a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs index 3114d7ff59..f366b421ee 100644 --- a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs @@ -352,7 +352,8 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps rootGroup.LinkToGroup(allparts[j]); } - rootGroup.ScheduleGroupForFullUpdate(); + //rootGroup.ScheduleGroupForFullUpdate(); + rootGroup.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //seems like new object pos = m_scene.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale(), false); responsedata["int_response_code"] = 200; //501; //410; //404; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index d87f91602f..b7e68d06d3 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1581,7 +1581,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (destination != null && !CrossPrimGroupIntoNewRegion(destination, grp, silent)) { grp.OffsetForNewRegion(oldGroupPosition); - grp.ScheduleGroupForFullUpdate(); + //grp.ScheduleGroupForFullUpdate(); + grp.ScheduleGroupForFullUpdate(SceneObjectPartProperties.Position); } } diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 7bb8789f16..91d8edc24e 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -600,7 +600,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // if not, we set it's position in world. if (!attachment) { - group.ScheduleGroupForFullUpdate(); + //group.ScheduleGroupForFullUpdate(); + group.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //new object float offsetHeight = 0; pos = m_Scene.GetNewRezLocation( @@ -698,7 +699,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); rootPart.ParentGroup.ResumeScripts(); - rootPart.ScheduleFullUpdate(); + //rootPart.ScheduleFullUpdate(); + rootPart.ScheduleFullUpdate(SceneObjectPartProperties.FullUpdate); } if (!m_Scene.Permissions.BypassPermissions()) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs index 3040866e46..bc8e4bac76 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs @@ -321,7 +321,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //RegionSyncMessage.HandleSuccess(LogHeader(), msg, String.Format("Object \"{0}\" ({1}) ({1}) updated.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString())); //else //RegionSyncMessage.HandleSuccess(LogHeader(), msg, String.Format("Object \"{0}\" ({1}) ({1}) added.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString())); - sog.ScheduleGroupForFullUpdate(); + //sog.ScheduleGroupForFullUpdate(); } return; } diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToScriptEngineConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToScriptEngineConnector.cs index 3167d901c4..8024edee2f 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToScriptEngineConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToScriptEngineConnector.cs @@ -550,7 +550,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //the prim is not the root-part, set the offset position primToUpdate.OffsetPosition = pos; parent.HasGroupChanged = true; - parent.ScheduleGroupForTerseUpdate(); + //parent.ScheduleGroupForTerseUpdate(); + parent.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.OffsetPosition); } } diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index a593538ca6..6d9aa3891a 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -181,8 +181,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule get { return m_isSyncRelay; } } - private Dictionary m_primPropertyBucketMap = new Dictionary(); - public Dictionary PrimPropertyBucketMap + private Dictionary m_primPropertyBucketMap = new Dictionary(); + public Dictionary PrimPropertyBucketMap { get { return m_primPropertyBucketMap; } } @@ -225,6 +225,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_propertyBucketDescription.Add(physicsBucketName); m_maxNumOfPropertyBuckets = 2; + /* foreach (string pName in SceneObjectPart.PropertyList) { switch (pName){ @@ -252,6 +253,36 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule break; } } + * */ + + foreach (SceneObjectPartProperties property in Enum.GetValues(typeof(SceneObjectPartProperties))) + { + switch (property) + { + case SceneObjectPartProperties.GroupPosition: + case SceneObjectPartProperties.OffsetPosition: + case SceneObjectPartProperties.Scale: + case SceneObjectPartProperties.Velocity: + case SceneObjectPartProperties.AngularVelocity: + case SceneObjectPartProperties.RotationOffset: + case SceneObjectPartProperties.Position: + case SceneObjectPartProperties.Size: + case SceneObjectPartProperties.Force: + case SceneObjectPartProperties.RotationalVelocity: + case SceneObjectPartProperties.PA_Acceleration: + case SceneObjectPartProperties.Torque: + case SceneObjectPartProperties.Orientation: + case SceneObjectPartProperties.IsPhysical: + case SceneObjectPartProperties.Flying: + case SceneObjectPartProperties.Buoyancy: + m_primPropertyBucketMap.Add(property, physicsBucketName); + break; + default: + //all other properties belong to the "General" bucket. + m_primPropertyBucketMap.Add(property, generalBucketName); + break; + } + } } private bool IsSyncingWithOtherActors() diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs index 7c5d044347..c909c195de 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs @@ -236,7 +236,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap part.Shape.Media[face] = me; UpdateMediaUrl(part, UUID.Zero); - part.ScheduleFullUpdate(); + //part.ScheduleFullUpdate(); + part.ScheduleFullUpdate(SceneObjectPartProperties.MediaUrl); part.TriggerScriptChangedEvent(Changed.MEDIA); } @@ -421,7 +422,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap UpdateMediaUrl(part, agentId); // Arguably, we could avoid sending a full update to the avatar that just changed the texture. - part.ScheduleFullUpdate(); + //part.ScheduleFullUpdate(); + part.ScheduleFullUpdate(SceneObjectPartProperties.Shape); + part.ScheduleFullUpdate(SceneObjectPartProperties.MediaUrl); //not an efficient way to taint two properties, but should not have bad side effects part.TriggerScriptChangedEvent(Changed.MEDIA); @@ -499,7 +502,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap UpdateMediaUrl(part, agentId); - part.ScheduleFullUpdate(); + //part.ScheduleFullUpdate(); + part.ScheduleFullUpdate(SceneObjectPartProperties.MediaUrl); part.TriggerScriptChangedEvent(Changed.MEDIA); diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs index be399ff65b..efa58ef710 100644 --- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs @@ -148,7 +148,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell part.GetProperties(remoteClient); part.TriggerScriptChangedEvent(Changed.OWNER); group.ResumeScripts(); - part.ScheduleFullUpdate(); + //part.ScheduleFullUpdate(); + part.ScheduleFullUpdate(SceneObjectPartProperties.FullUpdate); //quite some properties changed, let's just force all to be synchronized break; diff --git a/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs index 812a98610d..db3fd98e7a 100755 --- a/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs @@ -59,7 +59,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// The mapping of a property (identified by its name) to the index of a bucket. /// - Dictionary PrimPropertyBucketMap { get; } + Dictionary PrimPropertyBucketMap { get; } /// /// The text description of the properties in each bucket, e.g. "General", "Physics" /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index fa81d8c290..510831d0b1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2197,7 +2197,8 @@ namespace OpenSim.Region.Framework.Scenes // to find out if scripts should be activated at all. group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); - group.ScheduleGroupForFullUpdate(); + //group.ScheduleGroupForFullUpdate(); + group.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //new object, all properties have new value return group; } @@ -2262,7 +2263,8 @@ namespace OpenSim.Region.Framework.Scenes { sog.SetOwnerId(ownerID); sog.SetGroup(groupID, remoteClient); - sog.ScheduleGroupForFullUpdate(); + //sog.ScheduleGroupForFullUpdate(); + sog.ScheduleGroupForFullUpdate(SceneObjectPartProperties.OwnerID); SceneObjectPart[] partList = sog.Parts; diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index ab567fbcb0..db8c75f1ca 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -208,11 +208,12 @@ namespace OpenSim.Region.Framework.Scenes // TODO: Make selection flagging per prim! // part.ParentGroup.IsSelected = false; - + if (part.ParentGroup.IsAttachment) isAttachment = true; else - part.ParentGroup.ScheduleGroupForFullUpdate(); + //part.ParentGroup.ScheduleGroupForFullUpdate(); + part.ParentGroup.ScheduleGroupForFullUpdate(SceneObjectPartProperties.IsSelected); // 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 282491b153..af08e7bd9c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2391,7 +2391,8 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.SetGroup(groupID, null); } - sceneObject.ScheduleGroupForFullUpdate(); + //sceneObject.ScheduleGroupForFullUpdate(); + sceneObject.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //new object, all properties have new value return sceneObject; } @@ -4490,7 +4491,8 @@ namespace OpenSim.Region.Framework.Scenes { if (ent is SceneObjectGroup) { - ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(); + //((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(); + ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(SceneObjectPartProperties.None); //This is not due to property being updated, hence passing "None" property. } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index f43e12669f..191ca1aa55 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -383,7 +383,8 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.AttachToScene(m_parentScene); if (sendClientUpdates) - sceneObject.ScheduleGroupForFullUpdate(); + //sceneObject.ScheduleGroupForFullUpdate(); + sceneObject.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None); Entities.Add(sceneObject); @@ -1747,22 +1748,11 @@ namespace OpenSim.Region.Framework.Scenes } //SYMMETRIC SYNC - //set timestamp - /* - long timeStamp = DateTime.Now.Ticks; - string actorID = m_parentScene.GetSyncActorID(); - foreach (SceneObjectGroup sog in afterDelinkGroups) - { - if (m_parentScene.RegionSyncModule != null) - { - sog.SyncInfoUpdate(timeStamp, actorID); ; - } - } - * */ //Send out DelinkObject message to other actors to sychronize their object list - m_parentScene.RegionSyncModule.SendDeLinkObject(prims, beforeDelinkGroups, afterDelinkGroups); - - + if (m_parentScene.RegionSyncModule != null) + { + m_parentScene.RegionSyncModule.SendDeLinkObject(prims, beforeDelinkGroups, afterDelinkGroups); + } //Schedule updates as in legacy OpenSim code, to send updates to viewers connected to this actor (at least needed for client managers). //But timestamp won't be changed, so that when other actors get the update, they's simple ignore the updates since they already get them foreach (SceneObjectGroup sog in afterDelinkGroups) @@ -1905,7 +1895,8 @@ namespace OpenSim.Region.Framework.Scenes copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 1); copy.HasGroupChanged = true; - copy.ScheduleGroupForFullUpdate(); + //copy.ScheduleGroupForFullUpdate(); + copy.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //new object, all property values are new copy.ResumeScripts(); // required for physics to update it's position @@ -1974,7 +1965,7 @@ namespace OpenSim.Region.Framework.Scenes { //if we need to debug the script engine with a viewer attaching to it, //we need to schedule updates to be sent to the viewer - oldSog.ScheduleGroupForFullUpdate(); + oldSog.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None); } } else diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index fc6fa035ea..1cfb0d776c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1022,7 +1022,8 @@ namespace OpenSim.Region.Framework.Scenes RootPart.RemFlag(PrimFlags.TemporaryOnRez); AttachToBackup(); m_scene.EventManager.TriggerParcelPrimCountTainted(); - m_rootPart.ScheduleFullUpdate(); + //m_rootPart.ScheduleFullUpdate(); + m_rootPart.ScheduleFullUpdate(SceneObjectPartProperties.AttachmentPoint); //Physics properties, such as Position, OffsetPosition, etc, should be tainted in ApplyPhysics() m_rootPart.ClearUndoState(); } @@ -1295,7 +1296,8 @@ namespace OpenSim.Region.Framework.Scenes m_scene.RemoveGroupTarget(this); } - ScheduleGroupForFullUpdate(); + //ScheduleGroupForFullUpdate(); + ScheduleGroupForFullUpdate(SceneObjectPartProperties.Flags); } public void SetText(string text, Vector3 color, double alpha) @@ -1307,7 +1309,8 @@ namespace OpenSim.Region.Framework.Scenes Text = text; HasGroupChanged = true; - m_rootPart.ScheduleFullUpdate(); + //m_rootPart.ScheduleFullUpdate(); + m_rootPart.ScheduleFullUpdate(SceneObjectPartProperties.Text); } /// @@ -1541,7 +1544,8 @@ namespace OpenSim.Region.Framework.Scenes dupe.HasGroupChanged = true; dupe.AttachToBackup(); - ScheduleGroupForFullUpdate(); + //ScheduleGroupForFullUpdate(); + ScheduleGroupForFullUpdate(SceneObjectPartProperties.None); //This full-update is triggered by copying, no property changed } return dupe; @@ -1794,7 +1798,8 @@ namespace OpenSim.Region.Framework.Scenes ApplyNextOwnerPermissions(); } - part.ScheduleFullUpdate(); + //part.ScheduleFullUpdate(); + part.ScheduleFullUpdate(SceneObjectPartProperties.OwnerID); } /// @@ -1919,33 +1924,38 @@ namespace OpenSim.Region.Framework.Scenes /// /// Schedule a full update for this scene object /// - public void ScheduleGroupForFullUpdate() + //public void ScheduleGroupForFullUpdate() + public void ScheduleGroupForFullUpdate(SceneObjectPartProperties property) { // if (IsAttachment) // m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, LocalId); checkAtTargets(); - RootPart.ScheduleFullUpdate(); + //RootPart.ScheduleFullUpdate(); + RootPart.ScheduleFullUpdate(property); SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { SceneObjectPart part = parts[i]; if (part != RootPart) - part.ScheduleFullUpdate(); + //part.ScheduleFullUpdate(); + part.ScheduleFullUpdate(property); } } /// /// Schedule a terse update for this scene object /// - public void ScheduleGroupForTerseUpdate() + //public void ScheduleGroupForTerseUpdate() + public void ScheduleGroupForTerseUpdate(SceneObjectPartProperties property) { // m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) - parts[i].ScheduleTerseUpdate(); + //parts[i].ScheduleTerseUpdate(); + parts[i].ScheduleTerseUpdate(property); } /// @@ -2703,7 +2713,8 @@ namespace OpenSim.Region.Framework.Scenes HasGroupChanged = true; part.TriggerScriptChangedEvent(Changed.SCALE); - ScheduleGroupForFullUpdate(); + //ScheduleGroupForFullUpdate(); + ScheduleGroupForFullUpdate(SceneObjectPartProperties.None); //above actions only update Scale for the given part, and part.Resize() will taint Scale as updated //if (part.UUID == m_rootPart.UUID) //{ @@ -2855,7 +2866,8 @@ namespace OpenSim.Region.Framework.Scenes part.StoreUndoState(); HasGroupChanged = true; m_rootPart.TriggerScriptChangedEvent(Changed.SCALE); - ScheduleGroupForTerseUpdate(); + //ScheduleGroupForTerseUpdate(); + ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Scale); } } @@ -2896,7 +2908,8 @@ 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(); + //ScheduleGroupForTerseUpdate(); + ScheduleGroupForTerseUpdate(SceneObjectPartProperties.GroupPosition); } /// @@ -2959,7 +2972,8 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = newPos; HasGroupChanged = true; - ScheduleGroupForTerseUpdate(); + //ScheduleGroupForTerseUpdate(); + ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Position); } public void OffsetForNewRegion(Vector3 offset) @@ -2991,7 +3005,8 @@ namespace OpenSim.Region.Framework.Scenes } HasGroupChanged = true; - ScheduleGroupForTerseUpdate(); + //ScheduleGroupForTerseUpdate(); + ScheduleGroupForTerseUpdate(SceneObjectPartProperties.None); //Above actions only update m_rootPart's RotationOffset, and m_rootPart.UpdateRotation will taint RotationOffset as updated } /// @@ -3017,7 +3032,8 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = pos; HasGroupChanged = true; - ScheduleGroupForTerseUpdate(); + //ScheduleGroupForTerseUpdate(); + ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Position); //RotationOffset is only updated for m_rootPart, and m_rootPart.UpdateRotation should already taint RotationOffset as updated } /// @@ -3104,7 +3120,8 @@ namespace OpenSim.Region.Framework.Scenes Quaternion newRot = primsRot * oldParentRot; newRot *= Quaternion.Inverse(axRot); prim.RotationOffset = newRot; - prim.ScheduleTerseUpdate(); + //prim.ScheduleTerseUpdate(); + prim.ScheduleTerseUpdate(SceneObjectPartProperties.RotationOffset | SceneObjectPartProperties.OffsetPosition); } } @@ -3118,7 +3135,8 @@ namespace OpenSim.Region.Framework.Scenes } } - m_rootPart.ScheduleTerseUpdate(); + //m_rootPart.ScheduleTerseUpdate(); + m_rootPart.ScheduleTerseUpdate(SceneObjectPartProperties.RotationOffset); } #endregion diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ffbb7d0100..3d0f9ce4c8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -311,7 +311,8 @@ namespace OpenSim.Region.Framework.Scenes /// /// TODO - This should be an enumeration /// - private byte m_updateFlag; + //private byte m_updateFlag; + protected byte m_updateFlag; private PhysicsActor m_physActor; protected Vector3 m_acceleration; @@ -352,6 +353,7 @@ namespace OpenSim.Region.Framework.Scenes private bool m_forceMouselook; // TODO: Collision sound should have default. + //private UUID m_collisionSound; protected UUID m_collisionSound; private float m_collisionSoundVolume; @@ -2749,7 +2751,8 @@ namespace OpenSim.Region.Framework.Scenes } //m_parentGroup.RootPart.m_groupPosition = newpos; } - ScheduleTerseUpdate(); + //ScheduleTerseUpdate(); + ScheduleTerseUpdate(SceneObjectPartProperties.Position); //SendTerseUpdateToAllClients(); } @@ -2839,7 +2842,8 @@ namespace OpenSim.Region.Framework.Scenes m_shape.Scale = scale; ParentGroup.HasGroupChanged = true; - ScheduleFullUpdate(); + //ScheduleFullUpdate(); + ScheduleFullUpdate(SceneObjectPartProperties.Scale); } public void RotLookAt(Quaternion target, float strength, float damping) @@ -2881,7 +2885,8 @@ namespace OpenSim.Region.Framework.Scenes /// /// Schedules this prim for a full update /// - public void ScheduleFullUpdate() + //public void ScheduleFullUpdate() :: SYMMETRIC SYNC: changed the interface so that we can identify which property triggers calling this function + public virtual void ScheduleFullUpdate(SceneObjectPartProperties sopProperty) { // m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); @@ -2909,20 +2914,14 @@ 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 } /// /// Schedule a terse update for this prim. Terse updates only send position, /// rotation, velocity, rotational velocity and shape information. /// - public void ScheduleTerseUpdate() + //public void ScheduleTerseUpdate() + public virtual void ScheduleTerseUpdate(SceneObjectPartProperties sopProperty) { if (m_updateFlag < 1) { @@ -2937,13 +2936,6 @@ 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 } } @@ -2981,8 +2973,7 @@ namespace OpenSim.Region.Framework.Scenes } - //public void SculptTextureCallback(UUID textureID, AssetBase texture) - public virtual void SculptTextureCallback(UUID textureID, AssetBase texture) + public void SculptTextureCallback(UUID textureID, AssetBase texture) { if (m_shape.SculptEntry) { @@ -3164,10 +3155,10 @@ namespace OpenSim.Region.Framework.Scenes ClearUpdateSchedule(); //SYMMETRIC SYNC - if (m_parentGroup.Scene.RegionSyncModule == null) - return; - m_parentGroup.Scene.RegionSyncModule.QueueSceneObjectPartForUpdate((SceneObjectPart)this); - + if (m_parentGroup.Scene.RegionSyncModule != null) + { + m_parentGroup.Scene.RegionSyncModule.QueueSceneObjectPartForUpdate((SceneObjectPart)this); + } //end of SYMMETRIC SYNC } @@ -3274,8 +3265,7 @@ namespace OpenSim.Region.Framework.Scenes }); } - //public void SetAttachmentPoint(uint AttachmentPoint) - public virtual void SetAttachmentPoint(uint AttachmentPoint) + public void SetAttachmentPoint(uint AttachmentPoint) { this.AttachmentPoint = AttachmentPoint; @@ -3291,8 +3281,7 @@ namespace OpenSim.Region.Framework.Scenes // save the attachment point. //if (AttachmentPoint != 0) //{ - m_shape.State = (byte)AttachmentPoint; - + m_shape.State = (byte)AttachmentPoint; //} } @@ -3633,14 +3622,16 @@ namespace OpenSim.Region.Framework.Scenes Text = text; ParentGroup.HasGroupChanged = true; - ScheduleFullUpdate(); + //ScheduleFullUpdate(); + ScheduleFullUpdate(SceneObjectPartProperties.Text); } public void StopLookAt() { m_parentGroup.stopLookAt(); - m_parentGroup.ScheduleGroupForTerseUpdate(); + //m_parentGroup.ScheduleGroupForTerseUpdate(); + m_parentGroup.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.None);//in stopLookAt(), PhysicsActor shall already take care of tainting which properties have been updated } /// @@ -3662,7 +3653,8 @@ namespace OpenSim.Region.Framework.Scenes { m_parentGroup.stopMoveToTarget(); - m_parentGroup.ScheduleGroupForTerseUpdate(); + //m_parentGroup.ScheduleGroupForTerseUpdate(); + m_parentGroup.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.None); //in stopMoveToTarget(), PhysicsActor shall already take care of tainting which properties have been updated //m_parentGroup.ScheduleGroupForFullUpdate(); } @@ -4210,8 +4202,8 @@ namespace OpenSim.Region.Framework.Scenes } ParentGroup.HasGroupChanged = true; - ScheduleFullUpdate(); - + //ScheduleFullUpdate(); + ScheduleFullUpdate(SceneObjectPartProperties.Shape); } public void UpdateGroupPosition(Vector3 pos) @@ -4222,7 +4214,8 @@ namespace OpenSim.Region.Framework.Scenes { Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); GroupPosition = newPos; - ScheduleTerseUpdate(); + //ScheduleTerseUpdate(); + ScheduleFullUpdate(SceneObjectPartProperties.GroupPosition); } } @@ -4254,7 +4247,8 @@ namespace OpenSim.Region.Framework.Scenes } OffsetPosition = newPos; - ScheduleTerseUpdate(); + //ScheduleTerseUpdate(); + ScheduleFullUpdate(SceneObjectPartProperties.OffsetPosition); } } @@ -4543,7 +4537,8 @@ 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(); + //ScheduleFullUpdate(); + ScheduleFullUpdate(SceneObjectPartProperties.Flags); } public void UpdateRotation(Quaternion rot) @@ -4555,7 +4550,8 @@ namespace OpenSim.Region.Framework.Scenes { RotationOffset = rot; ParentGroup.HasGroupChanged = true; - ScheduleTerseUpdate(); + //ScheduleTerseUpdate(); + ScheduleFullUpdate(SceneObjectPartProperties.RotationOffset); } } @@ -4563,8 +4559,7 @@ namespace OpenSim.Region.Framework.Scenes /// Update the shape of this part. /// /// - //public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock) - public virtual void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock) + public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock) { m_shape.PathBegin = shapeBlock.PathBegin; m_shape.PathEnd = shapeBlock.PathEnd; @@ -4601,7 +4596,8 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.HasGroupChanged = true; TriggerScriptChangedEvent(Changed.SHAPE); - ScheduleFullUpdate(); + //ScheduleFullUpdate(); + ScheduleFullUpdate(SceneObjectPartProperties.Shape); } /// @@ -4639,8 +4635,7 @@ namespace OpenSim.Region.Framework.Scenes /// Update the texture entry for this part. /// /// - //public void UpdateTextureEntry(byte[] textureEntry) - public virtual void UpdateTextureEntry(byte[] textureEntry) + public void UpdateTextureEntry(byte[] textureEntry) { m_shape.TextureEntry = textureEntry; TriggerScriptChangedEvent(Changed.TEXTURE); @@ -4649,7 +4644,8 @@ namespace OpenSim.Region.Framework.Scenes //This is madness.. //ParentGroup.ScheduleGroupForFullUpdate(); //This is sparta - ScheduleFullUpdate(); + //ScheduleFullUpdate(); + ScheduleFullUpdate(SceneObjectPartProperties.Shape); } public void aggregateScriptEvents() @@ -4717,7 +4713,8 @@ 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(); + //ScheduleFullUpdate(); + ScheduleFullUpdate(SceneObjectPartProperties.Flags); return; } @@ -4740,7 +4737,8 @@ namespace OpenSim.Region.Framework.Scenes { // m_log.DebugFormat( // "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents()", Name, LocalId); - ScheduleFullUpdate(); + //ScheduleFullUpdate(); + ScheduleFullUpdate(SceneObjectPartProperties.Flags); } } @@ -4944,44 +4942,6 @@ namespace OpenSim.Region.Framework.Scenes set { m_lastUpdateTimeStamp = value; } } - - /// - /// Schedules this prim for a full update, without changing the timestamp or actorID (info on when and who modified any property). - /// NOTE: this is the same as the original SceneObjectPart.ScheduleFullUpdate(). - /// - public void ScheduleFullUpdate_SyncInfoUnchanged() - { - //m_log.DebugFormat("[SCENE OBJECT PART]: ScheduleFullUpdate_SyncInfoUnchanged 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; - } - else - { - TimeStampFull = (uint)timeNow; - } - - m_updateFlag = 2; - - // m_log.DebugFormat( - // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}", - // UUID, Name, TimeStampFull); - - } - - - #endregion } @@ -5037,6 +4997,164 @@ namespace OpenSim.Region.Framework.Scenes } + /* + public enum SceneObjectPartProperties:ulong + { + //Following properties copied from SceneObjectSerializer(), + AllowedDrop = (ulong) 1<<0, + CreatorID = (ulong) 1<<1, + CreatorData = (ulong) 1 <<2, + FolderID = (ulong) 1 << 3, + InventorySerial = (ulong) 1 << 4, + TaskInventory = (ulong) 1 << 5, + //UUID", + //LocalId", + Name = (ulong) 1 << 6, + Material = (ulong) 1 <<7, + PassTouches = (ulong) 1 << 8, + RegionHandle = (ulong) 1 << 9, + ScriptAccessPin = (ulong) 1 << 10, + GroupPosition = (ulong) 1 << 11, + OffsetPosition = (ulong) 1 << 12, + RotationOffset = (ulong) 1 << 13, + Velocity = (ulong) 1 << 14, + AngularVelocity = (ulong) 1 << 15, + //"Acceleration", + SOP_Acceleration = (ulong) 1 << 16, //SOP and PA read/write their own local copies of acceleration, so we distinguish the copies + Description = (ulong) 1 << 17, + Color = (ulong) 1 << 18, + Text = (ulong) 1 << 19, + SitName = (ulong) 1 << 20, + TouchName = (ulong) 1 << 21, + LinkNum = (ulong) 1 << 22, + ClickAction = (ulong) 1 << 23, + Shape = (ulong) 1 << 24, + Scale = (ulong) 1 << 25, + UpdateFlag = (ulong) 1 << 26, + SitTargetOrientation = (ulong) 1 << 27, + SitTargetPosition = (ulong) 1 << 28, + SitTargetPositionLL = (ulong) 1 << 29, + SitTargetOrientationLL = (ulong) 1 << 30, + ParentID = (ulong)1 << 31, + CreationDate = (ulong) 1 << 32, + Category = (ulong) 1 << 33, + SalePrice = (ulong) 1 << 34, + ObjectSaleType = (ulong) 1 << 35, + OwnershipCost = (ulong) 1 << 36, + GroupID = (ulong) 1 << 37, + OwnerID = (ulong) 1 << 38, + LastOwnerID = (ulong) 1 << 39, + BaseMask = (ulong) 1 << 40, + OwnerMask = (ulong) 1 << 41, + GroupMask = (ulong) 1 << 42, + EveryoneMask = (ulong) 1 << 43, + NextOwnerMask = (ulong) 1 << 44, + Flags = (ulong) 1 << 45, + CollisionSound = (ulong) 1 << 46, + CollisionSoundVolume = (ulong) 1 << 47, + MediaUrl = (ulong) 1 << 48, + TextureAnimation = (ulong) 1 << 49, + ParticleSystem = (ulong) 1 << 50, + //Property names below copied from PhysicsActor, they are necessary in synchronization, but not covered the above properties + //Physics properties "Velocity" is covered above + Position = (ulong) 1 << 51, + Size = (ulong) 1 << 52, + Force = (ulong) 1 << 53, + RotationalVelocity = (ulong) 1 << 54, + PA_Acceleration = (ulong) 1 << 55, + Torque = (ulong) 1 << 56, + Orientation = (ulong) 1 << 57, + IsPhysical = (ulong) 1 << 58, + Flying = (ulong) 1 << 59, + Buoyancy = (ulong) 1 << 60, + //To be handled + AttachmentPoint = (ulong)1 << 61, + FullUpdate = UInt64.MaxValue + } + */ + + public enum SceneObjectPartProperties + { + None, + //Following properties copied from SceneObjectSerializer(), + AllowedDrop , + CreatorID , + CreatorData , + FolderID , + InventorySerial, + TaskInventory, + //UUID", + //LocalId", + Name, + Material, + PassTouches, + RegionHandle, + ScriptAccessPin, + GroupPosition, + OffsetPosition, + RotationOffset, + Velocity, + AngularVelocity, + //"Acceleration", + SOP_Acceleration, //SOP and PA read/write their own local copies of acceleration, so we distinguish the copies + Description, + Color, + Text, + SitName, + TouchName, + LinkNum, + ClickAction, + Shape, + Scale, + UpdateFlag, + SitTargetOrientation, + SitTargetPosition, + SitTargetPositionLL, + SitTargetOrientationLL, + ParentID, + CreationDate, + Category, + SalePrice, + ObjectSaleType, + OwnershipCost, + GroupID, + OwnerID, + LastOwnerID, + BaseMask, + OwnerMask, + GroupMask, + EveryoneMask, + NextOwnerMask, + Flags, + CollisionSound, + CollisionSoundVolume, + MediaUrl, + TextureAnimation, + ParticleSystem, + //Property names below copied from PhysicsActor, they are necessary in synchronization, but not covered the above properties + //Physics properties "Velocity" is covered above + Position, + Size, + Force, + RotationalVelocity, + PA_Acceleration, + Torque, + Orientation, + IsPhysical, + Flying, + Buoyancy, + //To be handled in serialization/deserizaltion for synchronization + IsSelected, + AttachmentPoint, + AttachedPos, + Sound, //This indicates any Sound related property has changed: Sound, SoundGain, SoundFlags,SoundRadius, + //Addition properties to be added here + + //Client Manager may want to add some property here that viewers care about and should be synchronized across actors + + FullUpdate, + } + public class SceneObjectPart : SceneObjectPartBase { @@ -5064,10 +5182,8 @@ namespace OpenSim.Region.Framework.Scenes //TODO: serialization and deserialization processors to be added in SceneObjectSerializer //The following variables are initialized when RegionSyncModule reads the config file for mapping of properties and buckets - private static Dictionary m_primPropertyBucketMap = null; + private static Dictionary m_primPropertyBucketMap = null; private static List m_propertyBucketNames = null; - //private static List m_bucketUpdateLocks = null; - private static Dictionary m_bucketUpdateLocks = new Dictionary(); private static string m_localActorID = ""; //private static int m_bucketCount = 0; @@ -5076,6 +5192,8 @@ namespace OpenSim.Region.Framework.Scenes //private static Dictionary m_bucketUpdateProcessors = new Dictionary(); private Dictionary m_bucketUpdateProcessors = new Dictionary(); + private Dictionary m_bucketUpdateLocks = new Dictionary(); + private Dictionary m_bucketSyncTainted = new Dictionary(); //Define this as a guard to not to fill in any sync info when not desired, i.e. while de-serializing and building SOP and SOG, where //property set functions will be called and might trigger UpdateBucketSyncInfo() if not guarded carefully. @@ -5084,6 +5202,7 @@ namespace OpenSim.Region.Framework.Scenes //The list of each prim's properties. This is the list of properties that matter in synchronizing prim copies on different actors. //This list is created based on properties included in the serialization/deserialization process (see SceneObjectSerializer()) and the //properties Physics Engine needs to synchronize to other actors. + /* public static List PropertyList = new List() { //Following properties copied from SceneObjectSerializer() @@ -5154,9 +5273,10 @@ namespace OpenSim.Region.Framework.Scenes "Flying", "Buoyancy", }; - + * */ - public static void InitializePropertyBucketInfo(Dictionary propertyBucketMap, List bucketNames, string actorID) + + public static void InitializePropertyBucketInfo(Dictionary propertyBucketMap, List bucketNames, string actorID) { m_primPropertyBucketMap = propertyBucketMap; m_propertyBucketNames = bucketNames; @@ -5202,51 +5322,18 @@ namespace OpenSim.Region.Framework.Scenes } } - /// - /// Update the properties of this SOP with the values in updatedPart. - /// - /// - /// - private void GeneralBucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName) { - //NOTE!!!!!!!! Need to cast the local copy to SceneObjectPartBase in order not to trigger UpdateBucketSyncInfo(), - //since the property updates inside this function are not due to local operations. - SceneObjectPartBase localPart = (SceneObjectPartBase)this; - lock (m_bucketUpdateLocks[bucketName]) { - localPart.AllowedDrop = updatedPart.AllowedDrop; - localPart.Shape = updatedPart.Shape; - - bool collisionSoundUpdated = UpdateCollisionSound(updatedPart.CollisionSound); - - - m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp; - m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID; - - if (collisionSoundUpdated) - { - //If the local actor is Script Engine, it will catch this evnet and trigger aggregateScriptEvents() - m_parentGroup.Scene.EventManager.TriggerAggregateScriptEvents(this); - } } } private void PhysicsBucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName) { - //NOTE!!!!!!!! Need to cast the local copy to SceneObjectPartBase in order not to trigger UpdateBucketSyncInfo(), - //since the property updates inside this function are not due to local operations. - SceneObjectPartBase localPart = (SceneObjectPartBase)this; - lock (m_bucketUpdateLocks[bucketName]) { - localPart.GroupPosition = updatedPart.GroupPosition; - - m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp; - m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID; - } } @@ -5279,6 +5366,10 @@ namespace OpenSim.Region.Framework.Scenes { m_bucketUpdateLocks.Add(bucketName, new Object()); } + if (!m_bucketSyncTainted.ContainsKey(bucketName)) + { + m_bucketSyncTainted.Add(bucketName, false); + } } if (!m_BucketUpdateProcessorRegistered) @@ -5290,16 +5381,59 @@ namespace OpenSim.Region.Framework.Scenes m_syncEnabled = true; } + //For tainitng and clearing taints, do i need to lock on m_bucketSyncTaint? + public void TaintBucketSyncInfo(SceneObjectPartProperties property) + { + if (m_syncEnabled && m_bucketSyncTainted.Count > 0) + { + string bucketName = m_primPropertyBucketMap[property]; + m_bucketSyncTainted[bucketName] = true; + } + } + + /* + public void ClearBucketTaint() + { + if (m_syncEnabled && m_bucketSyncTainted.Count > 0) + { + foreach (KeyValuePair pair in m_bucketSyncTainted) + { + pair.Value = false; + } + } + } + * */ + + /// + /// Update the timestamp information of each property bucket, and clear out the taint on each bucket. + /// + public void UpdateTaintedBucketSyncInfo() + { + if (m_syncEnabled) + { + long timeStamp = DateTime.Now.Ticks; + foreach (KeyValuePair pair in m_bucketSyncInfoList) + { + string bucketName = pair.Key; + if (m_bucketSyncTainted[bucketName]) + { + m_bucketSyncInfoList[bucketName].UpdateSyncInfo(timeStamp, m_localActorID); + m_bucketSyncTainted[bucketName] = false; + } + } + } + } + /// /// Update the timestamp and actorID information of the bucket the given property belongs to. /// /// Name of the property. Make sure the spelling is consistent with what are defined in PropertyList - public void UpdateBucketSyncInfo(string propertyName) + public void UpdateBucketSyncInfo(SceneObjectPartProperties property) { if (m_syncEnabled && m_bucketSyncInfoList != null && m_bucketSyncInfoList.Count > 0) { //int bucketIndex = m_primPropertyBucketMap[propertyName]; - string bucketName = m_primPropertyBucketMap[propertyName]; + string bucketName = m_primPropertyBucketMap[property]; long timeStamp = DateTime.Now.Ticks; if (m_bucketSyncInfoList.ContainsKey(bucketName)) { @@ -5312,7 +5446,7 @@ namespace OpenSim.Region.Framework.Scenes } } - + public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart) { @@ -5371,95 +5505,53 @@ namespace OpenSim.Region.Framework.Scenes } - #region new property access functions - //(only properties relevant for synchronization purpose are implemented here) - - new public bool AllowedDrop + public override void ScheduleFullUpdate(SceneObjectPartProperties property) { - get { return base.AllowedDrop; } - set - { - base.AllowedDrop = value; - UpdateBucketSyncInfo("AllowedDrop"); - } + base.ScheduleFullUpdate(property); + TaintBucketSyncInfo(property); + } + + public override void ScheduleTerseUpdate(SceneObjectPartProperties property) + { + base.ScheduleTerseUpdate(property); + TaintBucketSyncInfo(property); } /// - /// The position of the entire group that this prim belongs to. + /// Schedules this prim for a full update, without changing the timestamp or actorID (info on when and who modified any property). + /// NOTE: this is the same as the original SceneObjectPart.ScheduleFullUpdate(). /// - new public Vector3 GroupPosition + public void ScheduleFullUpdate_SyncInfoUnchanged() { - get { return base.GroupPosition; } - set + //m_log.DebugFormat("[SCENE OBJECT PART]: ScheduleFullUpdate_SyncInfoUnchanged for {0} {1}", Name, LocalId); + + if (m_parentGroup != null) { - base.GroupPosition = value; - UpdateBucketSyncInfo("GroupPosition"); + m_parentGroup.QueueForUpdateCheck(); } - } - new public Vector3 OffsetPosition - { - get { return base.OffsetPosition; } - set + 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) { - base.OffsetPosition = value; - UpdateBucketSyncInfo("OffsetPosition"); + TimeStampFull += 1; } - } - - - - new public PrimitiveBaseShape Shape - { - get { return base.Shape; } - set + else { - base.Shape = value; - UpdateBucketSyncInfo("Shape"); + TimeStampFull = (uint)timeNow; } + + m_updateFlag = 2; + + // m_log.DebugFormat( + // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}", + // UUID, Name, TimeStampFull); + } - //For functions that update SOP properties, override them so that when they are called from SOPBase (but the object itself is an instance of SOP) - //the following implementations will be called instead of the same name functions in SOPBase. - public override void SculptTextureCallback(UUID textureID, AssetBase texture) - { - base.SculptTextureCallback(textureID, texture); - UpdateBucketSyncInfo("Shape"); - } - - public override void SetAttachmentPoint(uint AttachmentPoint) - { - base.SetAttachmentPoint(AttachmentPoint); - UpdateBucketSyncInfo("Shape"); - } - - public void UpdateExtraParam(ushort type, bool inUse, byte[] data) - { - base.UpdateExtraParam(type, inUse, data); - UpdateBucketSyncInfo("Shape"); - } - - public override void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock) - { - base.UpdateShape(shapeBlock); - UpdateBucketSyncInfo("Shape"); - } - - public override void UpdateTextureEntry(byte[] textureEntry) - { - base.UpdateTextureEntry(textureEntry); - UpdateBucketSyncInfo("Shape"); - } - - public override void Resize(Vector3 scale) - { - base.Resize(scale); - UpdateBucketSyncInfo("Scale"); - } - - #endregion //new property access functions - - private bool UpdateCollisionSound(UUID updatedCollisionSound) { if (this.CollisionSound != updatedCollisionSound) @@ -5469,7 +5561,6 @@ namespace OpenSim.Region.Framework.Scenes } return false; } - } //end of SYMMETRIC SYNC diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 1d1e66c826..f8509dd017 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -294,7 +294,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.ScheduleFullUpdate(SceneObjectPartProperties.Flags | SceneObjectPartProperties.TaskInventory); return; } @@ -322,7 +322,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.ScheduleFullUpdate(SceneObjectPartProperties.Flags | SceneObjectPartProperties.TaskInventory); } } } @@ -546,7 +546,7 @@ namespace OpenSim.Region.Framework.Scenes m_part.ParentGroup.HasGroupChanged = true; //SYMMETRIC SYNC: add ScheduleFullUpdate to enable synchronization across actors - m_part.ScheduleFullUpdate(); + m_part.ScheduleFullUpdate(SceneObjectPartProperties.TaskInventory | SceneObjectPartProperties.InventorySerial); } /// @@ -766,7 +766,7 @@ namespace OpenSim.Region.Framework.Scenes if (!ContainsScripts()) m_part.RemFlag(PrimFlags.Scripted); - m_part.ScheduleFullUpdate(); + m_part.ScheduleFullUpdate(SceneObjectPartProperties.TaskInventory); return type; diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 55e407ec5f..f325699d7c 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -91,7 +91,8 @@ namespace OpenSim.Region.Framework.Scenes part.RotationOffset = Rotation; if (Scale != Vector3.Zero) part.Resize(Scale); - part.ParentGroup.ScheduleGroupForTerseUpdate(); + //part.ParentGroup.ScheduleGroupForTerseUpdate(); + part.ParentGroup.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Scale); } else { @@ -99,7 +100,8 @@ namespace OpenSim.Region.Framework.Scenes part.OffsetPosition = Position; part.UpdateRotation(Rotation); if (Scale != Vector3.Zero) - part.Resize(Scale); part.ScheduleTerseUpdate(); + part.Resize(Scale); //part.ScheduleTerseUpdate(); + part.ScheduleTerseUpdate(SceneObjectPartProperties.Scale); } part.Undoing = false; @@ -119,7 +121,8 @@ namespace OpenSim.Region.Framework.Scenes part.UpdateRotation(Rotation); if (Scale != Vector3.Zero) part.Resize(Scale); - part.ParentGroup.ScheduleGroupForTerseUpdate(); + //part.ParentGroup.ScheduleGroupForTerseUpdate(); + part.ParentGroup.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Scale); } else { @@ -129,7 +132,9 @@ namespace OpenSim.Region.Framework.Scenes part.UpdateRotation(Rotation); if (Scale != Vector3.Zero) part.Resize(Scale); - part.ScheduleTerseUpdate(); + //part.ScheduleTerseUpdate(); + part.ScheduleTerseUpdate(SceneObjectPartProperties.Scale); + } part.Undoing = false; diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs index 3a6996ef9b..f3847c2bd7 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs @@ -290,7 +290,8 @@ 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).ScheduleGroupForFullUpdate(); + ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //don't know what properties to taint, so just taint all } catch(Exception e) { diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs index 421da3664a..5baf903d6e 100644 --- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs +++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs @@ -640,7 +640,8 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator { s_tree.Scale += copse.m_rate; s_tree.ParentGroup.HasGroupChanged = true; - s_tree.ScheduleFullUpdate(); + //s_tree.ScheduleFullUpdate(); + s_tree.ScheduleFullUpdate(SceneObjectPartProperties.Scale); } } else diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index f713cfa5f4..9fe925a282 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1411,7 +1411,8 @@ 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.ScheduleFullUpdate(); + m_host.ScheduleFullUpdate(SceneObjectPartProperties.ClickAction); return; } @@ -1679,7 +1680,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } part.ParentGroup.HasGroupChanged = true; - part.ScheduleFullUpdate(); + //part.ScheduleFullUpdate(); + part.ScheduleFullUpdate(SceneObjectPartProperties.Shape); } /// @@ -1714,7 +1716,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } part.ParentGroup.HasGroupChanged = true; - part.ScheduleFullUpdate(); + //part.ScheduleFullUpdate(); + part.ScheduleFullUpdate(SceneObjectPartProperties.Shape); } public LSL_Vector llGetColor(int face) @@ -1982,40 +1985,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api targetPos.z = ground; SceneObjectGroup parent = part.ParentGroup; LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); - //KittyL: edited below - if ((World.ScriptEngineToSceneConnectorModule == null)) - { - parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); - } - else - { - object[] valParams = new object[1]; - Vector3 pos = new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z); - valParams[0] = (Vector3)pos; - World.ScriptEngineToSceneConnectorModule.SendSetPrimProperties(m_host.ParentGroup.LocX, m_host.ParentGroup.LocY, m_host.UUID, "pos", (object)valParams); - } + parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); } else { LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); - - //KittyL: edited below - if ((World.ScriptEngineToSceneConnectorModule == null)) - { - part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); - SceneObjectGroup parent = part.ParentGroup; - parent.HasGroupChanged = true; - parent.ScheduleGroupForTerseUpdate(); - } - else - { - object[] valParams = new object[3]; - valParams[0] = (object)rel_vec.x; - valParams[1] = (object)rel_vec.y; - valParams[2] = (object)rel_vec.z; - World.ScriptEngineToSceneConnectorModule.SendSetPrimProperties(m_host.ParentGroup.LocX, m_host.ParentGroup.LocY, m_host.UUID, "pos", (object)valParams); - } - + part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); + SceneObjectGroup parent = part.ParentGroup; + parent.HasGroupChanged = true; + //parent.ScheduleGroupForTerseUpdate(); + parent.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.OffsetPosition); } } @@ -2361,7 +2340,8 @@ 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.ScheduleFullUpdate(); + m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound); m_host.SendFullUpdateToAllClients(); } @@ -2381,7 +2361,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api prim.SoundFlags = 1; // looping prim.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable? - prim.ScheduleFullUpdate(); + //prim.ScheduleFullUpdate(); + m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound); prim.SendFullUpdateToAllClients(); } } @@ -2393,7 +2374,8 @@ 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.ScheduleFullUpdate(); + m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound); m_host.SendFullUpdateToAllClients(); } @@ -2435,7 +2417,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api part.SoundGain = 0; part.SoundFlags = 0; part.SoundRadius = 0; - part.ScheduleFullUpdate(); + //part.ScheduleFullUpdate(); + m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound); part.SendFullUpdateToAllClients(); } m_host.ParentGroup.LoopSoundMasterPrim = null; @@ -2447,7 +2430,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.SoundGain = 0; m_host.SoundFlags = 0; m_host.SoundRadius = 0; - m_host.ScheduleFullUpdate(); + //m_host.ScheduleFullUpdate(); + m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound); m_host.SendFullUpdateToAllClients(); } } @@ -2457,7 +2441,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.SoundGain = 0; m_host.SoundFlags = 0; m_host.SoundRadius = 0; - m_host.ScheduleFullUpdate(); + //m_host.ScheduleFullUpdate(); + m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound); m_host.SendFullUpdateToAllClients(); } } @@ -3384,7 +3369,8 @@ 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.ScheduleTerseUpdate(); + m_host.ScheduleFullUpdate(SceneObjectPartProperties.AngularVelocity); m_host.SendTerseUpdateToAllClients(); m_host.ParentGroup.HasGroupChanged = true; } @@ -3664,7 +3650,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parentPrim.TriggerScriptChangedEvent(Changed.LINK); parentPrim.RootPart.CreateSelected = true; parentPrim.HasGroupChanged = true; - parentPrim.ScheduleGroupForFullUpdate(); + //parentPrim.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 (World.RegionSyncModule != null) + { + //Tell other actors to link the SceneObjectParts together as a new group. + //parentGroup.SyncInfoUpdate(); + World.RegionSyncModule.SendLinkObject(parentPrim, parentPrim.RootPart, new List(childPrim.Parts)); + } + m_host.ScheduleFullUpdate(SceneObjectPartProperties.None); //SendLinkObject above will synchronize the link operation, no need to taint updates here + //end of SYMMETRIC SYNC if (client != null) parentPrim.GetProperties(client); @@ -3722,15 +3719,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (linknum == ScriptBaseClass.LINK_ROOT) { + //SYMMETRIC SYNC + List beforeDelinkGroups = new List(); + beforeDelinkGroups.Add(parentPrim); + List afterDelinkGroups = new List(); + //end of SYMMETRIC SYNC + // Restructuring Multiple Prims. List parts = new List(parentPrim.Parts); parts.Remove(parentPrim.RootPart); foreach (SceneObjectPart part in parts) { parentPrim.DelinkFromGroup(part.LocalId, true); + //SYMMETRIC SYNC + afterDelinkGroups.Add(part.ParentGroup); } parentPrim.HasGroupChanged = true; - parentPrim.ScheduleGroupForFullUpdate(); + //parentPrim.ScheduleGroupForFullUpdate(); + //SYMMETRIC SYNC + //Send out DelinkObject message to other actors to sychronize their object list + if (World.RegionSyncModule != null) + { + World.RegionSyncModule.SendDeLinkObject(parts, beforeDelinkGroups, afterDelinkGroups); + } + parentPrim.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None); + //end of SYMMETRIC SYNC parentPrim.TriggerScriptChangedEvent(Changed.LINK); if (parts.Count > 0) @@ -3743,7 +3756,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api newRoot.ParentGroup.LinkToGroup(part.ParentGroup); } newRoot.ParentGroup.HasGroupChanged = true; - newRoot.ParentGroup.ScheduleGroupForFullUpdate(); + //newRoot.ParentGroup.ScheduleGroupForFullUpdate(); + //SYMMETRIC SYNC + if (World.RegionSyncModule != null) + { + World.RegionSyncModule.SendLinkObject(newRoot.ParentGroup, newRoot, new List(newRoot.ParentGroup.Parts)); + } + newRoot.ParentGroup.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None); + //end of SYMMETRIC SYNC + } } else @@ -3753,7 +3774,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parentPrim.DelinkFromGroup(childPrim.LocalId, true); parentPrim.HasGroupChanged = true; - parentPrim.ScheduleGroupForFullUpdate(); + //parentPrim.ScheduleGroupForFullUpdate(); + //SYMMETRIC SYNC + //Send out DelinkObject message to other actors to sychronize their object list + if (World.RegionSyncModule != null) + { + List beforeDelinkGroups = new List(); + beforeDelinkGroups.Add(parentPrim); + List afterDelinkGroups = new List(); + afterDelinkGroups.Add(childPrim.ParentGroup); + World.RegionSyncModule.SendDeLinkObject(new List(parentPrim.Parts), beforeDelinkGroups, afterDelinkGroups); + } + //end of SYMMETRIC SYNC + parentPrim.TriggerScriptChangedEvent(Changed.LINK); } } @@ -3765,6 +3798,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (parentPrim.RootPart.AttachmentPoint != 0) return; // Fail silently if attached + //SYMMETRIC SYNC + List beforeDelinkGroups = new List(); + beforeDelinkGroups.Add(parentPrim); + List afterDelinkGroups = new List(); + SceneObjectPart rootPart = parentPrim.RootPart; + //end of SYMMETRIC SYNC + List parts = new List(parentPrim.Parts); parts.Remove(parentPrim.RootPart); @@ -3772,9 +3812,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { parentPrim.DelinkFromGroup(part.LocalId, true); parentPrim.TriggerScriptChangedEvent(Changed.LINK); + //SYMMETRIC SYNC + afterDelinkGroups.Add(part.ParentGroup); } parentPrim.HasGroupChanged = true; - parentPrim.ScheduleGroupForFullUpdate(); + //parentPrim.ScheduleGroupForFullUpdate(); + //SYMMETRIC SYNC + if (World.RegionSyncModule != null) + { + parts.Add(rootPart); + afterDelinkGroups.Add(rootPart.ParentGroup); + World.RegionSyncModule.SendDeLinkObject(parts, beforeDelinkGroups, afterDelinkGroups); + } + parentPrim.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None); + //end of SYMMETRIC SYNC } public LSL_String llGetLinkKey(int linknum) @@ -4012,7 +4063,8 @@ 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.ScheduleGroupForFullUpdate(); + m_host.ParentGroup.ScheduleGroupForFullUpdate(SceneObjectPartProperties.Text); } public LSL_Float llWater(LSL_Vector offset) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index c0c790dd28..6bf95bf1e5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2349,7 +2349,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api obj.ParentGroup.HasGroupChanged = true; - obj.ScheduleFullUpdate(); + //obj.ScheduleFullUpdate(); + obj.ScheduleFullUpdate(SceneObjectPartProperties.Shape); } From f47c301a56e72fe8b7d133d7b7e47922800b4518 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Fri, 11 Feb 2011 16:23:03 -0800 Subject: [PATCH 20/22] Added SOP.HasPropertyUpdatedLocally() to help enqueue the right set of objects that have properties updated locally. Also, in RegionSyncModule.SendSceneUpdates, added calling sog.UpdateTaintedBucketSyncInfo() to update timestamp of a tainted property bucket. --- .../SymmetricSync/RegionSyncModule.cs | 9 ++++++ .../Framework/Scenes/SceneObjectGroup.cs | 7 +++++ .../Framework/Scenes/SceneObjectPart.cs | 31 +++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index 6d9aa3891a..4012666bf7 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -298,6 +298,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule if (!updated) { + /* foreach (KeyValuePair pair in part.BucketSyncInfoList) { if (pair.Value.LastUpdateActorID.Equals(m_actorID)) @@ -306,6 +307,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule break; } } + * */ + if (part.HasPropertyUpdatedLocally()) + { + updated = true; + } } if(updated) @@ -368,6 +374,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule if (primUpdates != null || presenceUpdates != null) { + long timeStamp = DateTime.Now.Ticks; + // This could be another thread for sending outgoing messages or just have the Queue functions // create and queue the messages directly into the outgoing server thread. System.Threading.ThreadPool.QueueUserWorkItem(delegate @@ -380,6 +388,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule foreach (SceneObjectGroup sog in primUpdates) { //If this is a relay node, or at least one part of the object has the last update caused by this actor, then send the update + sog.UpdateTaintedBucketSyncInfo(timeStamp); if (m_isSyncRelay || (!sog.IsDeleted && CheckObjectForSendingUpdate(sog))) { //send diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 1cfb0d776c..d81f4b08c0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -4104,6 +4104,13 @@ namespace OpenSim.Region.Framework.Scenes } + public void UpdateTaintedBucketSyncInfo(long timeStamp) + { + foreach (SceneObjectPart part in Parts) + { + part.UpdateTaintedBucketSyncInfo(timeStamp); + } + } #endregion } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 3d0f9ce4c8..3bb83d72dd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -5391,6 +5391,18 @@ namespace OpenSim.Region.Framework.Scenes } } + public bool HasPropertyUpdatedLocally() + { + bool updatedLocally = false; + foreach (KeyValuePair pair in m_bucketSyncTainted) + { + updatedLocally = pair.Value; + if (updatedLocally) + break; + } + return updatedLocally; + } + /* public void ClearBucketTaint() { @@ -5424,6 +5436,25 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// Update the timestamp information of each property bucket, and clear out the taint on each bucket. + /// + public void UpdateTaintedBucketSyncInfo(long timeStamp) + { + if (m_syncEnabled) + { + foreach (KeyValuePair pair in m_bucketSyncInfoList) + { + string bucketName = pair.Key; + if (m_bucketSyncTainted[bucketName]) + { + m_bucketSyncInfoList[bucketName].UpdateSyncInfo(timeStamp, m_localActorID); + m_bucketSyncTainted[bucketName] = false; + } + } + } + } + /// /// Update the timestamp and actorID information of the bucket the given property belongs to. /// From 63e35d53f7df840142ab121fb66c965ae83dba25 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Fri, 11 Feb 2011 16:51:38 -0800 Subject: [PATCH 21/22] Added implementation of GeneralBucketUpdateProcessor and PhysicsBucketUpdateProcessor --- .../Framework/Scenes/SceneObjectPart.cs | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 3bb83d72dd..4fa893ab29 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -5324,16 +5324,115 @@ namespace OpenSim.Region.Framework.Scenes private void GeneralBucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName) { + //If needed, we could define new set functions for these properties, and cast this SOP to SOPBase to + //invoke the set functions in SOPBase + //SceneObjectPartBase localPart = (SceneObjectPartBase)this; + SceneObjectPart localPart = this; + bool collisionSoundUpdated = false; + lock (m_bucketUpdateLocks[bucketName]) { + //See SceneObjectSerializer for the properties that are included in a serialized SceneObjectPart. + localPart.AllowedDrop = updatedPart.AllowedDrop; + localPart.CreatorID = updatedPart.CreatorID; + localPart.CreatorData = updatedPart.CreatorData; + localPart.FolderID = updatedPart.FolderID; + localPart.InventorySerial = updatedPart.InventorySerial; + localPart.TaskInventory = updatedPart.TaskInventory; + //Following two properties, UUID and LocalId, shall not be updated. + //localPart.UUID + //localPart.LocalId + localPart.Name = updatedPart.Name; + localPart.Material = updatedPart.Material; + localPart.PassTouches = updatedPart.PassTouches; + //RegionHandle shall not be copied, since updatedSog is sent by a different actor, which has a different local region + //localPart.RegionHandle + localPart.ScriptAccessPin = updatedPart.ScriptAccessPin; + + localPart.Description = updatedPart.Description; + localPart.Color = updatedPart.Color; + localPart.Text = updatedPart.Text; + localPart.SitName = updatedPart.SitName; + localPart.TouchName = updatedPart.TouchName; + localPart.LinkNum = updatedPart.LinkNum; + localPart.ClickAction = updatedPart.ClickAction; + localPart.Shape = updatedPart.Shape; + localPart.Scale = updatedPart.Scale; + localPart.UpdateFlag = updatedPart.UpdateFlag; + localPart.SitTargetOrientation = updatedPart.SitTargetOrientation; + localPart.SitTargetPosition = updatedPart.SitTargetPosition; + localPart.SitTargetPositionLL = updatedPart.SitTargetPositionLL; + localPart.SitTargetOrientationLL = updatedPart.SitTargetOrientationLL; + //ParentID should still point to the rootpart in the local sog, do not update. If the root part changed, we will update it in SceneObjectGroup.UpdateObjectProperties() + //localPart.ParentID; + localPart.CreationDate = updatedPart.CreationDate; + localPart.Category = updatedPart.Category; + localPart.SalePrice = updatedPart.SalePrice; + localPart.ObjectSaleType = updatedPart.ObjectSaleType; + localPart.OwnershipCost = updatedPart.OwnershipCost; + localPart.GroupID = updatedPart.GroupID; + localPart.OwnerID = updatedPart.OwnerID; + localPart.LastOwnerID = updatedPart.LastOwnerID; + localPart.BaseMask = updatedPart.BaseMask; + localPart.OwnerMask = updatedPart.OwnerMask; + localPart.GroupMask = updatedPart.GroupMask; + localPart.EveryoneMask = updatedPart.EveryoneMask; + localPart.NextOwnerMask = updatedPart.NextOwnerMask; + localPart.Flags = updatedPart.Flags; + //We will update CollisionSound with special care so that it does not lead to ScheduleFullUpdate of this part, to make the actor think it just made an update and + //need to propogate that update to other actors. + //localPart.CollisionSound = updatedPart.CollisionSound; + collisionSoundUpdated = UpdateCollisionSound(updatedPart.CollisionSound); + + localPart.CollisionSoundVolume = updatedPart.CollisionSoundVolume; + localPart.MediaUrl = updatedPart.MediaUrl; + localPart.TextureAnimation = updatedPart.TextureAnimation; + localPart.ParticleSystem = updatedPart.ParticleSystem; + + m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp; + m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID; + + if (collisionSoundUpdated) + { + //If the local actor is Script Engine, it will catch this evnet and trigger aggregateScriptEvents() + m_parentGroup.Scene.EventManager.TriggerAggregateScriptEvents(this); + } } } private void PhysicsBucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName) { + //If needed, we could define new set functions for these properties, and cast this SOP to SOPBase to + //invoke the set functions in SOPBase + //SceneObjectPartBase localPart = (SceneObjectPartBase)this; + SceneObjectPart localPart = this; + lock (m_bucketUpdateLocks[bucketName]) { + localPart.GroupPosition = updatedPart.GroupPosition; + localPart.OffsetPosition = updatedPart.OffsetPosition; + localPart.Scale = updatedPart.Scale; + localPart.Velocity = updatedPart.Velocity; + localPart.AngularVelocity = updatedPart.AngularVelocity; + localPart.RotationOffset = updatedPart.RotationOffset; + //properties in Physics bucket whose update processors are in PhysicsActor + /* + "Position": + "Size": + "Force": + "RotationalVelocity": + "PA_Acceleration": + "Torque": + "Orientation": + "IsPhysical": + "Flying": + "Buoyancy": + * */ + + m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp; + m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID; + } } From 411fa60b2b17f59103f40159557ac5246a627943 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Mon, 14 Feb 2011 11:33:57 -0800 Subject: [PATCH 22/22] RegionSyncModule.SendLinkObject and SendLinkObject now call BucketSyncInfoUpdate() for the linked/delinked objects, to make sure they have updated timestamp information for synchronization purpose. --- .../SymmetricSync/RegionSyncModule.cs | 9 +++++++++ OpenSim/Region/Framework/Scenes/SceneGraph.cs | 1 - .../Region/Framework/Scenes/SceneObjectGroup.cs | 8 +++++--- .../Region/Framework/Scenes/SceneObjectPart.cs | 15 ++++++++++++++- .../Shared/Api/Implementation/LSL_Api.cs | 2 +- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index 4012666bf7..e683e2d1bb 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -515,6 +515,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule return; } + //First, make sure the linked group has updated timestamp info for synchronization + linkedGroup.BucketSyncInfoUpdate(); + OSDMap data = new OSDMap(); string sogxml = SceneObjectSerializer.ToXml2Format(linkedGroup); data["linkedGroup"]=OSD.FromString(sogxml); @@ -573,6 +576,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule groupNum++; } + //make sure the newly delinked objects have the updated timestamp information + foreach (SceneObjectGroup sog in afterDelinkGroups) + { + sog.BucketSyncInfoUpdate(); + } + SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.DelinkObject, OSDParser.SerializeJsonString(data)); SendDelinkObjectToRelevantSyncConnectors(beforeDelinkGroups, rsm); } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 191ca1aa55..96a7075942 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1601,7 +1601,6 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentScene.RegionSyncModule != null) { //Tell other actors to link the SceneObjectParts together as a new group. - //parentGroup.SyncInfoUpdate(); m_parentScene.RegionSyncModule.SendLinkObject(parentGroup, root, children); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index d81f4b08c0..d4a7d1099e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -4046,17 +4046,19 @@ namespace OpenSim.Region.Framework.Scenes } - /* - public void SyncInfoUpdate() + + public void BucketSyncInfoUpdate() { long timeStamp = DateTime.Now.Ticks; string actorID = m_scene.GetSyncActorID(); foreach (SceneObjectPart part in Parts) { - part.SyncInfoUpdate(timeStamp, actorID); + //part.SyncInfoUpdate(timeStamp, actorID); + part.UpdateAllBucketSyncInfo(timeStamp); } } + /* public void SyncInfoUpdate(long timeStamp, string actorID) { foreach (SceneObjectPart part in Parts) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 4fa893ab29..89f68b6058 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -5576,7 +5576,20 @@ namespace OpenSim.Region.Framework.Scenes } } - + public void UpdateAllBucketSyncInfo(long timeStamp) + { + if (m_syncEnabled) + { + foreach (KeyValuePair pair in m_bucketSyncInfoList) + { + string bucketName = pair.Key; + BucketSyncInfo syncInfo= pair.Value; + syncInfo.UpdateSyncInfo(timeStamp, m_localActorID); + m_bucketSyncTainted[bucketName] = false; + } + } + } + public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 9fe925a282..664813b20d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3817,7 +3817,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } parentPrim.HasGroupChanged = true; //parentPrim.ScheduleGroupForFullUpdate(); - //SYMMETRIC SYNC + //SYMMETRIC SYNCF if (World.RegionSyncModule != null) { parts.Add(rootPart);