Removed Bucket Sync code from SceneObjectPart. Bucket Sync should be gone now.

dsg
Huaiyu (Kitty) Liu 2011-05-11 16:42:38 -07:00
parent 6c945ae38f
commit ef66b29e95
6 changed files with 10 additions and 971 deletions

View File

@ -207,22 +207,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
get { return m_propertyBucketNames; }
}
public void QueueSceneObjectPartForUpdate(SceneObjectPart part)
{
foreach (string bucketName in m_propertyBucketNames)
{
if(!part.ParentGroup.IsDeleted && HaveUpdatesToSendoutForSync(part, bucketName))
{
lock (m_primUpdateLocks[bucketName])
{
m_primUpdates[bucketName][part.UUID] = part;
}
}
}
}
public void QueueScenePresenceForTerseUpdate(ScenePresence presence)
{
lock (m_updateScenePresenceLock)
@ -773,20 +757,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//}
}
}
}
private bool HaveUpdatesToSendoutForSync(SceneObjectPart part, string bucketName)
{
if (m_isSyncRelay)
{
return (part.HasPropertyUpdatedLocally(bucketName) || part.HasPropertyUpdatedBySync(bucketName));
}
else
{
return part.HasPropertyUpdatedLocally(bucketName);
}
}
}
private bool IsSyncingWithOtherSyncNodes()
{
@ -956,15 +927,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
private HashSet<SyncConnector> GetSyncConnectorsForPrimUpdates(SceneObjectPart updatedPart)
{
/*
Vector3 globalPos = updatedPart.GroupPosition;
if (CoordinatesConversionHandler != null)
{
bool inComingMsg = false; //this function should only be triggered by trying to send messages out
globalPos = CoordinatesConversionHandler(globalPos, inComingMsg);
}
return m_syncConnectorManager.GetSyncConnectorsByPosition(globalPos);
* */
HashSet<SyncConnector> syncConnectors = new HashSet<SyncConnector>(GetSyncConnectorsForObjectUpdates(updatedPart.ParentGroup));
return syncConnectors;
}
@ -1541,15 +1503,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
return;
}
case SymmetricSyncMessage.MsgType.NewObject:
//HandleAddNewObject(msg, senderActorID);
HandleSyncNewObject(msg, senderActorID);
break;
case SymmetricSyncMessage.MsgType.UpdatedPrimProperties:
HandleUpdatedPrimProperties(msg, senderActorID);
break;
case SymmetricSyncMessage.MsgType.UpdatedObject:
{
//HandleUpdateObjectBySynchronization(msg, senderActorID);
{
HandleUpdatedObject(msg, senderActorID);
return;
}
@ -1636,14 +1596,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{
SendSpecialObjectUpdateToRelevantSyncConnectors(senderActorID, globalPos, msg);
}
/*
if (!m_syncQuarkManager.IsPosInSyncQuarks(globalPos))
{
m_log.WarnFormat("{0}: Received an update for object at global pos {1}, not within local quarks, ignore the update", LogHeader, globalPos.ToString());
return;
}
* */
AddNewSceneObjectByDecoding(data);
@ -1694,12 +1646,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
List<SceneObjectPartSyncProperties> propertiesUpdated = m_primSyncInfoManager.UpdatePrimSyncInfoBySync(sop, propertiesSyncInfo);
//SYNC DEBUG
/*
if (propertiesUpdated.Contains(SceneObjectPartSyncProperties.AggregateScriptEvents))
{
//m_log.DebugFormat("AggregateScriptEvents updated: " + sop.AggregateScriptEvents);
}
/*
if (propertiesUpdated.Contains(SceneObjectPartSyncProperties.Shape))
{
String hashedShape = Util.Md5Hash((PropertySerializer.SerializeShape(sop)));
@ -1902,45 +1854,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
}
private void HandleUpdateObjectBySynchronization(SymmetricSyncMessage msg, string senderActorID)
{
string sogxml = Encoding.ASCII.GetString(msg.Data, 0, msg.Length);
SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml);
lock (m_stats) m_statSOGBucketIn++;
if (sog.IsDeleted)
{
SymmetricSyncMessage.HandleTrivial(LogHeader, msg, String.Format("Ignoring update on deleted object, UUID: {0}.", sog.UUID));
return;
}
else
{
//m_log.Debug(LogHeader + "HandleUpdateObjectBySynchronization: sog " + sog.Name + "," + sog.UUID);
Scene.ObjectUpdateResult updateResult = m_scene.UpdateObjectBySynchronization(sog);
/*
switch (updateResult)
{
case Scene.ObjectUpdateResult.New:
m_log.DebugFormat("[{0} Object \"{1}\" ({1}) ({2}) added.", LogHeader, sog.Name, sog.UUID.ToString(), sog.LocalId.ToString());
break;
case Scene.ObjectUpdateResult.Updated:
m_log.DebugFormat("[{0} Object \"{1}\" ({1}) ({2}) updated.", LogHeader, sog.Name, sog.UUID.ToString(), sog.LocalId.ToString());
break;
case Scene.ObjectUpdateResult.Error:
m_log.WarnFormat("[{0} Object \"{1}\" ({1}) ({2}) -- add or update ERROR.", LogHeader, sog.Name, sog.UUID.ToString(), sog.LocalId.ToString());
break;
case Scene.ObjectUpdateResult.Unchanged:
//m_log.DebugFormat("[{0} Object \"{1}\" ({1}) ({2}) unchanged after receiving an update.", LogHeader, sog.Name, sog.UUID.ToString(), sog.LocalId.ToString());
break;
}
* */
}
}
/// <summary>
/// Send out a sync message about the updated Terrain. If this is a relay node,
/// forward the sync message to all connectors except the one which initiated
@ -2824,13 +2737,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
data["UUID"] = OSD.FromUUID(sog.UUID);
Vector3 globalPos = sog.AbsolutePosition;
/*
if (CoordinatesConversionHandler != null)
{
bool inComingMsg = false;
globalPos = CoordinatesConversionHandler(globalPos, inComingMsg);
}
* */
data["GroupPosition"] = OSDMap.FromVector3(globalPos);
HashSet<SceneObjectPartSyncProperties> fullPropertyList = new HashSet<SceneObjectPartSyncProperties>() { SceneObjectPartSyncProperties.FullUpdate };
@ -2842,9 +2748,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
data["RootPart"] = m_primSyncInfoManager.EncodePrimProperties(sog.RootPart, fullPropertyList);
//int otherPartsCount = sog.Parts.Length - 1;
//data["OtherPartsCount"] = OSD.FromInteger(otherPartsCount);
OSDArray otherPartsArray = new OSDArray();
foreach (SceneObjectPart part in sog.Parts)
{
@ -2861,9 +2764,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
}
data["OtherParts"] = otherPartsArray;
//string sogxml = SceneObjectSerializer.ToXml2Format(sog);
//SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.NewObject, OSDParser.SerializeJsonString(data));
return data;
}
@ -2960,20 +2860,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
partsPrimSyncInfo[part.UUID].SetGroupProperties(part);
}
//Convert the coordinates if necessary
/*
Vector3 globalPos;
if(data.ContainsKey("GroupPosition"))
globalPos = data["GroupPosition"].AsVector3();
Vector3 localPos = globalPos;
if (CoordinatesConversionHandler != null)
{
bool inComingMsg = true;
localPos = CoordinatesConversionHandler(globalPos, inComingMsg);
}
* */
//sog.AbsolutePosition = localPos;
}
#endregion //Prim Property Sync management
@ -4732,21 +4618,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
break;
case SceneObjectPartSyncProperties.GroupPosition:
/*
if (!part.GroupPosition.Equals(m_propertiesSyncInfo[property].LastUpdateValue))
{
if (lastUpdateByLocalTS > m_propertiesSyncInfo[property].LastUpdateTimeStamp)
{
m_propertiesSyncInfo[property].UpdateSyncInfoByLocal(lastUpdateByLocalTS, syncID, (Object)part.GroupPosition);
propertyUpdatedByLocal = true;
}
else if (lastUpdateByLocalTS < m_propertiesSyncInfo[property].LastUpdateTimeStamp)
{
//overwrite SOP's data
part.GroupPosition = (Vector3)m_propertiesSyncInfo[property].LastUpdateValue;
}
}
* */
propertyUpdatedByLocal = CompareAndUpdateSOPGroupPosition(part, lastUpdateByLocalTS, syncID);
break;
case SceneObjectPartSyncProperties.InventorySerial:
@ -5378,21 +5249,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
break;
case SceneObjectPartSyncProperties.Position:
/*
if (!part.PhysActor.Position.Equals(m_propertiesSyncInfo[property].LastUpdateValue))
{
if (lastUpdateByLocalTS > m_propertiesSyncInfo[property].LastUpdateTimeStamp)
{
m_propertiesSyncInfo[property].UpdateSyncInfoByLocal(lastUpdateByLocalTS, syncID, (Object)part.PhysActor.Position);
propertyUpdatedByLocal = true;
}
else if (lastUpdateByLocalTS < m_propertiesSyncInfo[property].LastUpdateTimeStamp)
{
//overwrite PhysActor's data
part.PhysActor.Position = (Vector3)m_propertiesSyncInfo[property].LastUpdateValue;
}
}
* */
propertyUpdatedByLocal = CompareAndUpdateSOPPosition(part, lastUpdateByLocalTS, syncID);
break;
case SceneObjectPartSyncProperties.RotationalVelocity:

