Added code to send and receive SymmetricSyncMessage.MsgType.UpdatedBucketProperties sync message.

dsg
Huaiyu (Kitty) Liu 2011-02-15 14:02:53 -08:00
parent 7229aa204e
commit 94e433315e
4 changed files with 225 additions and 163 deletions

View File

@ -200,9 +200,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//private object m_updateSceneObjectPartLock = new object();
//private Dictionary<UUID, SceneObjectGroup> m_primUpdates = new Dictionary<UUID, SceneObjectGroup>();
private Dictionary<string, Object> m_primUpdateLocks = new Dictionary<string, object>();
private Dictionary<string, Dictionary<UUID, SceneObjectGroup>> m_primUpdates = new Dictionary<string, Dictionary<UUID, SceneObjectGroup>>();
private Dictionary<string, Dictionary<UUID, SceneObjectPart>> m_primUpdates = new Dictionary<string, Dictionary<UUID, SceneObjectPart>>();
private delegate void PrimUpdatePerBucketSender(SceneObjectGroup sog, string bucketName);
private delegate void PrimUpdatePerBucketSender(string bucketName, List<SceneObjectPart> primUpdates);
private Dictionary<string,PrimUpdatePerBucketSender> m_primUpdatesPerBucketSender = new Dictionary<string,PrimUpdatePerBucketSender>();
private object m_updateScenePresenceLock = new object();
@ -222,18 +222,60 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
private void PrimUpdatesGeneralBucketSender(SceneObjectGroup sog, string bucketName)
//As of current version, we still use the xml serialization as most of SOP's properties are in the General bucket.
//Going forward, we may serialize the properties differently, e.g. using OSDMap
private void PrimUpdatesGeneralBucketSender(string bucketName, List<SceneObjectPart> primUpdates)
{
sog.UpdateTaintedBucketSyncInfo(bucketName, DateTime.Now.Ticks); //this update the timestamp and clear the taint info of the bucket
string sogxml = SceneObjectSerializer.ToXml2Format(sog);
SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedObject, sogxml);
SendObjectUpdateToRelevantSyncConnectors(sog, syncMsg);
Dictionary<UUID, SceneObjectGroup> updatedObjects = new Dictionary<UUID, SceneObjectGroup>();
foreach (SceneObjectPart part in primUpdates)
{
updatedObjects[part.ParentGroup.UUID] = part.ParentGroup;
}
foreach (SceneObjectGroup sog in updatedObjects.Values)
{
sog.UpdateTaintedBucketSyncInfo(bucketName, DateTime.Now.Ticks); //this update the timestamp and clear the taint info of the bucket
string sogxml = SceneObjectSerializer.ToXml2Format(sog);
SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedObject, sogxml);
SendObjectUpdateToRelevantSyncConnectors(sog, syncMsg);
}
}
private void PrimUpdatesPhysicsBucketSender(SceneObjectGroup sog, string bucketName)
private void PrimUpdatesPhysicsBucketSender(string bucketName, List<SceneObjectPart> primUpdates)
{
foreach (SceneObjectPart updatedPart in primUpdates)
{
updatedPart.UpdateTaintedBucketSyncInfo(bucketName, DateTime.Now.Ticks);
OSDMap data = new OSDMap();
data["UUID"] = OSD.FromUUID(updatedPart.UUID);
data["Bucket"] = OSD.FromString(bucketName);
data["GroupPosition"] = OSD.FromVector3(updatedPart.GroupPosition);
data["OffsetPosition"] = OSD.FromVector3(updatedPart.OffsetPosition);
data["RotationOffset"] = OSD.FromQuaternion(updatedPart.RotationOffset);
data["Velocity"] = OSD.FromVector3(updatedPart.Velocity);
data["Scale"] = OSD.FromVector3(updatedPart.Scale);
//Other properties to be included
/*
"Position":
"Size":
"Force":
"RotationalVelocity":
"PA_Acceleration":
"Torque":
"Orientation":
"IsPhysical":
"Flying":
"Buoyancy":
* */
data["LastUpdateTimeStamp"] = OSD.FromLong(updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp);
data["LastUpdateActorID"] = OSD.FromString(updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID);
SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedBucketProperties, OSDParser.SerializeJsonString(data));
SendObjectUpdateToRelevantSyncConnectors(updatedPart, syncMsg);
}
}
//If nothing configured in the config file, this is the default settings for grouping properties into different bucket
@ -283,7 +325,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//create different lists to keep track which SOP has what properties updated (which bucket of properties)
foreach (string bucketName in m_propertyBucketNames)
{
m_primUpdates.Add(bucketName, new Dictionary<UUID, SceneObjectGroup>());
m_primUpdates.Add(bucketName, new Dictionary<UUID, SceneObjectPart>());
m_primUpdateLocks.Add(bucketName, new Object());
}
}
@ -302,7 +344,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{
lock (m_primUpdateLocks[bucketName])
{
m_primUpdates[bucketName][part.UUID] = part.ParentGroup;
m_primUpdates[bucketName][part.UUID] = part;
}
}
}
@ -339,7 +381,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
//List<SceneObjectGroup> primUpdates=null;
Dictionary<string, List<SceneObjectGroup>> primUpdates = new Dictionary<string,List<SceneObjectGroup>>();
Dictionary<string, List<SceneObjectPart>> primUpdates = new Dictionary<string,List<SceneObjectPart>>();
bool updated = false;
//copy the updated SOG list and clear m_primUpdates for immediately future usage
@ -350,7 +392,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
lock (m_primUpdateLocks[bucketName])
{
updated = true;
primUpdates.Add(bucketName, new List<SceneObjectGroup>(m_primUpdates[bucketName].Values));
primUpdates.Add(bucketName, new List<SceneObjectPart>(m_primUpdates[bucketName].Values));
m_primUpdates[bucketName].Clear();
@ -383,11 +425,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
foreach (string bucketName in m_propertyBucketNames)
{
if (primUpdates[bucketName].Count>0)
if (primUpdates.ContainsKey(bucketName) && primUpdates[bucketName].Count > 0)
{
/*
foreach (SceneObjectGroup sog in primUpdates[bucketName])
{
/*
//If this is a relay node, or at least one part of the object has the last update caused by this actor, then send the update
sog.UpdateTaintedBucketSyncInfo(timeStamp);
if (m_isSyncRelay || (!sog.IsDeleted && CheckObjectForSendingUpdate(sog)))
@ -397,9 +440,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedObject, sogxml);
SendObjectUpdateToRelevantSyncConnectors(sog, syncMsg);
}
* */
m_primUpdatesPerBucketSender[bucketName](sog, bucketName);
}
* */
m_primUpdatesPerBucketSender[bucketName](bucketName, primUpdates[bucketName]);
}
}
/*
@ -778,6 +821,19 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
}
//Object updates are sent by enqueuing into each connector's outQueue.
private void SendObjectUpdateToRelevantSyncConnectors(SceneObjectPart updatedPart, SymmetricSyncMessage syncMsg)
{
List<SyncConnector> syncConnectors = GetSyncConnectorsForObjectUpdates(updatedPart);
foreach (SyncConnector connector in syncConnectors)
{
//string sogxml = SceneObjectSerializer.ToXml2Format(sog);
//SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedObject, sogxml);
connector.EnqueueOutgoingUpdate(updatedPart.UUID, syncMsg.ToBytes());
}
}
private void SendDelinkObjectToRelevantSyncConnectors(List<SceneObjectGroup> beforeDelinkGroups, SymmetricSyncMessage syncMsg)
{
HashSet<int> syncConnectorsSent = new HashSet<int>();
@ -871,6 +927,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
return syncConnectors;
}
private List<SyncConnector> GetSyncConnectorsForObjectUpdates(SceneObjectPart updatedPart)
{
return GetSyncConnectorsForObjectUpdates(updatedPart.ParentGroup);
}
/// <summary>
/// Get the set of SyncConnectors to send certain scene events.
/// </summary>
@ -1341,6 +1402,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//HandleAddNewObject(sog);
return;
}
case SymmetricSyncMessage.MsgType.UpdatedBucketProperties:
{
HandleUpdatedBucketProperties(msg, senderActorID);
return;
}
case SymmetricSyncMessage.MsgType.RemovedObject:
{
HandleRemovedObject(msg, senderActorID);
@ -1428,6 +1494,64 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
}
private void HandleUpdatedBucketProperties(SymmetricSyncMessage msg, string senderActorID)
{
// Get the data from message and error check
OSDMap data = DeserializeMessage(msg);
if (data == null)
{
SymmetricSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
return;
}
UUID partUUID = data["UUID"].AsUUID();
string bucketName = data["Bucket"].AsString();
SceneObjectPart updatedPart = new SceneObjectPart();
updatedPart.GroupPosition = data["GroupPosition"].AsVector3();
updatedPart.OffsetPosition = data["OffsetPosition"].AsVector3();
updatedPart.RotationOffset = data["RotationOffset"].AsQuaternion();
updatedPart.Velocity = data["Velocity"].AsVector3();
updatedPart.AngularVelocity = data["AngularVelocity"].AsVector3();
//Scale is a bit complex, we need to have Shape first -- not a good solution, but leave it as is so that we can move on,
updatedPart.Shape = new PrimitiveBaseShape();
updatedPart.Scale = data["Scale"].AsVector3();
/*
Dictionary<string, Object> updatedProperties = new Dictionary<string, Object>();
updatedProperties.Add("GroupPosition", (Object)data["GroupPosition"].AsVector3());
updatedProperties.Add("OffsetPosition", (Object)data["OffsetPosition"].AsVector3());
updatedProperties.Add("RotationOffset", (Object)data["RotationOffset"].AsQuaternion());
updatedProperties.Add("Velocity", (Object)data["Velocity"].AsVector3());
updatedProperties.Add("AngularVelocity", (Object)data["AngularVelocity"].AsVector3());
updatedProperties.Add("Scale", (Object)data["Scale"].AsVector3());
* */
//Other properties to be included
/*
"Position":
"Size":
"Force":
"RotationalVelocity":
"PA_Acceleration":
"Torque":
"Orientation":
"IsPhysical":
"Flying":
"Buoyancy":
* */
BucketSyncInfo rBucketSyncInfo = new BucketSyncInfo(bucketName);
rBucketSyncInfo.LastUpdateTimeStamp = data["LastUpdateTimeStamp"].AsLong();
rBucketSyncInfo.LastUpdateActorID = data["LastUpdateActorID"].AsString();
updatedPart.BucketSyncInfoList.Add(bucketName, rBucketSyncInfo);
m_scene.UpdateObjectPartBucketProperties(bucketName, partUUID, updatedPart);
}
private void SendTerrainUpdateMessage()
{
string msgData = m_scene.Heightmap.SaveToXmlString();

View File

@ -815,6 +815,12 @@ namespace OpenSim.Region.Framework.Scenes
m_sceneGraph.DelinkObjectsBySync(delinkPrimIDs, beforeDelinkGroupIDs, incomingAfterDelinkGroups);
}
//public ObjectUpdateResult UpdateObjectPartBucketProperties(string bucketName, UUID partUUID, Dictionary<string, Object> updatedProperties, BucketSyncInfo rBucketSyncInfo)
public ObjectUpdateResult UpdateObjectPartBucketProperties(string bucketName, UUID partUUID, SceneObjectPart updatePart)
{
return m_sceneGraph.UpdateObjectPartBucketProperties(bucketName, partUUID, updatePart);
}
#endregion //SYMMETRIC SYNC
public ICapabilitiesModule CapsModule

