Removed Bucket Sync code from SceneObjectPart. Bucket Sync should be gone now.
parent
6c945ae38f
commit
ef66b29e95
|
@ -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)
|
||||
|
@ -775,19 +759,6 @@ 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()
|
||||
{
|
||||
return (m_syncConnectors.Count > 0);
|
||||
|
@ -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,7 +1503,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
return;
|
||||
}
|
||||
case SymmetricSyncMessage.MsgType.NewObject:
|
||||
//HandleAddNewObject(msg, senderActorID);
|
||||
HandleSyncNewObject(msg, senderActorID);
|
||||
break;
|
||||
case SymmetricSyncMessage.MsgType.UpdatedPrimProperties:
|
||||
|
@ -1549,7 +1510,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
break;
|
||||
case SymmetricSyncMessage.MsgType.UpdatedObject:
|
||||
{
|
||||
//HandleUpdateObjectBySynchronization(msg, senderActorID);
|
||||
HandleUpdatedObject(msg, senderActorID);
|
||||
return;
|
||||
}
|
||||
|
@ -1637,14 +1597,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)
|
||||
{
|
||||
|
@ -2862,9 +2765,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:
|
||||
|
|
|
@ -663,10 +663,12 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
public ObjectUpdateResult UpdateObjectBySynchronization(SceneObjectGroup sog)
|
||||
{
|
||||
return m_sceneGraph.UpdateObjectBySynchronization(sog);
|
||||
}
|
||||
* */
|
||||
|
||||
public void DeleteAllSceneObjectsBySync()
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,129 +3897,10 @@ 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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1198,7 +1198,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
set
|
||||
{
|
||||
base.Serial = value;
|
||||
//m_part.UpdateBucketSyncInfo("InventorySerial");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue