Added code to include serialization/deserialization of BucketSyncInfoList in each SceneObjectPart.
parent
f36f1010b7
commit
ce4c8e4b6f
|
@ -179,12 +179,16 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
get { return m_isSyncRelay; }
|
get { return m_isSyncRelay; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string, int> m_primPropertyBucketMap = new Dictionary<string, int>();
|
private Dictionary<string, string> m_primPropertyBucketMap = new Dictionary<string, string>();
|
||||||
public Dictionary<string, int> PrimPropertyBucketMap
|
public Dictionary<string, string> PrimPropertyBucketMap
|
||||||
{
|
{
|
||||||
get { return m_primPropertyBucketMap; }
|
get { return m_primPropertyBucketMap; }
|
||||||
}
|
}
|
||||||
public List<string> PropertyBucketDescription = new List<string>();
|
private List<string> m_propertyBucketDescription = new List<string>();
|
||||||
|
public List<string> PropertyBucketDescription
|
||||||
|
{
|
||||||
|
get { return m_propertyBucketDescription; }
|
||||||
|
}
|
||||||
|
|
||||||
private RegionSyncListener m_localSyncListener = null;
|
private RegionSyncListener m_localSyncListener = null;
|
||||||
private bool m_synced = false;
|
private bool m_synced = false;
|
||||||
|
@ -201,21 +205,24 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
//Read in configuration for which property-bucket each property belongs to, and the description of each bucket
|
//Read in configuration for which property-bucket each property belongs to, and the description of each bucket
|
||||||
private void PupolatePropertyBucketMap(IConfig config)
|
private void PupolatePropertyBucketMap(IConfig config)
|
||||||
{
|
{
|
||||||
|
//We start with a default bucket map. Will add the code to read in configuration from config files later.
|
||||||
PupolatePropertyBuketMapByDefault();
|
PupolatePropertyBuketMapByDefault();
|
||||||
|
|
||||||
|
//Pass the bucket information to SceneObjectPart.
|
||||||
|
SceneObjectPart.InitializeBucketInfo(m_primPropertyBucketMap, m_propertyBucketDescription, m_actorID);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//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
|
||||||
private void PupolatePropertyBuketMapByDefault()
|
private void PupolatePropertyBuketMapByDefault()
|
||||||
{
|
{
|
||||||
//by default, there are two property buckets: the "General" bucket and the "Physics" bucket.
|
//by default, there are two property buckets: the "General" bucket and the "Physics" bucket.
|
||||||
PropertyBucketDescription.Add("General");
|
string generalBucketName = "General";
|
||||||
PropertyBucketDescription.Add("Physics");
|
string physicsBucketName = "Physics";
|
||||||
|
m_propertyBucketDescription.Add(generalBucketName);
|
||||||
|
m_propertyBucketDescription.Add(physicsBucketName);
|
||||||
m_maxNumOfPropertyBuckets = 2;
|
m_maxNumOfPropertyBuckets = 2;
|
||||||
|
|
||||||
int generalBucketID = 0;
|
|
||||||
int physicsBucketID = 1;
|
|
||||||
|
|
||||||
foreach (string pName in SceneObjectPart.PropertyList)
|
foreach (string pName in SceneObjectPart.PropertyList)
|
||||||
{
|
{
|
||||||
switch (pName){
|
switch (pName){
|
||||||
|
@ -235,11 +242,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
case "IsPhysical":
|
case "IsPhysical":
|
||||||
case "Flying":
|
case "Flying":
|
||||||
case "Buoyancy":
|
case "Buoyancy":
|
||||||
m_primPropertyBucketMap.Add(pName, physicsBucketID);
|
m_primPropertyBucketMap.Add(pName, generalBucketName);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//all other properties belong to the "General" bucket.
|
//all other properties belong to the "General" bucket.
|
||||||
m_primPropertyBucketMap.Add(pName, generalBucketID);
|
m_primPropertyBucketMap.Add(pName, physicsBucketName);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,15 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
string ActorID { get; }
|
string ActorID { get; }
|
||||||
DSGActorTypes DSGActorType { get; set; }
|
DSGActorTypes DSGActorType { get; set; }
|
||||||
bool IsSyncRelay { get; }
|
bool IsSyncRelay { get; }
|
||||||
Dictionary<string, int> PrimPropertyBucketMap { get; }
|
|
||||||
|
/// <summary>
|
||||||
|
/// The mapping of a property (identified by its name) to the index of a bucket.
|
||||||
|
/// </summary>
|
||||||
|
Dictionary<string, string> PrimPropertyBucketMap { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// The text description of the properties in each bucket, e.g. "General", "Physics"
|
||||||
|
/// </summary>
|
||||||
|
List<string> PropertyBucketDescription { get; }
|
||||||
|
|
||||||
//Enqueue updates for scene-objects and scene-presences
|
//Enqueue updates for scene-objects and scene-presences
|
||||||
void QueueSceneObjectPartForUpdate(SceneObjectPart part);
|
void QueueSceneObjectPartForUpdate(SceneObjectPart part);
|
||||||
|
|
|
@ -579,6 +579,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
|
// 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.
|
// for the same object with very different properties. The caller must schedule the update.
|
||||||
//ScheduleGroupForFullUpdate();
|
//ScheduleGroupForFullUpdate();
|
||||||
|
|
||||||
|
//SYMMETRIC SYNC
|
||||||
|
if (m_scene.RegionSyncClientModule != null)
|
||||||
|
{
|
||||||
|
foreach (SceneObjectPart part in Parts)
|
||||||
|
{
|
||||||
|
part.InitializeBucketSyncInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 GroupScale()
|
public Vector3 GroupScale()
|
||||||
|
|
|
@ -116,6 +116,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
private string m_lastUpdateActorID;
|
private string m_lastUpdateActorID;
|
||||||
//lock for concurrent updates of the timestamp and actorID.
|
//lock for concurrent updates of the timestamp and actorID.
|
||||||
private Object m_updateLock = new Object();
|
private Object m_updateLock = new Object();
|
||||||
|
private string m_bucketName;
|
||||||
|
|
||||||
public long LastUpdateTimeStamp
|
public long LastUpdateTimeStamp
|
||||||
{
|
{
|
||||||
|
@ -127,10 +128,21 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
get { return m_lastUpdateActorID; }
|
get { return m_lastUpdateActorID; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public BucketSyncInfo(long timeStamp, string actorID)
|
public string BucketName
|
||||||
|
{
|
||||||
|
get { return m_bucketName; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public BucketSyncInfo(string bucketName)
|
||||||
|
{
|
||||||
|
m_bucketName = bucketName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BucketSyncInfo(long timeStamp, string actorID, string bucketName)
|
||||||
{
|
{
|
||||||
m_lastUpdateTimeStamp = timeStamp;
|
m_lastUpdateTimeStamp = timeStamp;
|
||||||
m_lastUpdateActorID = actorID;
|
m_lastUpdateActorID = actorID;
|
||||||
|
m_bucketName = bucketName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateSyncInfo(long timeStamp, string actorID)
|
public void UpdateSyncInfo(long timeStamp, string actorID)
|
||||||
|
@ -5096,11 +5108,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
private Object propertyUpdateLock = new Object();
|
private Object propertyUpdateLock = new Object();
|
||||||
|
|
||||||
//!!!!!! -- TODO:
|
//!!!!!! -- TODO:
|
||||||
//!!!!!! -- We should call UpdateXXX functions to update each property, cause some of such updates involves sanity checking.
|
//!!!!!! -- We should call UpdateXXX functions to update each property, cause some of such updates involves sanity checking.
|
||||||
|
|
||||||
public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart)
|
public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart)
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -5223,6 +5236,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
return partUpdateResult;
|
return partUpdateResult;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
private bool UpdateCollisionSound(UUID updatedCollisionSound)
|
private bool UpdateCollisionSound(UUID updatedCollisionSound)
|
||||||
{
|
{
|
||||||
|
@ -5276,34 +5291,170 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//The following three variables should be initialized when this SceneObjectPart is added into the local Scene.
|
//The following variables should be initialized when this SceneObjectPart is added into the local Scene.
|
||||||
private List<BucketSyncInfo> m_bucketSyncInfo = null;
|
//private List<BucketSyncInfo> SynchronizeUpdatesToScene = null;
|
||||||
private Dictionary<string, int> m_primPropertyBucketMap = null;
|
//public List<BucketSyncInfo> BucketSyncInfoList
|
||||||
private string m_localActorID = "";
|
private Dictionary<string, BucketSyncInfo> m_bucketSyncInfoList = null;
|
||||||
|
public Dictionary<string, BucketSyncInfo> BucketSyncInfoList
|
||||||
|
{
|
||||||
|
get { return m_bucketSyncInfoList; }
|
||||||
|
set { m_bucketSyncInfoList = value; }
|
||||||
|
}
|
||||||
|
//TODO: serialization and deserialization processors to be added in SceneObjectSerializer
|
||||||
|
|
||||||
public void InitializeBucketSyncInfo(Dictionary<string, int> propertyBucketMap, string actorID)
|
//The following variables are initialized when RegionSyncModule reads the config file for mapping of properties and buckets
|
||||||
|
private static Dictionary<string, string> m_primPropertyBucketMap = null;
|
||||||
|
private static List<string> m_propertyBucketNames = null;
|
||||||
|
//private static List<Object> m_bucketUpdateLocks = null;
|
||||||
|
private static Dictionary<string, Object> m_bucketUpdateLocks = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
private static string m_localActorID = "";
|
||||||
|
private static int m_bucketCount = 0;
|
||||||
|
//private delegate void BucketUpdateProcessor(int bucketIndex);
|
||||||
|
private delegate void BucketUpdateProcessor(string bucketName);
|
||||||
|
|
||||||
|
private static Dictionary<string, BucketUpdateProcessor> m_bucketUpdateProcessors = new Dictionary<string, BucketUpdateProcessor>();
|
||||||
|
|
||||||
|
public static void InitializeBucketInfo(Dictionary<string, string> propertyBucketMap, List<string> bucketNames, string actorID)
|
||||||
{
|
{
|
||||||
m_primPropertyBucketMap = propertyBucketMap;
|
m_primPropertyBucketMap = propertyBucketMap;
|
||||||
|
m_propertyBucketNames = bucketNames;
|
||||||
m_localActorID = actorID;
|
m_localActorID = actorID;
|
||||||
int bucketNum = propertyBucketMap.Count;
|
m_bucketCount = propertyBucketMap.Count;
|
||||||
long timeStamp = DateTime.Now.Ticks;
|
|
||||||
for (int i = 0; i < bucketNum; i++)
|
RegisterBucketUpdateProcessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Link each bucket with the function that applies updates to properties in the bucket. 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()
|
||||||
|
{
|
||||||
|
foreach (string bucketName in m_propertyBucketNames)
|
||||||
{
|
{
|
||||||
BucketSyncInfo syncInfo = new BucketSyncInfo(timeStamp, m_localActorID);
|
switch (bucketName)
|
||||||
m_bucketSyncInfo.Add(syncInfo);
|
{
|
||||||
|
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 static void GeneralBucketUpdateProcessor(string bucketName)
|
||||||
|
{
|
||||||
|
lock (m_bucketUpdateLocks[bucketName])
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PhysicsBucketUpdateProcessor(string bucketName)
|
||||||
|
{
|
||||||
|
lock (m_bucketUpdateLocks[bucketName])
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Should be called when the SceneObjectGroup this part is in is added to scene, see SceneObjectGroup.AttachToScene
|
||||||
|
public void InitializeBucketSyncInfo()
|
||||||
|
{
|
||||||
|
if (m_primPropertyBucketMap == null)
|
||||||
|
{
|
||||||
|
m_log.Error("Bucket Information has not been initilized. Return.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long timeStamp = DateTime.Now.Ticks;
|
||||||
|
for (int i = 0; i < m_bucketCount; i++)
|
||||||
|
{
|
||||||
|
string bucketName = m_propertyBucketNames[i];
|
||||||
|
BucketSyncInfo syncInfo = new BucketSyncInfo(timeStamp, m_localActorID, bucketName);
|
||||||
|
m_bucketSyncInfoList.Add(bucketName, syncInfo);
|
||||||
|
m_bucketUpdateLocks.Add(bucketName, new Object());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateBucketSyncInfo(string propertyName)
|
private void UpdateBucketSyncInfo(string propertyName)
|
||||||
{
|
{
|
||||||
if (m_bucketSyncInfo != null)
|
if (m_bucketSyncInfoList != null)
|
||||||
{
|
{
|
||||||
int bucketIndex = m_primPropertyBucketMap[propertyName];
|
//int bucketIndex = m_primPropertyBucketMap[propertyName];
|
||||||
|
string bucketName = m_primPropertyBucketMap[propertyName];
|
||||||
long timeStamp = DateTime.Now.Ticks;
|
long timeStamp = DateTime.Now.Ticks;
|
||||||
m_bucketSyncInfo[bucketIndex].UpdateSyncInfo(timeStamp, m_localActorID);
|
m_bucketSyncInfoList[bucketName].UpdateSyncInfo(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_bucketCount; 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 " + UUID + " with the same TimeStamp (" + m_bucketSyncInfoList[bucketName].LastUpdateActorID
|
||||||
|
+ "," + updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID + ", CONFLICT RESOLUTION TO BE IMPLEMENTED!!!!");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Second, if need to update local properties, call each bucket's update process
|
||||||
|
if (m_bucketUpdateProcessors.ContainsKey(bucketName))
|
||||||
|
{
|
||||||
|
m_bucketUpdateProcessors[bucketName](bucketName);
|
||||||
|
partUpdateResult = Scene.ObjectUpdateResult.Updated;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.Warn("No update processor for property bucket " + bucketName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return partUpdateResult;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//private void UpdateBucketProperties(string bucketDescription,
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -330,8 +330,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem);
|
m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem);
|
||||||
|
|
||||||
//SYMMETRIC SYNC
|
//SYMMETRIC SYNC
|
||||||
m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp);
|
//m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp);
|
||||||
m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID);
|
//m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID);
|
||||||
|
m_SOPXmlProcessors.Add("BucketSyncInfoList", ProcessBucketSyncInfo);
|
||||||
//end of SYMMETRIC SYNC
|
//end of SYMMETRIC SYNC
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -702,6 +703,55 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
{
|
{
|
||||||
obj.LastUpdateActorID = reader.ReadElementContentAsString("LastUpdateActorID", string.Empty);
|
obj.LastUpdateActorID = reader.ReadElementContentAsString("LastUpdateActorID", string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ProcessBucketSyncInfo(SceneObjectPart obj, XmlTextReader reader)
|
||||||
|
{
|
||||||
|
obj.BucketSyncInfoList = new Dictionary<string, BucketSyncInfo>();
|
||||||
|
|
||||||
|
if (reader.IsEmptyElement)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string elementName = "BucketSyncInfoList";
|
||||||
|
reader.ReadStartElement(elementName, String.Empty);
|
||||||
|
|
||||||
|
while (reader.Name == "Bucket")
|
||||||
|
{
|
||||||
|
reader.ReadStartElement("Bucket", String.Empty); // Bucket
|
||||||
|
string bucketName="";
|
||||||
|
long timeStamp = 0;
|
||||||
|
string actorID = "";
|
||||||
|
while (reader.NodeType != XmlNodeType.EndElement)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "Name":
|
||||||
|
bucketName = reader.ReadElementContentAsString("Name", String.Empty);
|
||||||
|
break;
|
||||||
|
case "TimeStamp":
|
||||||
|
timeStamp = reader.ReadElementContentAsLong("TimeStamp", String.Empty);
|
||||||
|
break;
|
||||||
|
case "ActorID":
|
||||||
|
actorID = reader.ReadElementContentAsString("ActorID", String.Empty);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reader.ReadOuterXml();
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
reader.ReadEndElement();
|
||||||
|
BucketSyncInfo bucketSyncInfo = new BucketSyncInfo(timeStamp, actorID, bucketName);
|
||||||
|
obj.BucketSyncInfoList.Add(bucketName, bucketSyncInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reader.NodeType == XmlNodeType.EndElement)
|
||||||
|
reader.ReadEndElement(); // BucketSyncInfoList
|
||||||
|
}
|
||||||
|
|
||||||
//end of SYMMETRIC SYNC
|
//end of SYMMETRIC SYNC
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -1186,13 +1236,36 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
WriteBytes(writer, "ParticleSystem", sop.ParticleSystem);
|
WriteBytes(writer, "ParticleSystem", sop.ParticleSystem);
|
||||||
|
|
||||||
//SYMMETRIC SYNC
|
//SYMMETRIC SYNC
|
||||||
writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString());
|
//writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString());
|
||||||
writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID);
|
//writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID);
|
||||||
|
WriteBucketSyncInfo(writer, sop.BucketSyncInfoList);
|
||||||
//end of SYMMETRIC SYNC
|
//end of SYMMETRIC SYNC
|
||||||
|
|
||||||
writer.WriteEndElement();
|
writer.WriteEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SYMMETRIC SYNC
|
||||||
|
static void WriteBucketSyncInfo(XmlTextWriter writer, Dictionary<string, BucketSyncInfo> bucketSyncInfoList)
|
||||||
|
{
|
||||||
|
if (bucketSyncInfoList.Count > 0) // otherwise skip this
|
||||||
|
{
|
||||||
|
writer.WriteStartElement("BucketSyncInfoList");
|
||||||
|
foreach (KeyValuePair<string, BucketSyncInfo> pair in bucketSyncInfoList)
|
||||||
|
{
|
||||||
|
BucketSyncInfo bucketSyncInfo = pair.Value;
|
||||||
|
writer.WriteStartElement("Bucket");
|
||||||
|
writer.WriteElementString("Name", bucketSyncInfo.BucketName);
|
||||||
|
writer.WriteElementString("TimeStamp", bucketSyncInfo.LastUpdateTimeStamp.ToString());
|
||||||
|
writer.WriteElementString("ActorID", bucketSyncInfo.LastUpdateActorID);
|
||||||
|
writer.WriteEndElement(); // Bucket
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteEndElement(); // BucketSyncInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//end of SYMMETRIC SYNC
|
||||||
|
|
||||||
static void WriteUUID(XmlTextWriter writer, string name, UUID id, Dictionary<string, object> options)
|
static void WriteUUID(XmlTextWriter writer, string name, UUID id, Dictionary<string, object> options)
|
||||||
{
|
{
|
||||||
writer.WriteStartElement(name);
|
writer.WriteStartElement(name);
|
||||||
|
|
Loading…
Reference in New Issue