View File

@ -2429,126 +2429,18 @@ namespace OpenSim.Region.Framework.Scenes
return afterDelinkGroups;
}
/*
* //Initial effort to delink objects by copying from the linksets from remote copy. Too much book-keeping updating work to make sure all details are right.
* //So we switched to letting local actor to apply the same "delink" operation as the remote actor did, and check if the "before-state" and "after-state"
* //agrees.
public void DelinkObjectsBySync(List<UUID> delinkPrimIDs, List<UUID> beforeDelinkGroupIDs, List<SceneObjectGroup> incomingAfterDelinkGroups)
//public Scene.ObjectUpdateResult UpdateObjectPartBucketProperties(string bucketName, UUID partUUID, Dictionary<string, Object> updatedProperties, BucketSyncInfo rBucketSyncInfo)
public Scene.ObjectUpdateResult UpdateObjectPartBucketProperties(string bucketName, UUID partUUID, SceneObjectPart updatedPart)
{
Monitor.Enter(m_updateLock);
try
SceneObjectPart localPart = GetSceneObjectPart(partUUID);
if (localPart == null)
{
Dictionary<UUID, SceneObjectGroup> localBeforeDelinkGroups = new Dictionary<UUID, SceneObjectGroup>();
Dictionary<UUID, SceneObjectPart> delinkPrims = new Dictionary<UUID, SceneObjectPart>();
//get the before-delink-groups, and all the prims to delink
foreach (UUID primID in delinkPrimIDs)
{
SceneObjectPart localPart = GetSceneObjectPart(primID);
if (!delinkPrims.ContainsKey(primID))
{
delinkPrims.Add(primID, localPart);
}
SceneObjectGroup localGroup = localPart.ParentGroup;
if (!localBeforeDelinkGroups.ContainsKey(localGroup.UUID))
{
localBeforeDelinkGroups.Add(localGroup.UUID, localGroup);
}
}
//Next, do some sanity check to see if the local copy agrees with remote copy on the before-link state.
//TODO:: Actions to be taken after detecting conflicts. For now, we just assume the chance that conflict will happen is almost 0.
//First, check if the groups match
if (beforeDelinkGroupIDs.Count != localBeforeDelinkGroups.Count)
{
//detected conflict on editing object groups
m_log.Warn("DelinkObjectsBySync: the # of groups in before-delink-groups is different from the incoming delink message. NEED BETTER CONCURRENCY CONTROL IMPLEMENTATION!!!");
//TODO: further actions
}
else
{
foreach (UUID beforeGroupID in beforeDelinkGroupIDs)
{
if (!localBeforeDelinkGroups.ContainsKey(beforeGroupID))
{
m_log.Warn("DelinkObjectsBySync: the local state of before-delink-groups is different from the incoming delink message. NEED BETTER CONCURRENCY CONTROL IMPLEMENTATION!!!");
}
}
//TODO: further actions
}
//Second, check if the prims match
List<SceneObjectPart> allPrimsInLocalGroups = new List<SceneObjectPart>();
foreach (KeyValuePair<UUID, SceneObjectGroup> pair in localBeforeDelinkGroups)
{
foreach (SceneObjectPart part in pair.Value.Parts)
{
allPrimsInLocalGroups.Add(part);
}
}
if (allPrimsInLocalGroups.Count != delinkPrims.Count)
{
m_log.Warn("DelinkObjectsBySync: the # of prims of before-delink-groups is different from the incoming delink message. NEED BETTER CONCURRENCY CONTROL IMPLEMENTATION!!!");
//TODO: further action
}
foreach (SceneObjectPart part in allPrimsInLocalGroups)
{
if (!delinkPrims.ContainsKey(part.UUID))
{
m_log.Warn("DelinkObjectsBySync: some local prims in before-delink-groups not exist in the incoming delink message. NEED BETTER CONCURRENCY CONTROL IMPLEMENTATION!!!");
//TODO: further action
}
}
//end of sanity checking
//now work with localBeforeDelinkGroups, delinkPrims, and incomingAfterDelinkGroups
List<SceneObjectGroup> localAfterDelinkGroups = new List<SceneObjectGroup>();
List<SceneObjectGroup> remoteOldGroups = new List<SceneObjectGroup>();
List<SceneObjectGroup> remoteNewGroups = new List<SceneObjectGroup>();
foreach (SceneObjectGroup remoteGroup in incomingAfterDelinkGroups)
{
if (localBeforeDelinkGroups.ContainsKey(remoteGroup.UUID))
{
remoteOldGroups.Add(remoteGroup);
}
else
{
remoteNewGroups.Add(remoteGroup);
}
}
//update parts in old groups
foreach (SceneObjectGroup remoteGroupCopy in remoteOldGroups)
{
SceneObjectGroup localGroupCopy = localBeforeDelinkGroups[remoteGroupCopy.UUID];
//update the parts in local copy with those in the remote copy
}
//add new groups
}
finally
{
Monitor.Exit(m_updateLock);
m_log.Warn("No SOP found: UUID -- " + partUUID);
return Scene.ObjectUpdateResult.Unchanged;
}
return localPart.UpdateBucketProperties(bucketName, updatedPart);
}
//update the parts in local copy with those in the updated copy
private void UpdatePartsInGroup(SceneObjectGroup localGroup, SceneObjectGroup updatedGroup)
{
//caller of this function should already lock on m_updateLock, hence no locking here
foreach (SceneObjectPart part in localGroup.Parts){
}
}
* */
#endregion //SYMMETRIC SYNC
}
}

