From 2f17a9d2241a4ceb3c74ff53798c4cf353422284 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Thu, 7 Apr 2011 15:34:09 -0700 Subject: [PATCH] Added more functions to PrimSyncInfo, and added class PrimSyncInfoManager. Also, commented out a few not sync-relavent properties from SceneObjectPartProperties. --- .../SymmetricSync/RegionSyncModule.cs | 373 +++++++++++++++++- .../Framework/Scenes/SceneObjectPart.cs | 7 +- 2 files changed, 366 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index ade7b4e829..b7d5b03402 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -3194,6 +3194,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule get { return m_lastUpdateValue; } } + private string m_lastUpdateValueHash; + /// /// Record the time the last sync message about this property is received. /// This value is only meaninful when m_lastUpdateSource==BySync @@ -3246,13 +3248,23 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_lastUpdateSource = PropertyUpdateSource.BySync; } } + + public bool IsHashValueEqual(string hashValue) + { + return m_lastUpdateValueHash.Equals(hashValue); + } + + public bool IsValueEqual(Object pValue) + { + return m_lastUpdateValue.Equals(pValue); + } } public class PrimSyncInfo { #region Members public static long TimeOutThreshold; - + private Dictionary m_propertiesSyncInfo; public Dictionary PropertiesSyncInfo { @@ -3264,20 +3276,25 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { get { return m_PrimLastUpdateTime; } } + + private ILog m_log; + private Object m_primSyncInfoLock = new Object(); + #endregion //Members - #region Constructor + #region Constructors public PrimSyncInfo() { - m_propertiesSyncInfo = new Dictionary(); - - foreach (SceneObjectPartProperties property in Enum.GetValues(typeof(SceneObjectPartProperties))) - { - PropertySyncInfo syncInfo = new PropertySyncInfo(); - m_propertiesSyncInfo.Add(property, syncInfo); - } + InitPropertiesSyncInfo(); } - #endregion //Constructor + + public PrimSyncInfo(ILog log) + { + InitPropertiesSyncInfo(); + + m_log = log; + } + #endregion //Constructors public void UpdatePropertySyncInfoLocally(SceneObjectPartProperties property, ulong lastUpdateTS, string syncID, Object pValue) { @@ -3288,6 +3305,342 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { m_propertiesSyncInfo[property].UpdateSyncInfoBySync(lastUpdateTS, syncID, recvTS, pValue); } + + //Triggered when a set of local writes just happened, and ScheduleFullUpdate + //or ScheduleTerseUpdate has been called. + /// + /// Update copies of the given list of properties in this SyncModule, + /// by copying property values from SOP's data and set the timestamp + /// and syncID. + /// + /// + /// + /// + /// + public void UpdatePropertiesByLocal(SceneObjectPart part, List updatedProperties, ulong lastUpdateTS, string syncID) + { + if (part == null) return; + + lock (m_primSyncInfoLock) + { + foreach (SceneObjectPartProperties property in updatedProperties) + { + bool isLocalValueDifferent = false; + bool isFullUpdate = false; + //Compare if the value of the property in this SyncModule is + //different than the value in SOP + switch (property) + { + case SceneObjectPartProperties.None: + break; + case SceneObjectPartProperties.FullUpdate: + //The caller indicates a FullUpdate. Compare values of all + //properties and update if needed. + break; + case SceneObjectPartProperties.Shape: + case SceneObjectPartProperties.TaskInventory: + //Convert the value of complex properties to string and hash + isLocalValueDifferent = CompareHashedValues(part, property); + break; + default: + isLocalValueDifferent = CompareValues(part, property); + break; + } + + if (isFullUpdate) + { + //We should have executed a full update operation above. + //Break the For loop. + break; + } + + if (isLocalValueDifferent) + { + Object pLocalValue = GetPropertyLocalValue(part, property); + UpdatePropertySyncInfoLocally(property, lastUpdateTS, syncID, pLocalValue); + } + } + } + } + + private void InitPropertiesSyncInfo() + { + m_propertiesSyncInfo = new Dictionary(); + + foreach (SceneObjectPartProperties property in Enum.GetValues(typeof(SceneObjectPartProperties))) + { + PropertySyncInfo syncInfo = new PropertySyncInfo(); + m_propertiesSyncInfo.Add(property, syncInfo); + } + } + + private bool CompareHashedValues(SceneObjectPart part, SceneObjectPartProperties property) + { + bool isLocalValueDifferent = false; + switch (property) + { + case SceneObjectPartProperties.Shape: + break; + case SceneObjectPartProperties.TaskInventory: + break; + } + return isLocalValueDifferent; + } + + private bool CompareValues(SceneObjectPart part, SceneObjectPartProperties property) + { + bool isLocalValueDifferent = false; + switch (property) + { + //SOP properties + case SceneObjectPartProperties.AggregateScriptEvents: + return part.AggregateScriptEvents.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.AllowedDrop: + return part.AllowedDrop.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.AngularVelocity: + return part.AngularVelocity.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.AttachedAvatar: + return part.AttachedAvatar.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.AttachedPos: + return part.AttachedPos.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.AttachmentPoint: + return part.AttachmentPoint.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.BaseMask: + return part.BaseMask.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + //PhysActor properties + case SceneObjectPartProperties.Buoyancy: + if(part.PhysActor==null){ + m_log.WarnFormat("PrimSyncInfo: Comparing Values of Buoyancy, yet SOP's PhysActor no longer exsits."); + return true; + } + return part.PhysActor.Buoyancy.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Category: + return part.Category.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.ClickAction: + return part.ClickAction.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.CollisionSound: + return part.CollisionSound.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.CollisionSoundVolume: + return part.CollisionSoundVolume.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Color: + return part.Color.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.CreationDate: + return part.CreationDate.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.CreatorData: + return part.CreatorData.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.CreatorID: + return part.CreatorID.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Description: + return part.Description.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.EveryoneMask: + return part.EveryoneMask.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Flags: + return part.Flags.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Flying: + if (part.PhysActor == null) + { + m_log.WarnFormat("PrimSyncInfo: Comparing Values of Flying, yet SOP's PhysActor no longer exsits."); + return true; + } + return part.PhysActor.Flying.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.FolderID: + return part.FolderID.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Force: + if (part.PhysActor == null) + { + m_log.WarnFormat("PrimSyncInfo: Comparing Values of Force, yet SOP's PhysActor no longer exsits."); + return true; + } + return part.PhysActor.Force.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + //Skip SceneObjectPartProperties.FullUpdate, which should be handled seperatedly + case SceneObjectPartProperties.GroupID: + return part.GroupID.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.GroupMask: + return part.GroupMask.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.GroupPosition: + return part.GroupPosition.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.InventorySerial: + return part.InventorySerial.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.IsAttachment: + return part.IsAttachment.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.IsColliding: + if (part.PhysActor == null) + { + m_log.WarnFormat("PrimSyncInfo: Comparing Values of IsColliding, yet SOP's PhysActor no longer exsits."); + return true; + } + return part.PhysActor.IsColliding.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + /* case SceneObjectPartProperties.IsCollidingGround: + if (part.PhysActor == null) + { + m_log.WarnFormat("PrimSyncInfo: Comparing Values of IsCollidingGround, yet SOP's PhysActor no longer exsits."); + return true; + } + return part.PhysActor.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + * */ + case SceneObjectPartProperties.IsPhysical: + if (part.PhysActor == null) + { + m_log.WarnFormat("PrimSyncInfo: Comparing Values of IsPhysical, yet SOP's PhysActor no longer exsits."); + return true; + } + return part.PhysActor.IsPhysical.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + //SOG properties + case SceneObjectPartProperties.IsSelected: + return part.ParentGroup.IsSelected.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Kinematic: + if (part.PhysActor == null) + { + m_log.WarnFormat("PrimSyncInfo: Comparing Values of Kinematic, yet SOP's PhysActor no longer exsits."); + return true; + } + return part.PhysActor.Kinematic.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.LastOwnerID: + return part.LastOwnerID.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.LinkNum: + return part.LinkNum.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Material: + return part.Material.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.MediaUrl: + return part.MediaUrl.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Name: + return part.Name.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.NextOwnerMask: + return part.NextOwnerMask.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.ObjectSaleType: + return part.ObjectSaleType.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.OffsetPosition: + return part.OffsetPosition.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Orientation: + if (part.PhysActor == null) + { + m_log.WarnFormat("PrimSyncInfo: Comparing Values of Orientation, yet SOP's PhysActor no longer exsits."); + return true; + } + return part.PhysActor.Orientation.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.OwnerID: + return part.OwnerID.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.OwnerMask: + return part.OwnerMask.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.OwnershipCost: + return part.OwnershipCost.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.PA_Acceleration: + if (part.PhysActor == null) + { + m_log.WarnFormat("PrimSyncInfo: Comparing Values of PA.Acceleration, yet SOP's PhysActor no longer exsits."); + return true; + } + return part.PhysActor.Acceleration.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.ParticleSystem: + //return part.ParticleSystem.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + return ByteArrayEquals(part.ParticleSystem, (Byte[])m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.PassTouches: + return part.PassTouches.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Position: + if (part.PhysActor == null) + { + m_log.WarnFormat("PrimSyncInfo: Comparing Values of PA.Position, yet SOP's PhysActor no longer exsits."); + return true; + } + return part.PhysActor.Position.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.RotationalVelocity: + if (part.PhysActor == null) + { + m_log.WarnFormat("PrimSyncInfo: Comparing Values of RotationalVelocity, yet SOP's PhysActor no longer exsits."); + return true; + } + return part.PhysActor.RotationalVelocity.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.RotationOffset: + return part.RotationOffset.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.SalePrice: + return part.SalePrice.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Scale: + return part.Scale.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.ScriptAccessPin: + return part.ScriptAccessPin.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + //case SceneObjectPartProperties.Shape: -- For "Shape", we need to call CompareHashValues + case SceneObjectPartProperties.SitName: + return part.SitName.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.SitTargetOrientation: + return part.SitTargetOrientation.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.SitTargetOrientationLL: + return part.SitTargetOrientationLL.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.SitTargetPosition: + return part.SitTargetPosition.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.SitTargetPositionLL: + return part.SitTargetPositionLL.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Size: + if (part.PhysActor == null) + { + m_log.WarnFormat("PrimSyncInfo: Comparing Values of Size, yet SOP's PhysActor no longer exsits."); + return true; + } + return part.PhysActor.Size.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.SOP_Acceleration: + return part.Acceleration.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Sound: + return part.Sound.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + //case SceneObjectPartProperties.TaskInventory:-- For "TaskInventory", we need to call CompareHashValues + case SceneObjectPartProperties.Text: + return part.Text.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.TextureAnimation: + return ByteArrayEquals(part.TextureAnimation, (Byte[])m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Torque: + if (part.PhysActor == null) + { + m_log.WarnFormat("PrimSyncInfo: Comparing Values of Torque, yet SOP's PhysActor no longer exsits."); + return true; + } + return part.PhysActor.Torque.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.TouchName: + return part.TouchName.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.UpdateFlag: + return part.UpdateFlag.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + case SceneObjectPartProperties.Velocity: + return part.Velocity.Equals(m_propertiesSyncInfo[property].LastUpdateValue); + + } + + return isLocalValueDifferent; + } + + private bool ByteArrayEquals(Byte[] a, Byte[] b) + { + if (a.Length != b.Length) + return false; + for (int i = 0; i < a.Length; i++) + { + if (a[i] != b[i]) + return false; + } + return true; + } + + private Object GetPropertyLocalValue(SceneObjectPart part, SceneObjectPartProperties property) + { + if (part == null) return null; + + return null; + } + } + + public class PrimSyncInfoManager + { + private Dictionary m_primsInSync; + public Dictionary PrimsInSync + { + get { return m_primsInSync; } + } + + public PrimSyncInfoManager() + { + m_primsInSync = new Dictionary(); + } + + public void UpdatePrimSyncInfo(SceneObjectPart part, List updatedProperties) + { + + } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index c49b0fd62d..b684b7d0f8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3204,8 +3204,7 @@ namespace OpenSim.Region.Framework.Scenes //SYMMETRIC SYNC //KittyL: 04/06/2011, No longer calling QueueSceneObjectPartForUpdate - //from here. Local updates are now recorded by calling - //IRegionSyncModule.RecordPrimUpdatesByLocal. + //from here. Local updates are now recorded by calling IRegionSyncModule.RecordPrimUpdatesByLocal(). /* if (m_parentGroup.Scene.RegionSyncModule != null) { @@ -5171,7 +5170,7 @@ namespace OpenSim.Region.Framework.Scenes Name, Material, PassTouches, - RegionHandle, + //RegionHandle, ScriptAccessPin, GroupPosition, OffsetPosition, @@ -5194,7 +5193,7 @@ namespace OpenSim.Region.Framework.Scenes SitTargetPosition, SitTargetPositionLL, SitTargetOrientationLL, - ParentID, + //ParentID, CreationDate, Category, SalePrice,