View File

@ -663,10 +663,12 @@ namespace OpenSim.Region.Framework.Scenes
return "";
}
/*
public ObjectUpdateResult UpdateObjectBySynchronization(SceneObjectGroup sog)
{
return m_sceneGraph.UpdateObjectBySynchronization(sog);
}
* */
public void DeleteAllSceneObjectsBySync()
{

View File

@ -2002,6 +2002,7 @@ namespace OpenSim.Region.Framework.Scenes
#region DSG SYNC
/*
public Scene.ObjectUpdateResult UpdateObjectBySynchronization(SceneObjectGroup updatedSog)
{
UUID sogID = updatedSog.UUID;
@ -2032,7 +2033,7 @@ namespace OpenSim.Region.Framework.Scenes
return updateResult;
}
*/
//This is called when an object is added due to receiving a state synchronization message from Scene or an actor. Do similar things as the original AddSceneObject(),
//but call ScheduleGroupForFullUpdate_TimeStampUnchanged() instead, so as not to modify the timestamp or actorID, since the object was not created locally.
public Scene.ObjectUpdateResult AddNewSceneObjectBySync(SceneObjectGroup sceneObject)

View File

@ -3505,6 +3505,7 @@ namespace OpenSim.Region.Framework.Scenes
//NOTE: updates on script content are handled seperately (e.g. user edited the script and saved it) -- SESyncServerOnUpdateScript(), a handler of EventManager.OnUpdateScript
//public void UpdateObjectProperties(SceneObjectGroup updatedSog)
/*
/// <summary>
/// Update the existing copy of the object with updated properties in 'updatedSog'. For now we update
/// all properties. Later on this should be edited to allow only updating a bucket of properties.
@ -3532,14 +3533,6 @@ namespace OpenSim.Region.Framework.Scenes
lock (m_parts.SyncRoot)
{
//update rootpart, if changed
/*
if (m_rootPart.UUID != updatedSog.RootPart.UUID)
{
m_rootPart = updatedSog.RootPart;
rootPartChanged = true;
}
* */
//foreach (KeyValuePair<UUID, SceneObjectPart> pair in updatedSog.Parts)
Dictionary<UUID, SceneObjectPart> remainedParts = new Dictionary<UUID, SceneObjectPart>();
@ -3620,53 +3613,6 @@ namespace OpenSim.Region.Framework.Scenes
//Just to make sure the parts each has the right localID of the rootpart
UpdateParentIDs();
/*
//old code below
foreach (SceneObjectPart updatedPart in updatedSog.Parts)
{
UUID partUUID = updatedPart.UUID;
Scene.ObjectUpdateResult partUpdateResult = Scene.ObjectUpdateResult.Unchanged;
if (HasChildPrim(partUUID))
{
//update the existing part
SceneObjectPart oldPart = GetChildPart(partUUID);
partUpdateResult = oldPart.UpdateAllProperties(updatedPart);
updatedParts.Add(partUUID, updatedPart);
}
else
{
//a new part
//m_parts.Add(partUUID, updatedPart);
AddPart(updatedPart);
partUpdateResult = Scene.ObjectUpdateResult.New;
}
if (partUpdateResult != Scene.ObjectUpdateResult.Unchanged)
{
if (partUpdateResult == Scene.ObjectUpdateResult.New)
groupUpdateResult = Scene.ObjectUpdateResult.Updated;
else
groupUpdateResult = partUpdateResult; //Error or Updated
}
}
//For any parts that are not in the updatesParts (the old parts that are still in updatedSog), delete them.
foreach (SceneObjectPart oldPart in this.Parts)
{
if (!updatedParts.ContainsKey(oldPart.UUID))
{
m_parts.Remove(oldPart.UUID);
partsRemoved = true;
}
}
//Update the rootpart's ID in each non root parts
if (rootPartChanged)
{
UpdateParentIDs();
}
* */
}
//Schedule updates to be sent out, if the local copy has just been updated
@ -3687,6 +3633,7 @@ namespace OpenSim.Region.Framework.Scenes
return groupUpdateResult;
}
*/
public string DebugObjectUpdateResult()
{
@ -3950,130 +3897,11 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary>
/// 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.
/// </summary>
/// <param name="scene"></param>
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();
}
///////////////////////////////////////////////////////////////////////
// Per SOP property based sync
///////////////////////////////////////////////////////////////////////
/// <summary>
/// Update the existing copy of the object with updated properties in 'updatedSog'.
/// </summary>
/// <param name="updatedSog"></param>
/// <returns></returns>
public Scene.ObjectUpdateResult UpdateSOGBySync(SceneObjectGroup updatedSog)
{
//This GroupID check should be done by the actor who initiates the object update
//if (!this.GroupID.Equals(updatedSog.GroupID))
// return Scene.ObjectUpdateResult.Error;
////////////////////////////////////////////////////////////////////////////////////////////////////
//NOTE!!!
//We do not want to simply call SceneObjectGroup.Copy here to clone the object:
//the prims (SceneObjectParts) in updatedSog are different instances than those in the local copy,
//and we want to preserve the references to the prims in this local copy, especially for scripts
//of each prim, where the scripts have references to the local copy. If the local copy is replaced,
//the prims (parts) will be replaces and we need to update all the references that were pointing to
//the previous prims.
////////////////////////////////////////////////////////////////////////////////////////////////////
Scene.ObjectUpdateResult groupUpdateResult = Scene.ObjectUpdateResult.Unchanged;
Dictionary<UUID, SceneObjectPart> updatedParts = new Dictionary<UUID, SceneObjectPart>();
lock (m_parts.SyncRoot)
{
//This function is called by LinkObjectBySync and DelinkObjectBySinc(),
//which should have updated the parts in this SOG, hence should be no need to
//add or remove parts to sync
if (this.PrimCount != updatedSog.PrimCount)
{
m_log.WarnFormat("UpdateSOGBySync: For SOP {0}, local copy has {1} parts, while incoming updated copy has {2} parts. Inconsistent.", this.UUID,
this.PrimCount, updatedSog.PrimCount);
}
//now update properties of the parts
foreach (SceneObjectPart part in this.Parts)
{
Scene.ObjectUpdateResult partUpdateResult = Scene.ObjectUpdateResult.Unchanged;
SceneObjectPart updatedPart = updatedSog.GetChildPart(part.UUID);
if (updatedPart == null)
{
m_log.WarnFormat("UpdateSOGBySync: part {0},{1} exists in local copy, not in incoming updated copy", part.Name, part.UUID);
}
else
{
partUpdateResult = part.UpdateAllProperties(updatedPart);
if (partUpdateResult != Scene.ObjectUpdateResult.Unchanged)
{
groupUpdateResult = partUpdateResult;
}
}
}
//Just to make sure the parts each has the right localID of the rootpart
UpdateParentIDs();
}
//Schedule updates to be sent out, if the local copy has just been updated
//(1) if we are debugging the actor with a viewer attaching to it,
//we need to schedule updates to be sent to the viewer.
//(2) or if we are a relaying node to relay updates, we need to forward the updates.
//NOTE: LastUpdateTimeStamp and LastUpdateActorID should be kept the same as in the received copy of the object.
if (groupUpdateResult == Scene.ObjectUpdateResult.Updated)
{
ScheduleGroupForFullUpdate_SyncInfoUnchanged();
}
//debug the update result
if (groupUpdateResult == Scene.ObjectUpdateResult.Updated)
{
DebugObjectUpdateResult();
}
return groupUpdateResult;
}
#endregion
}
}

