Starting add SetXXX() functions to SceneObjectPart, where XXX is each property's name. Also fixed some bugs in InitializeBucketSyncInfo

dsg
Huaiyu (Kitty) Liu 2011-02-02 15:46:12 -08:00
parent ce4c8e4b6f
commit 9ca061b25a
4 changed files with 186 additions and 28 deletions

View File

@ -19,6 +19,8 @@ using System.Net.Sockets;
using System.Threading;
using System.Text;
using System.IO;
using System.Xml;
using Mono.Addins;
using OpenMetaverse.StructuredData;
@ -198,7 +200,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
private Dictionary<UUID, SceneObjectGroup> m_primUpdates = new Dictionary<UUID, SceneObjectGroup>();
private object m_updateScenePresenceLock = new object();
private Dictionary<UUID, ScenePresence> m_presenceUpdates = new Dictionary<UUID, ScenePresence>();
private int m_sendingUpdates;
private int m_sendingUpdates=0;
private int m_maxNumOfPropertyBuckets;
@ -242,16 +244,21 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
case "IsPhysical":
case "Flying":
case "Buoyancy":
m_primPropertyBucketMap.Add(pName, generalBucketName);
m_primPropertyBucketMap.Add(pName, physicsBucketName);
break;
default:
//all other properties belong to the "General" bucket.
m_primPropertyBucketMap.Add(pName, physicsBucketName);
m_primPropertyBucketMap.Add(pName, generalBucketName);
break;
}
}
}
private bool IsSyncingWithOtherActors()
{
return (m_syncConnectors.Count > 0);
}
public void QueueSceneObjectPartForUpdate(SceneObjectPart part)
{
//if the last update of the prim is caused by this actor itself, or if the actor is a relay node, then enqueue the update
@ -275,6 +282,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//SendSceneUpdates put each update into an outgoing queue of each SyncConnector
public void SendSceneUpdates()
{
if (!IsSyncingWithOtherActors())
{
//no SyncConnector connected. Do nothing.
return;
}
// Existing value of 1 indicates that updates are currently being sent so skip updates this pass
if (Interlocked.Exchange(ref m_sendingUpdates, 1) == 1)
{
@ -389,6 +402,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
public void SendTerrainUpdates(string lastUpdateActorID)
{
if (!IsSyncingWithOtherActors())
{
//no SyncConnector connected. Do nothing.
return;
}
if(m_isSyncRelay || m_actorID.Equals(lastUpdateActorID))
{
//m_scene.Heightmap should have been updated already by the caller, send it out
@ -406,7 +424,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//private void RegionSyncModule_OnObjectBeingRemovedFromScene(SceneObjectGroup sog)
public void SendDeleteObject(SceneObjectGroup sog, bool softDelete)
{
m_log.DebugFormat("SendDeleteObject called for object {0}", sog.UUID);
if (!IsSyncingWithOtherActors())
{
//no SyncConnector connected. Do nothing.
return;
}
m_log.DebugFormat(LogHeader+"SendDeleteObject called for object {0}", sog.UUID);
//Only send the message out if this is a relay node for sync messages, or this actor caused deleting the object
//if (m_isSyncRelay || CheckObjectForSendingUpdate(sog))
@ -428,6 +452,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{
if(children.Count==0) return;
if (!IsSyncingWithOtherActors())
{
//no SyncConnector connected. Do nothing.
return;
}
OSDMap data = new OSDMap();
string sogxml = SceneObjectSerializer.ToXml2Format(linkedGroup);
data["linkedGroup"]=OSD.FromString(sogxml);
@ -449,6 +479,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{
if (prims.Count==0 || beforeDelinkGroups.Count==0) return;
if (!IsSyncingWithOtherActors())
{
//no SyncConnector connected. Do nothing.
return;
}
OSDMap data = new OSDMap();
data["partCount"] = OSD.FromInteger(prims.Count);
int partNum = 0;
@ -486,6 +522,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
public void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs)
{
if (!IsSyncingWithOtherActors())
{
//no SyncConnector connected. Do nothing.
return;
}
switch (ev)
{
case EventManager.EventNames.NewScript:
@ -566,9 +608,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
Command cmdSyncStatus = new Command("status", CommandIntentions.COMMAND_HAZARDOUS, SyncStatus, "Displays synchronization status.");
//for debugging purpose
Command cmdSyncDebug = new Command("debug", CommandIntentions.COMMAND_HAZARDOUS, SyncDebug, "Trigger some debugging functions");
m_commander.RegisterCommand("start", cmdSyncStart);
m_commander.RegisterCommand("stop", cmdSyncStop);
m_commander.RegisterCommand("status", cmdSyncStatus);
m_commander.RegisterCommand("debug", cmdSyncDebug);
lock (m_scene)
{
@ -794,7 +840,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
//Start symmetric synchronization initialization automatically
SyncStart(null);
//SyncStart(null);
}
private void StartLocalSyncListener()
@ -930,6 +976,38 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
m_log.Warn("[REGION SYNC MODULE]: SyncStatus() TO BE IMPLEMENTED !!!");
}
private void SyncDebug(Object[] args)
{
if (m_scene != null)
{
EntityBase[] entities = m_scene.GetEntities();
foreach (EntityBase entity in entities)
{
if (entity is SceneObjectGroup)
{
//first test serialization
StringWriter sw = new StringWriter();
XmlTextWriter writer = new XmlTextWriter(sw);
Dictionary<string, BucketSyncInfo> bucketSyncInfoList = new Dictionary<string,BucketSyncInfo>();
BucketSyncInfo generalBucket = new BucketSyncInfo(DateTime.Now.Ticks, m_actorID, "General");
bucketSyncInfoList.Add("General", generalBucket);
BucketSyncInfo physicsBucket = new BucketSyncInfo(DateTime.Now.Ticks, m_actorID, "Physics");
bucketSyncInfoList.Add("Physics", physicsBucket);
SceneObjectSerializer.WriteBucketSyncInfo(writer, bucketSyncInfoList);
string xmlString = sw.ToString();
m_log.Debug("Serialized xml string: " + xmlString);
//second, test de-serialization
XmlTextReader reader = new XmlTextReader(new StringReader(xmlString));
SceneObjectPart part = new SceneObjectPart();
SceneObjectSerializer.ProcessBucketSyncInfo(part, reader);
break;
}
}
}
}
//Start connections to each remote listener.
//For now, there is only one remote listener.
private bool StartSyncConnections()

View File

@ -581,7 +581,7 @@ namespace OpenSim.Region.Framework.Scenes
//ScheduleGroupForFullUpdate();
//SYMMETRIC SYNC
if (m_scene.RegionSyncClientModule != null)
if (m_scene.RegionSyncModule != null)
{
foreach (SceneObjectPart part in Parts)
{

View File

@ -186,9 +186,13 @@ namespace OpenSim.Region.Framework.Scenes
set
{
m_allowedDrop = value;
UpdateBucketSyncInfo("AllowedDrop");
//UpdateBucketSyncInfo("AllowedDrop");
}
}
public void SetAllowedDrop(bool value)
{
m_allowedDrop = value;
}
public bool DIE_AT_EDGE;
@ -793,6 +797,10 @@ namespace OpenSim.Region.Framework.Scenes
}
set
{
//SetGroupPosition(value);
//UpdateBucketSyncInfo("GroupPosition");
//Legacy Opensim code
m_groupPosition = value;
PhysicsActor actor = PhysActor;
@ -833,8 +841,54 @@ namespace OpenSim.Region.Framework.Scenes
}
}
}
}
}
//SYMMETRIC SYNC
public void SetGroupPosition(Vector3 value)
{
m_groupPosition = value;
PhysicsActor actor = PhysActor;
if (actor != null)
{
try
{
// Root prim actually goes at Position
if (_parentID == 0)
{
actor.Position = value;
}
else
{
// To move the child prim in respect to the group position and rotation we have to calculate
actor.Position = GetWorldPosition();
actor.Orientation = GetWorldRotation();
}
// Tell the physics engines that this prim changed.
m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
}
catch (Exception e)
{
m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message);
}
}
// TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
if (m_sitTargetAvatar != UUID.Zero)
{
if (m_parentGroup != null) // TODO can there be a SOP without a SOG?
{
ScenePresence avatar;
if (m_parentGroup.Scene.TryGetScenePresence(m_sitTargetAvatar, out avatar))
{
avatar.ParentPosition = GetWorldPosition();
}
}
}
}
public Vector3 OffsetPosition
{
@ -5108,7 +5162,7 @@ namespace OpenSim.Region.Framework.Scenes
/*
private Object propertyUpdateLock = new Object();
//!!!!!! -- TODO:
@ -5236,7 +5290,7 @@ namespace OpenSim.Region.Framework.Scenes
return partUpdateResult;
}
*/
private bool UpdateCollisionSound(UUID updatedCollisionSound)
@ -5294,7 +5348,7 @@ 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 = null;
private Dictionary<string, BucketSyncInfo> m_bucketSyncInfoList = new Dictionary<string, BucketSyncInfo>();
public Dictionary<string, BucketSyncInfo> BucketSyncInfoList
{
get { return m_bucketSyncInfoList; }
@ -5309,7 +5363,7 @@ namespace OpenSim.Region.Framework.Scenes
private static Dictionary<string, Object> m_bucketUpdateLocks = new Dictionary<string, object>();
private static string m_localActorID = "";
private static int m_bucketCount = 0;
//private static int m_bucketCount = 0;
//private delegate void BucketUpdateProcessor(int bucketIndex);
private delegate void BucketUpdateProcessor(string bucketName);
@ -5320,7 +5374,7 @@ namespace OpenSim.Region.Framework.Scenes
m_primPropertyBucketMap = propertyBucketMap;
m_propertyBucketNames = bucketNames;
m_localActorID = actorID;
m_bucketCount = propertyBucketMap.Count;
//m_bucketCount = bucketNames.Count;
RegisterBucketUpdateProcessor();
}
@ -5373,29 +5427,51 @@ namespace OpenSim.Region.Framework.Scenes
return;
}
long timeStamp = DateTime.Now.Ticks;
for (int i = 0; i < m_bucketCount; i++)
m_log.Debug("InitializeBucketSyncInfo called at " + timeStamp);
for (int i = 0; i < m_propertyBucketNames.Count; 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());
//If the object is created by de-serialization, then it already has m_bucketSyncInfoList populated with the right number of buckets
if (m_bucketSyncInfoList.ContainsKey(bucketName))
{
m_bucketSyncInfoList[bucketName] = syncInfo;
}
else
{
m_bucketSyncInfoList.Add(bucketName, syncInfo);
}
if (!m_bucketSyncInfoList.ContainsKey(bucketName))
{
m_bucketUpdateLocks.Add(bucketName, new Object());
}
}
}
private void UpdateBucketSyncInfo(string propertyName)
{
if (m_bucketSyncInfoList != null)
if (m_bucketSyncInfoList != null && m_bucketSyncInfoList.Count>0)
{
//int bucketIndex = m_primPropertyBucketMap[propertyName];
string bucketName = m_primPropertyBucketMap[propertyName];
long timeStamp = DateTime.Now.Ticks;
m_bucketSyncInfoList[bucketName].UpdateSyncInfo(timeStamp, m_localActorID);
if (m_bucketSyncInfoList.ContainsKey(bucketName))
{
m_bucketSyncInfoList[bucketName].UpdateSyncInfo(timeStamp, m_localActorID);
}
else
{
m_log.Warn("No SyncInfo of bucket (name: " + bucketName + ") found");
}
}
}
/*
public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart)
{
@ -5452,7 +5528,7 @@ namespace OpenSim.Region.Framework.Scenes
return partUpdateResult;
}
*/
//private void UpdateBucketProperties(string bucketDescription,
#endregion

View File

@ -330,9 +330,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem);
//SYMMETRIC SYNC
//m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp);
//m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID);
m_SOPXmlProcessors.Add("BucketSyncInfoList", ProcessBucketSyncInfo);
m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp);
m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID);
// m_SOPXmlProcessors.Add("BucketSyncInfoList", ProcessBucketSyncInfo);
//end of SYMMETRIC SYNC
#endregion
@ -418,6 +418,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
}
#region SOPXmlProcessors
//SYMMETRIC SYNC NOTE: TODO -- assignments in de-serialization should directly set the values w/o triggering SceneObjectPart.UpdateBucketSyncInfo;
//That is, calling SetXXX(value) instead of "XXX = value". It's an code optimization to be done later.
private static void ProcessAllowedDrop(SceneObjectPart obj, XmlTextReader reader)
{
obj.AllowedDrop = Util.ReadBoolean(reader);
@ -704,7 +706,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
obj.LastUpdateActorID = reader.ReadElementContentAsString("LastUpdateActorID", string.Empty);
}
private static void ProcessBucketSyncInfo(SceneObjectPart obj, XmlTextReader reader)
public static void ProcessBucketSyncInfo(SceneObjectPart obj, XmlTextReader reader)
{
obj.BucketSyncInfoList = new Dictionary<string, BucketSyncInfo>();
@ -1236,19 +1238,20 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
WriteBytes(writer, "ParticleSystem", sop.ParticleSystem);
//SYMMETRIC SYNC
//writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString());
//writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID);
WriteBucketSyncInfo(writer, sop.BucketSyncInfoList);
writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString());
writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID);
//WriteBucketSyncInfo(writer, sop.BucketSyncInfoList);
//end of SYMMETRIC SYNC
writer.WriteEndElement();
}
//SYMMETRIC SYNC
static void WriteBucketSyncInfo(XmlTextWriter writer, Dictionary<string, BucketSyncInfo> bucketSyncInfoList)
public static void WriteBucketSyncInfo(XmlTextWriter writer, Dictionary<string, BucketSyncInfo> bucketSyncInfoList)
{
if (bucketSyncInfoList.Count > 0) // otherwise skip this
if (bucketSyncInfoList!=null || bucketSyncInfoList.Count > 0) // otherwise skip this
{
writer.WriteStartElement("BucketSyncInfoList");
foreach (KeyValuePair<string, BucketSyncInfo> pair in bucketSyncInfoList)
{
@ -1261,6 +1264,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
}
writer.WriteEndElement(); // BucketSyncInfo
}
}