Added code to send and receive SymmetricSyncMessage.MsgType.UpdatedBucketProperties sync message.
parent
7229aa204e
commit
94e433315e
|
@ -200,9 +200,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
//private object m_updateSceneObjectPartLock = new object();
|
//private object m_updateSceneObjectPartLock = new object();
|
||||||
//private Dictionary<UUID, SceneObjectGroup> m_primUpdates = new Dictionary<UUID, SceneObjectGroup>();
|
//private Dictionary<UUID, SceneObjectGroup> m_primUpdates = new Dictionary<UUID, SceneObjectGroup>();
|
||||||
private Dictionary<string, Object> m_primUpdateLocks = new Dictionary<string, object>();
|
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 Dictionary<string,PrimUpdatePerBucketSender> m_primUpdatesPerBucketSender = new Dictionary<string,PrimUpdatePerBucketSender>();
|
||||||
|
|
||||||
private object m_updateScenePresenceLock = new object();
|
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
|
Dictionary<UUID, SceneObjectGroup> updatedObjects = new Dictionary<UUID, SceneObjectGroup>();
|
||||||
string sogxml = SceneObjectSerializer.ToXml2Format(sog);
|
foreach (SceneObjectPart part in primUpdates)
|
||||||
SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedObject, sogxml);
|
{
|
||||||
SendObjectUpdateToRelevantSyncConnectors(sog, syncMsg);
|
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
|
//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)
|
//create different lists to keep track which SOP has what properties updated (which bucket of properties)
|
||||||
foreach (string bucketName in m_propertyBucketNames)
|
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());
|
m_primUpdateLocks.Add(bucketName, new Object());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,7 +344,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
{
|
{
|
||||||
lock (m_primUpdateLocks[bucketName])
|
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;
|
//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;
|
bool updated = false;
|
||||||
//copy the updated SOG list and clear m_primUpdates for immediately future usage
|
//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])
|
lock (m_primUpdateLocks[bucketName])
|
||||||
{
|
{
|
||||||
updated = true;
|
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();
|
m_primUpdates[bucketName].Clear();
|
||||||
|
|
||||||
|
@ -383,11 +425,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
|
|
||||||
foreach (string bucketName in m_propertyBucketNames)
|
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])
|
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
|
//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);
|
sog.UpdateTaintedBucketSyncInfo(timeStamp);
|
||||||
if (m_isSyncRelay || (!sog.IsDeleted && CheckObjectForSendingUpdate(sog)))
|
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);
|
SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedObject, sogxml);
|
||||||
SendObjectUpdateToRelevantSyncConnectors(sog, syncMsg);
|
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)
|
private void SendDelinkObjectToRelevantSyncConnectors(List<SceneObjectGroup> beforeDelinkGroups, SymmetricSyncMessage syncMsg)
|
||||||
{
|
{
|
||||||
HashSet<int> syncConnectorsSent = new HashSet<int>();
|
HashSet<int> syncConnectorsSent = new HashSet<int>();
|
||||||
|
@ -871,6 +927,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
return syncConnectors;
|
return syncConnectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<SyncConnector> GetSyncConnectorsForObjectUpdates(SceneObjectPart updatedPart)
|
||||||
|
{
|
||||||
|
return GetSyncConnectorsForObjectUpdates(updatedPart.ParentGroup);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the set of SyncConnectors to send certain scene events.
|
/// Get the set of SyncConnectors to send certain scene events.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1341,6 +1402,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
//HandleAddNewObject(sog);
|
//HandleAddNewObject(sog);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case SymmetricSyncMessage.MsgType.UpdatedBucketProperties:
|
||||||
|
{
|
||||||
|
HandleUpdatedBucketProperties(msg, senderActorID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
case SymmetricSyncMessage.MsgType.RemovedObject:
|
case SymmetricSyncMessage.MsgType.RemovedObject:
|
||||||
{
|
{
|
||||||
HandleRemovedObject(msg, senderActorID);
|
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()
|
private void SendTerrainUpdateMessage()
|
||||||
{
|
{
|
||||||
string msgData = m_scene.Heightmap.SaveToXmlString();
|
string msgData = m_scene.Heightmap.SaveToXmlString();
|
||||||
|
|
|
@ -815,6 +815,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_sceneGraph.DelinkObjectsBySync(delinkPrimIDs, beforeDelinkGroupIDs, incomingAfterDelinkGroups);
|
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
|
#endregion //SYMMETRIC SYNC
|
||||||
|
|
||||||
public ICapabilitiesModule CapsModule
|
public ICapabilitiesModule CapsModule
|
||||||
|
|
|
@ -2429,126 +2429,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return afterDelinkGroups;
|
return afterDelinkGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//public Scene.ObjectUpdateResult UpdateObjectPartBucketProperties(string bucketName, UUID partUUID, Dictionary<string, Object> updatedProperties, BucketSyncInfo rBucketSyncInfo)
|
||||||
/*
|
public Scene.ObjectUpdateResult UpdateObjectPartBucketProperties(string bucketName, UUID partUUID, SceneObjectPart updatedPart)
|
||||||
* //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)
|
|
||||||
{
|
{
|
||||||
Monitor.Enter(m_updateLock);
|
SceneObjectPart localPart = GetSceneObjectPart(partUUID);
|
||||||
try
|
if (localPart == null)
|
||||||
{
|
{
|
||||||
Dictionary<UUID, SceneObjectGroup> localBeforeDelinkGroups = new Dictionary<UUID, SceneObjectGroup>();
|
m_log.Warn("No SOP found: UUID -- " + partUUID);
|
||||||
Dictionary<UUID, SceneObjectPart> delinkPrims = new Dictionary<UUID, SceneObjectPart>();
|
return Scene.ObjectUpdateResult.Unchanged;
|
||||||
|
|
||||||
//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);
|
|
||||||
}
|
}
|
||||||
|
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
|
#endregion //SYMMETRIC SYNC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5209,7 +5209,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
//private static Dictionary<string, BucketUpdateProcessor> m_bucketUpdateProcessors = new Dictionary<string, BucketUpdateProcessor>();
|
//private static Dictionary<string, BucketUpdateProcessor> m_bucketUpdateProcessors = new Dictionary<string, BucketUpdateProcessor>();
|
||||||
private 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, 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
|
//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.
|
//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());
|
m_bucketUpdateLocks.Add(bucketName, new Object());
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (!m_bucketSyncTainted.ContainsKey(bucketName))
|
|
||||||
{
|
|
||||||
m_bucketSyncTainted.Add(bucketName, false);
|
|
||||||
}
|
|
||||||
* */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_BucketUpdateProcessorRegistered)
|
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?
|
//For tainitng and clearing taints, do i need to lock on m_bucketSyncTaint?
|
||||||
public void TaintBucketSyncInfo(SceneObjectPartProperties property)
|
public void TaintBucketSyncInfo(SceneObjectPartProperties property)
|
||||||
{
|
{
|
||||||
if (m_syncEnabled && m_bucketSyncTainted.Count > 0)
|
if (m_syncEnabled)
|
||||||
{
|
{
|
||||||
string bucketName = m_primPropertyBucketMap[property];
|
if (property == SceneObjectPartProperties.None)
|
||||||
//m_bucketSyncTainted[bucketName] = true;
|
return;
|
||||||
m_bucketSyncInfoList[bucketName].TaintBucket();
|
|
||||||
|
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>
|
/// <summary>
|
||||||
/// Update the timestamp information of each property bucket, and clear out the taint on each bucket.
|
/// Update the timestamp information of each property bucket, and clear out the taint on each bucket.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -5540,10 +5534,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
foreach (KeyValuePair<string, BucketSyncInfo> pair in m_bucketSyncInfoList)
|
foreach (KeyValuePair<string, BucketSyncInfo> pair in m_bucketSyncInfoList)
|
||||||
{
|
{
|
||||||
string bucketName = pair.Key;
|
string bucketName = pair.Key;
|
||||||
if (m_bucketSyncTainted[bucketName])
|
if (m_bucketSyncInfoList[bucketName].Tainted)
|
||||||
{
|
{
|
||||||
m_bucketSyncInfoList[bucketName].UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
|
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)
|
foreach (KeyValuePair<string, BucketSyncInfo> pair in m_bucketSyncInfoList)
|
||||||
{
|
{
|
||||||
string bucketName = pair.Key;
|
string bucketName = pair.Key;
|
||||||
if (m_bucketSyncTainted[bucketName])
|
if (m_bucketSyncInfoList[bucketName].Tainted)
|
||||||
{
|
{
|
||||||
m_bucketSyncInfoList[bucketName].UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
|
m_bucketSyncInfoList[bucketName].UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
|
||||||
}
|
}
|
||||||
|
@ -5574,10 +5567,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
if (m_syncEnabled)
|
if (m_syncEnabled)
|
||||||
{
|
{
|
||||||
if (m_bucketSyncTainted[bucketName])
|
if (m_bucketSyncInfoList[bucketName].Tainted)
|
||||||
{
|
{
|
||||||
m_bucketSyncInfoList[bucketName].UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
|
m_bucketSyncInfoList[bucketName].UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
|
||||||
//m_bucketSyncTainted[bucketName] = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5613,12 +5605,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
string bucketName = pair.Key;
|
string bucketName = pair.Key;
|
||||||
BucketSyncInfo syncInfo= pair.Value;
|
BucketSyncInfo syncInfo= pair.Value;
|
||||||
syncInfo.UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
|
syncInfo.UpdateSyncInfoAndClearTaint(timeStamp, m_localActorID);
|
||||||
m_bucketSyncTainted[bucketName] = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart)
|
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))
|
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
|
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;
|
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)
|
public override void ScheduleFullUpdate(List<SceneObjectPartProperties> updatedProperties)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPartProperties property in updatedProperties)
|
foreach (SceneObjectPartProperties property in updatedProperties)
|
||||||
|
|
Loading…
Reference in New Issue