View File

@ -4938,86 +4938,6 @@ namespace OpenSim.Region.Framework.Scenes
//DSG 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;
private bool m_bucketLocallyTainted = false; //indicating if the bucket has been tainted by local write operations
private bool m_bucketTaintedBySync = false; //indicating if the bucket has been tainted by remote write operations (propogated by synchronization)
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 bool LocallyTainted
{
get { return m_bucketLocallyTainted; }
}
public bool TaintedBySync
{
get { return m_bucketTaintedBySync; }
}
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 UpdateSyncInfoAndClearTaint(long timeStamp, string actorID)
{
lock (m_updateLock)
{
m_lastUpdateTimeStamp = timeStamp;
m_lastUpdateActorID = actorID;
m_bucketLocallyTainted = false; //clear taint
}
}
public void TaintBucketLocally()
{
lock (m_updateLock)
{
m_bucketLocallyTainted = true;
}
}
public void TaintBucketBySync()
{
m_bucketTaintedBySync = true;
}
public void ClearBucketTaintBySync()
{
m_bucketTaintedBySync = false;
}
}
public enum SceneObjectPartSyncProperties
{
None,
@ -5126,33 +5046,8 @@ namespace OpenSim.Region.Framework.Scenes
{
}
//The following variables should be initialized when this SceneObjectPart is added into the local Scene.
//private List<BucketSyncInfo> SynchronizeUpdatesToScene = null;
//public List<BucketSyncInfo> BucketSyncInfoList
private Dictionary<string, BucketSyncInfo> m_bucketSyncInfoList = new Dictionary<string, BucketSyncInfo>();
public Dictionary<string, BucketSyncInfo> BucketSyncInfoList
{
get { return m_bucketSyncInfoList; }
set { m_bucketSyncInfoList = value; }
}
//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<SceneObjectPartSyncProperties, string> m_primPropertyBucketMap = null;
private static List<string> m_propertyBucketNames = null;
private static string m_localActorID = "";
//private static int m_bucketCount = 0;
//private delegate void BucketUpdateProcessor(int bucketIndex);
private delegate void BucketUpdateProcessor(Object updatedPart, string bucketName);
//private static Dictionary<string, BucketUpdateProcessor> m_bucketUpdateProcessors = new Dictionary<string, BucketUpdateProcessor>();
private Dictionary<string, BucketUpdateProcessor> m_bucketUpdateProcessors = new Dictionary<string, BucketUpdateProcessor>();
private Dictionary<string, Object> m_bucketUpdateLocks = new Dictionary<string, object>();
//private Dictionary<string, bool> m_bucketSyncTainted = new Dictionary<string, bool>();
//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;
#region SceneObjectPartSyncProperties categorization
@ -5262,543 +5157,6 @@ namespace OpenSim.Region.Framework.Scenes
#endregion SceneObjectPartSyncProperties categorization
#region BucketSync
public static void InitializePropertyBucketInfo(Dictionary<SceneObjectPartSyncProperties, string> propertyBucketMap, List<string> bucketNames, string actorID)
{
m_primPropertyBucketMap = propertyBucketMap;
m_propertyBucketNames = bucketNames;
m_localActorID = actorID;
//m_bucketCount = bucketNames.Count;
//RegisterBucketUpdateProcessor();
}
/// <summary>
/// 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.
/// </summary>
//private static void RegisterBucketUpdateProcessor()
private void RegisterBucketUpdateProcessor()
{
foreach (string bucketName in m_propertyBucketNames)
{
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 void GeneralBucketUpdateProcessor(Object updatedPartO, string bucketName)
{
if (!(updatedPartO is SceneObjectPart)) return;
SceneObjectPart updatedPart = (SceneObjectPart)updatedPartO;
//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;
localPart.LocalFlags = updatedPart.LocalFlags;
//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;
bool preIsAttachment = localPart.IsAttachment;
if (!localPart.AttachedAvatar.Equals(updatedPart.AttachedAvatar))
{
localPart.AttachedAvatar = updatedPart.AttachedAvatar;
ScenePresence avatar = m_parentGroup.Scene.GetScenePresence(AttachedAvatar);
localPart.ParentGroup.RootPart.SetParentLocalId(avatar.LocalId);
}
localPart.AttachedPos = updatedPart.AttachedPos;
localPart.SetAttachmentPoint(updatedPart.AttachmentPoint);
//localPart.AttachmentPoint = updatedPart.AttachmentPoint;
//NOTE!!!! IsAttachment can only be set after AttachedAvatar is set, see GroupPosition get function.
//if (!localPart.AttachedAvatar.Equals(UUID.Zero) && updatedPart.IsAttachment)
//{
// localPart.IsAttachment = updatedPart.IsAttachment;
//}
localPart.AggregateScriptEvents = updatedPart.AggregateScriptEvents;
aggregateScriptEventSubscriptions();
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);
}
}
//Schedule updates to be sent out, if the local copy has just been updated
//(1) if we are debugging the actor with a viewer attaching to it,
//we need to schedule updates to be sent to the viewer.
//(2) or if we are a relaying node to relay updates, we need to forward the updates.
//NOTE: Passing null argument to make sure that LastUpdateTimeStamp and LastUpdateActorID of each bucket
// are kept the same as in the received copy of the object.
ScheduleFullUpdate(null);
//Mark the bucket as having been tainted by sync operations
m_bucketSyncInfoList[bucketName].TaintBucketBySync();
}
//NOTE:
//1. Only touch the properties and BucketSyncInfo that is related to
//the given bucketName. Other properties and buckets may not be filled
//at all in "updatedPart".
//2. For GroupPosition and Position properties, if coordinates conversion
// is needed, the caller should have done that already.
private void PhysicsBucketUpdateProcessor(Object updatedPartO, string bucketName)
{
SceneObjectPart localPart = this;
if (updatedPartO is SceneObjectPart)
{
SceneObjectPart updatedPart = (SceneObjectPart)updatedPartO;
localPart.GroupPosition = updatedPart.GroupPosition;
localPart.OffsetPosition = updatedPart.OffsetPosition;
localPart.Scale = updatedPart.Scale;
localPart.Velocity = updatedPart.Velocity;
localPart.AngularVelocity = updatedPart.AngularVelocity;
localPart.RotationOffset = updatedPart.RotationOffset;
//TEMP DEBUG
// m_log.DebugFormat("SceneObjectPart.PhysicsBucketUpdateProcessor called for part {0},{1}, at GroupPos {2}", localPart.Name, localPart.UUID, localPart.GroupPosition);
return;
}
if (!(updatedPartO is OSDMap)) return;
OSDMap data = (OSDMap)updatedPartO;
//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;
PhysicsActor pa = localPart.PhysActor;
//m_log.Debug("Received Physics Bucket updates for " + localPart.Name + ". GroupPosition: " + data["GroupPosition"].AsVector3().ToString()
// + ", Position = " + data["Position"].AsVector3().ToString());
lock (m_bucketUpdateLocks[bucketName])
{
if (data.ContainsKey("GroupPosition"))
localPart.GroupPosition = data["GroupPosition"].AsVector3();
if (data.ContainsKey("OffsetPosition"))
localPart.OffsetPosition = data["OffsetPosition"].AsVector3();
if (data.ContainsKey("Scale"))
localPart.Scale = data["Scale"].AsVector3();
if (data.ContainsKey("Velocity"))
localPart.Velocity = data["Velocity"].AsVector3();
if (data.ContainsKey("AngularVelocity"))
localPart.AngularVelocity = data["AngularVelocity"].AsVector3();
if (data.ContainsKey("RotationOffset"))
localPart.RotationOffset = data["RotationOffset"].AsQuaternion();
//m_log.Debug("Received Physics Bucket updates for " + localPart.Name + ","+localPart.UUID
// + ". GroupPosition: " + data["GroupPosition"].AsVector3().ToString());
if (pa != null)
{
if (data.ContainsKey("Size"))
pa.Size = data["Size"].AsVector3();
if (data.ContainsKey("Position"))
pa.Position = data["Position"].AsVector3();
if (data.ContainsKey("Force"))
pa.Force = data["Force"].AsVector3();
// pa.Velocity = data["Velocity"].AsVector3();
if (data.ContainsKey("RotationalVelocity"))
pa.RotationalVelocity = data["RotationalVelocity"].AsVector3();
if (data.ContainsKey("PA_Acceleration"))
pa.Acceleration = data["PA_Acceleration"].AsVector3();
if (data.ContainsKey("Torque"))
pa.Torque = data["Torque"].AsVector3();
if (data.ContainsKey("Orientation"))
pa.Orientation = data["Orientation"].AsQuaternion();
if (data.ContainsKey("IsPhysical"))
pa.IsPhysical = data["IsPhysical"].AsBoolean();
if (data.ContainsKey("Flying"))
pa.Flying = data["Flying"].AsBoolean();
if (data.ContainsKey("Kinematic"))
pa.Kinematic = data["Kinematic"].AsBoolean();
if (data.ContainsKey("Buoyancy"))
pa.Buoyancy = (float)data["Buoyancy"].AsReal();
if (data.ContainsKey("CollidingGround"))
pa.CollidingGround = data["CollidingGround"].AsBoolean();
if (data.ContainsKey("IsColliding"))
pa.IsColliding = data["IsColliding"].AsBoolean();
// m_log.DebugFormat("{0}: PhysicsBucketUpdateProcessor for {2},{3}. pos={1}", , data["Position"].AsVector3().ToString(), localPart.Name, localPart.UUID);
}
if (data.ContainsKey("LastUpdateTimeStamp"))
m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = data["LastUpdateTimeStamp"].AsLong();
if (data.ContainsKey("LastUpdateActorID"))
m_bucketSyncInfoList[bucketName].LastUpdateActorID = data["LastUpdateActorID"].AsString();
}
//TEMP DEBUG
//m_log.DebugFormat("SceneObjectPart.PhysicsBucketUpdateProcessor called for part {0},{1}, at GroupPos {2}", localPart.Name, localPart.UUID, localPart.GroupPosition);
//Schedule updates to be sent out, if the local copy has just been updated
//(1) if we are debugging the actor with a viewer attaching to it,
//we need to schedule updates to be sent to the viewer.
//(2) or if we are a relaying node to relay updates, we need to forward the updates.
//NOTE: Passing SceneObjectPartProperties.None to make sure that LastUpdateTimeStamp and LastUpdateActorID of each bucket
// are kept the same as in the received copy of the object.
ScheduleFullUpdate(null);
//Mark the bucket as having been tainted by sync operations
m_bucketSyncInfoList[bucketName].TaintBucketBySync();
}
//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)
{
m_log.Error("Bucket Information has not been initilized. Return.");
return;
}
long timeStamp = DateTime.Now.Ticks;
// m_log.Debug("InitializeBucketSyncInfo called at " + timeStamp);
for (int i = 0; i < m_propertyBucketNames.Count; i++)
{
string bucketName = m_propertyBucketNames[i];
//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))
{
BucketSyncInfo syncInfo = new BucketSyncInfo(timeStamp, m_localActorID, bucketName);
m_bucketSyncInfoList.Add(bucketName, syncInfo);
}
if (!m_bucketUpdateLocks.ContainsKey(bucketName))
{
m_bucketUpdateLocks.Add(bucketName, new Object());
}
}
if (!m_BucketUpdateProcessorRegistered)
{
RegisterBucketUpdateProcessor();
m_BucketUpdateProcessorRegistered = true;
}
m_syncEnabled = true;
}
//For tainitng and clearing taints, do i need to lock on m_bucketSyncTaint?
public void TaintBucketSyncInfo(SceneObjectPartSyncProperties property)
{
if (m_syncEnabled)
{
if (property == SceneObjectPartSyncProperties.None)
return;
if (property == SceneObjectPartSyncProperties.FullUpdate)
{
foreach (BucketSyncInfo bucketSynInfo in m_bucketSyncInfoList.Values)
{
bucketSynInfo.TaintBucketLocally();
}
// m_log.DebugFormat("{0}: TaintBucketSyncInfo: FullUpdate", "[SCENE OBJECT PART]");
}
else
{
string bucketName = m_primPropertyBucketMap[property];
//m_bucketSyncTainted[bucketName] = true;
m_bucketSyncInfoList[bucketName].TaintBucketLocally();
// m_log.Debug(this.Name + ": " + property.ToString() + " just changed. Tainted " + bucketName);
// m_log.DebugFormat("{0}: TaintBucketSyncInfo: tainting bucket {1} for {2}",
// "[SCENE OBJECT PART]", bucketName, property.ToString());
}
}
}
public bool HasPropertyUpdatedLocally(string bucketName)
{
return m_bucketSyncInfoList[bucketName].LocallyTainted;
}
public bool HasPropertyUpdatedBySync(string bucketName)
{
return m_bucketSyncInfoList[bucketName].TaintedBySync;
}
/// <summary>
/// Update the timestamp information of each property bucket, and clear out the taint on each bucket.
/// </summary>
public void UpdateTaintedBucketSyncInfo()
{
if (m_syncEnabled)
{
long timeStamp = DateTime.Now.Ticks;
foreach (KeyValuePair<string, BucketSyncInfo> pair in m_bucketSyncInfoList)
{
string bucketName = pair.Key;
if (m_bucketSyncInfoList[bucketName].LocallyTainted)
{
m_bucketSyncInfoList[bucketName].UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
}
}
}
}
/// <summary>
/// Update the timestamp information of each property bucket, and clear out the taint on each bucket. This function won't
/// clear the taints. Caller should clear the taints if needed.
/// </summary>
/// <param name="timeStamp">the timestamp value to be set for any updated bucket</param>
public void UpdateTaintedBucketSyncInfo(long timeStamp)
{
if (m_syncEnabled)
{
foreach (KeyValuePair<string, BucketSyncInfo> pair in m_bucketSyncInfoList)
{
string bucketName = pair.Key;
if (m_bucketSyncInfoList[bucketName].LocallyTainted)
{
m_bucketSyncInfoList[bucketName].UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
}
}
}
}
public void UpdateTaintedBucketSyncInfo(string bucketName, long timeStamp)
{
if (m_syncEnabled)
{
if (m_bucketSyncInfoList[bucketName].LocallyTainted)
{
m_bucketSyncInfoList[bucketName].UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
}
}
}
/// <summary>
/// Update the timestamp and actorID information of the bucket the given property belongs to.
/// </summary>
/// <param name="propertyName">Name of the property. Make sure the spelling is consistent with what are defined in PropertyList</param>
public void UpdateBucketSyncInfo(SceneObjectPartSyncProperties property)
{
if (m_syncEnabled && m_bucketSyncInfoList != null && m_bucketSyncInfoList.Count > 0)
{
//int bucketIndex = m_primPropertyBucketMap[propertyName];
string bucketName = m_primPropertyBucketMap[property];
long timeStamp = DateTime.Now.Ticks;
if (m_bucketSyncInfoList.ContainsKey(bucketName))
{
m_bucketSyncInfoList[bucketName].UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
}
else
{
m_log.Warn("No SyncInfo of bucket (name: " + bucketName + ") found");
}
}
}
public void UpdateAllBucketSyncInfo(long timeStamp)
{
if (m_syncEnabled)
{
foreach (KeyValuePair<string, BucketSyncInfo> pair in m_bucketSyncInfoList)
{
string bucketName = pair.Key;
BucketSyncInfo syncInfo= pair.Value;
syncInfo.UpdateSyncInfoAndClearTaint(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 < m_propertyBucketNames.Count; i++)
{
string bucketName = m_propertyBucketNames[i];
//First, compare the bucket's timestamp and actorID
if (m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp > 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 " + Name+"," +UUID + ", bucket "+bucketName+", with the same TimeStamp ("
+ m_bucketSyncInfoList[bucketName].LastUpdateActorID
+ "," + updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID +
", CONFLICT RESOLUTION TO BE IMPLEMENTED, PICK A WINNER!!!!");
}
//TODO: conflict resolution to be implemented -- pick a winner
continue;
}
//Second, if need to update local properties, call each bucket's update process
if (m_bucketUpdateProcessors.ContainsKey(bucketName))
{
//m_log.Debug("Update properties in " + bucketName + " buckets");
m_bucketUpdateProcessors[bucketName](updatedPart, bucketName);
partUpdateResult = Scene.ObjectUpdateResult.Updated;
}
else
{
m_log.Warn("No update processor for property bucket " + bucketName);
}
}
return partUpdateResult;
}
/// <summary>
/// Update values of property in the given bucket.
/// </summary>
/// <param name="bucketName">The bucket that the properties belong to.</param>
/// <param name="updatedPart">A container of the updated properties. Only the values of the updated properties are set.</param>
/// <param name="rBucketSyncInfo">A copy of the sync info of the bucket on the sender's (who sends out the syn message) side.</param>
/// <returns></returns>
public Scene.ObjectUpdateResult UpdateBucketProperties(string bucketName, Object updatedPart, BucketSyncInfo rBucketSyncInfo)
{
Scene.ObjectUpdateResult partUpdateResult = Scene.ObjectUpdateResult.Unchanged;
if (!m_bucketSyncInfoList.ContainsKey(bucketName))
{
m_log.Error("SceneObjectPart.UpdateBucketProperties: no bucket name " + bucketName + " defined");
return partUpdateResult;
}
if (m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp > rBucketSyncInfo.LastUpdateTimeStamp)
{
//Our timestamp is more update to date, keep our values of the properties. Do not update anything.
return partUpdateResult;
}
if (m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp == rBucketSyncInfo.LastUpdateTimeStamp)
{
if (!m_bucketSyncInfoList[bucketName].LastUpdateActorID.Equals(rBucketSyncInfo.LastUpdateActorID))
{
m_log.Warn("UpdateBucketProperties: Different actors modified SceneObjetPart " + Name + "," + UUID + ", bucket " + bucketName + ", with the same TimeStamp ("
+ m_bucketSyncInfoList[bucketName].LastUpdateActorID
+ "," + rBucketSyncInfo.LastUpdateActorID +
", CONFLICT RESOLUTION TO BE IMPLEMENTED, PICK A WINNER!!!!");
}
//TODO: conflict resolution to be implemented -- pick a winner
return partUpdateResult;
}
m_bucketUpdateProcessors[bucketName](updatedPart, bucketName);
partUpdateResult = Scene.ObjectUpdateResult.Updated;
return partUpdateResult;
}
#endregion BucketSync
#region overridden SOPBase functions
//Implementation of ScheduleFullUpdate and ScheduleTerseUpdate for Bucket
//based synchronization
@ -5892,11 +5250,6 @@ namespace OpenSim.Region.Framework.Scenes
public string DebugObjectPartProperties()
{
string debugMsg = "UUID " + UUID + ", Name " + Name + ", localID " + LocalId;
//debugMsg += ", parentID " + ParentID + ", parentUUID " + ParentUUID;
//foreach (KeyValuePair<string, BucketSyncInfo> pair in m_bucketSyncInfoList)
//{
// debugMsg += ", Bucket " + pair.Key + ": TimeStamp - " + pair.Value.LastUpdateTimeStamp + ", ActorID - " + pair.Value.LastUpdateActorID;
//}
debugMsg += ", AggregateScriptEvents = " + AggregateScriptEvents.ToString() + ", OffsetPosition: " + OffsetPosition;
String hashedShape = Util.Md5Hash(SerializeShape());
debugMsg += ", hashed Shape = " + hashedShape;

View File

@ -1198,7 +1198,6 @@ namespace OpenSim.Region.Framework.Scenes
set
{
base.Serial = value;
//m_part.UpdateBucketSyncInfo("InventorySerial");
}
}
}