View File

@ -5209,7 +5209,7 @@ namespace OpenSim.Region.Framework.Scenes
//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>();
//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.
@ -5481,12 +5481,6 @@ namespace OpenSim.Region.Framework.Scenes
{
m_bucketUpdateLocks.Add(bucketName, new Object());
}
/*
if (!m_bucketSyncTainted.ContainsKey(bucketName))
{
m_bucketSyncTainted.Add(bucketName, false);
}
* */
}
if (!m_BucketUpdateProcessorRegistered)
@ -5501,11 +5495,24 @@ namespace OpenSim.Region.Framework.Scenes
//For tainitng and clearing taints, do i need to lock on m_bucketSyncTaint?
public void TaintBucketSyncInfo(SceneObjectPartProperties property)
{
if (m_syncEnabled && m_bucketSyncTainted.Count > 0)
if (m_syncEnabled)
{
string bucketName = m_primPropertyBucketMap[property];
//m_bucketSyncTainted[bucketName] = true;
m_bucketSyncInfoList[bucketName].TaintBucket();
if (property == SceneObjectPartProperties.None)
return;
if (property == SceneObjectPartProperties.FullUpdate)
{
foreach (BucketSyncInfo bucketSynInfo in m_bucketSyncInfoList.Values)
{
bucketSynInfo.TaintBucket();
}
}
else
{
string bucketName = m_primPropertyBucketMap[property];
//m_bucketSyncTainted[bucketName] = true;
m_bucketSyncInfoList[bucketName].TaintBucket();
}
}
}
@ -5516,19 +5523,6 @@ namespace OpenSim.Region.Framework.Scenes
}
/*
public void ClearBucketTaint()
{
if (m_syncEnabled && m_bucketSyncTainted.Count > 0)
{
foreach (KeyValuePair<string, bool> pair in m_bucketSyncTainted)
{
pair.Value = false;
}
}
}
* */
/// <summary>
/// Update the timestamp information of each property bucket, and clear out the taint on each bucket.
/// </summary>
@ -5540,10 +5534,9 @@ namespace OpenSim.Region.Framework.Scenes
foreach (KeyValuePair<string, BucketSyncInfo> pair in m_bucketSyncInfoList)
{
string bucketName = pair.Key;
if (m_bucketSyncTainted[bucketName])
if (m_bucketSyncInfoList[bucketName].Tainted)
{
m_bucketSyncInfoList[bucketName].UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
//m_bucketSyncTainted[bucketName] = false;
}
}
}
@ -5562,7 +5555,7 @@ namespace OpenSim.Region.Framework.Scenes
foreach (KeyValuePair<string, BucketSyncInfo> pair in m_bucketSyncInfoList)
{
string bucketName = pair.Key;
if (m_bucketSyncTainted[bucketName])
if (m_bucketSyncInfoList[bucketName].Tainted)
{
m_bucketSyncInfoList[bucketName].UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
}
@ -5574,10 +5567,9 @@ namespace OpenSim.Region.Framework.Scenes
{
if (m_syncEnabled)
{
if (m_bucketSyncTainted[bucketName])
if (m_bucketSyncInfoList[bucketName].Tainted)
{
m_bucketSyncInfoList[bucketName].UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
//m_bucketSyncTainted[bucketName] = false;
}
}
}
@ -5613,12 +5605,10 @@ namespace OpenSim.Region.Framework.Scenes
string bucketName = pair.Key;
BucketSyncInfo syncInfo= pair.Value;
syncInfo.UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
m_bucketSyncTainted[bucketName] = false;
}
}
}
public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart)
{
@ -5653,8 +5643,9 @@ namespace OpenSim.Region.Framework.Scenes
if (!m_bucketSyncInfoList[bucketName].LastUpdateActorID.Equals(updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID))
{
m_log.Warn("Different actors modified SceneObjetPart " + UUID + " with the same TimeStamp (" + m_bucketSyncInfoList[bucketName].LastUpdateActorID
+ "," + updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID + ", CONFLICT RESOLUTION TO BE IMPLEMENTED!!!!");
+ "," + updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID + ", CONFLICT RESOLUTION TO BE IMPLEMENTED, PICK A WINNER!!!!");
}
//TODO: conflict resolution to be implemented -- pick a winner
continue;
}
@ -5676,6 +5667,55 @@ namespace OpenSim.Region.Framework.Scenes
}
/// <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, SceneObjectPart updatedPart)
{
Scene.ObjectUpdateResult partUpdateResult = Scene.ObjectUpdateResult.Unchanged;
if (updatedPart.BucketSyncInfoList.ContainsKey(bucketName))
{
m_log.Warn("No bucket named " + bucketName + " found in the copy of updatedPart in UpdateBucketProperties");
return partUpdateResult;
}
BucketSyncInfo rBucketSyncInfo = updatedPart.BucketSyncInfoList[bucketName];
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("Different actors modified SceneObjetPart " + UUID + " 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;
}
public override void ScheduleFullUpdate(List<SceneObjectPartProperties> updatedProperties)
{
foreach (SceneObjectPartProperties property in updatedProperties)