Added class PropertySyncInfo and PrimSyncInfo in RegionSyncModule.

dsg
Huaiyu (Kitty) Liu 2011-04-06 12:23:04 -07:00
parent e5a022c8d7
commit 2bea8bb4bc
2 changed files with 166 additions and 121 deletions

View File

@ -130,27 +130,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//Called after AddRegion() has been called for all region modules of the scene //Called after AddRegion() has been called for all region modules of the scene
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)
{ {
//m_log.Warn(LogHeader + " RegionLoaded() called");
/*
//If this one is configured to start a listener so that other actors can connect to form a overlay, start the listener.
//For now, we use the star topology, and ScenePersistence actor is always the one to start the listener.
if (m_isSyncListenerLocal)
{
StartLocalSyncListener();
}
else
{
//Start connecting to the remote listener. TO BE IMPLEMENTED.
//For now, the connection will be started by manually typing in "sync start".
}
* */
//Start symmetric synchronization initialization automatically
//SyncStart(null);
// connect to statistics system
SyncStatisticCollector.Register(this); SyncStatisticCollector.Register(this);
} }
@ -182,24 +161,20 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
// Synchronization related members and functions, exposed through IRegionSyncModule interface // Synchronization related members and functions, exposed through IRegionSyncModule interface
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
private DSGActorTypes m_actorType = DSGActorTypes.Unknown; //ActorID might not be in use anymore. Rather, SyncID should be used.
/// <summary> //(Synchronization is sync node centric, not actor centric.)
/// The type of the actor running locally. This value will be set by an ActorSyncModule, so that
/// no hard code needed in RegionSyncModule to recoganize the actor's type, thus make it easier
/// to add new ActorSyncModules w/o chaning the code in RegionSyncModule.
/// </summary>
public DSGActorTypes DSGActorType
{
get { return m_actorType; }
set { m_actorType = value; }
}
private string m_actorID; private string m_actorID;
public string ActorID public string ActorID
{ {
get { return m_actorID; } get { return m_actorID; }
} }
private string m_syncID;
public string SyncID
{
get { return m_syncID; }
}
private bool m_active = false; private bool m_active = false;
public bool Active public bool Active
{ {
@ -228,12 +203,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
foreach (string bucketName in m_propertyBucketNames) foreach (string bucketName in m_propertyBucketNames)
{ {
//if (m_isSyncRelay || part.HasPropertyUpdatedLocallyInGivenBucket(bucketName))
if(!part.ParentGroup.IsDeleted && HaveUpdatesToSendoutForSync(part, bucketName)) if(!part.ParentGroup.IsDeleted && HaveUpdatesToSendoutForSync(part, bucketName))
{ {
lock (m_primUpdateLocks[bucketName]) lock (m_primUpdateLocks[bucketName])
{ {
//m_log.Debug("Queueing to bucket " + bucketName + " with part " + part.Name + ", " + part.UUID+" at pos "+part.GroupPosition.ToString());
m_primUpdates[bucketName][part.UUID] = part; m_primUpdates[bucketName][part.UUID] = part;
} }
} }
@ -250,8 +223,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
//SendSceneUpdates put each update into an outgoing queue of each SyncConnector //SendSceneUpdates put each update into an outgoing queue of each SyncConnector
/// <summary>
/// Send updates to other sync nodes. So far we only handle object updates.
/// </summary>
public void SendSceneUpdates() public void SendSceneUpdates()
{ {
if (!IsSyncingWithOtherSyncNodes()) if (!IsSyncingWithOtherSyncNodes())
@ -271,7 +247,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
return; return;
} }
//List<SceneObjectGroup> primUpdates=null;
Dictionary<string, List<SceneObjectPart>> primUpdates = new Dictionary<string,List<SceneObjectPart>>(); Dictionary<string, List<SceneObjectPart>> primUpdates = new Dictionary<string,List<SceneObjectPart>>();
bool updated = false; bool updated = false;
@ -304,18 +279,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
} }
List<ScenePresence> presenceUpdates = new List<ScenePresence>();
/*
if (m_presenceUpdates.Count > 0)
{
lock (m_updateScenePresenceLock)
{
updated = true;
presenceUpdates = new List<ScenePresence>(m_presenceUpdates.Values);
m_presenceUpdates.Clear();
}
}
*/
if (updated) if (updated)
{ {
@ -337,48 +300,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
primUpdates[bucketName].Clear(); primUpdates[bucketName].Clear();
} }
} }
foreach (ScenePresence presence in presenceUpdates)
{
try
{
if (!presence.IsDeleted)
{
/*
OSDMap data = new OSDMap(10);
data["id"] = OSD.FromUUID(presence.UUID);
// Do not include offset for appearance height. That will be handled by RegionSyncClient before sending to viewers
if(presence.AbsolutePosition.IsFinite())
data["pos"] = OSD.FromVector3(presence.AbsolutePosition);
else
data["pos"] = OSD.FromVector3(Vector3.Zero);
if(presence.Velocity.IsFinite())
data["vel"] = OSD.FromVector3(presence.Velocity);
else
data["vel"] = OSD.FromVector3(Vector3.Zero);
data["rot"] = OSD.FromQuaternion(presence.Rotation);
data["fly"] = OSD.FromBoolean(presence.Flying);
data["flags"] = OSD.FromUInteger((uint)presence.AgentControlFlags);
data["anim"] = OSD.FromString(presence.Animator.CurrentMovementAnimation);
// needed for a full update
if (presence.ParentID != presence.lastSentParentID)
{
data["coll"] = OSD.FromVector4(presence.CollisionPlane);
data["off"] = OSD.FromVector3(presence.OffsetPosition);
data["pID"] = OSD.FromUInteger(presence.ParentID);
presence.lastSentParentID = presence.ParentID;
}
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.UpdatedAvatar, OSDParser.SerializeJsonString(data));
m_server.EnqueuePresenceUpdate(presence.UUID, rsm.ToBytes());
*/
}
}
catch (Exception e)
{
m_log.ErrorFormat("[REGION SYNC MODULE] Caught exception sending presence updates for {0}: {1}", presence.Name, e);
}
}
// Indicate that the current batch of updates has been completed // Indicate that the current batch of updates has been completed
Interlocked.Exchange(ref m_sendingUpdates, 0); Interlocked.Exchange(ref m_sendingUpdates, 0);
@ -583,21 +504,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
OnLocalScriptReset((uint)evArgs[0], (UUID)evArgs[1]); OnLocalScriptReset((uint)evArgs[0], (UUID)evArgs[1]);
return; return;
case EventManager.EventNames.ChatFromClient: case EventManager.EventNames.ChatFromClient:
/*if (evArgs.Length < 2) case EventManager.EventNames.ChatFromWorld:
{
m_log.Error(LogHeader + " not enough event args for ChatFromClient");
return;
}
OnLocalChatFromClient(evArgs[0], (OSChatMessage)evArgs[1]);
return;*/
case EventManager.EventNames.ChatFromWorld:
/*if (evArgs.Length < 2)
{
m_log.Error(LogHeader + " not enough event args for ChatFromWorld");
return;
}
OnLocalChatFromWorld(evArgs[0], (OSChatMessage)evArgs[1]);
return;*/
case EventManager.EventNames.ChatBroadcast: case EventManager.EventNames.ChatBroadcast:
if (evArgs.Length < 2) if (evArgs.Length < 2)
{ {
@ -699,9 +606,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
#region RegionSyncModule members and functions #region RegionSyncModule members and functions
///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// Synchronization related functions, NOT exposed through IRegionSyncModule interface // Memeber variables
///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
private static int PortUnknown = -1; private static int PortUnknown = -1;
private static string IPAddrUnknown = String.Empty; private static string IPAddrUnknown = String.Empty;
@ -740,9 +647,16 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
private RegionSyncListener m_localSyncListener = null; private RegionSyncListener m_localSyncListener = null;
private bool m_synced = false; private bool m_synced = false;
// Lock is used to synchronize access to the update status and update queues ///////////////////////////////////////////////////////////////////////
//private object m_updateSceneObjectPartLock = new object(); // Memeber variables for per-property timestamp
//private Dictionary<UUID, SceneObjectGroup> m_primUpdates = new Dictionary<UUID, SceneObjectGroup>(); ///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// Legacy members for bucket-based sync,
///////////////////////////////////////////////////////////////////////
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, SceneObjectPart>> m_primUpdates = new Dictionary<string, Dictionary<UUID, SceneObjectPart>>(); private Dictionary<string, Dictionary<UUID, SceneObjectPart>> m_primUpdates = new Dictionary<string, Dictionary<UUID, SceneObjectPart>>();
@ -771,6 +685,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
private int m_maxNumOfPropertyBuckets; private int m_maxNumOfPropertyBuckets;
/////////////////////////////////////////////////////////////////////////////////////////
// Synchronization related functions, NOT exposed through IRegionSyncModule interface
/////////////////////////////////////////////////////////////////////////////////////////
private void StatsTimerElapsed(object source, System.Timers.ElapsedEventArgs e) private void StatsTimerElapsed(object source, System.Timers.ElapsedEventArgs e)
{ {
//TO BE IMPLEMENTED //TO BE IMPLEMENTED
@ -1690,7 +1608,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
m_log.Error(LogHeader + "interface Scene.ActorSyncModule has not been set yet"); m_log.Error(LogHeader + "interface Scene.ActorSyncModule has not been set yet");
return; return;
} }
m_actorType = m_scene.ActorSyncModule.ActorType; //m_actorType = m_scene.ActorSyncModule.ActorType;
} }
//Start symmetric synchronization initialization automatically //Start symmetric synchronization initialization automatically
@ -1800,12 +1718,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//Start SyncListener if a listener is supposed to run on this actor; Otherwise, initiate connections to remote listeners. //Start SyncListener if a listener is supposed to run on this actor; Otherwise, initiate connections to remote listeners.
private void SyncStart(Object[] args) private void SyncStart(Object[] args)
{ {
if (m_actorType == DSGActorTypes.Unknown)
{
m_log.Error(LogHeader + ": SyncStart -- ActorType not set yet. Either it's not defined in config file (DSGActorType), or the ActorSyncModule (ScenePersistenceSyncModule, ScriptEngineSyncModule etc) has not defined it.");
return;
}
if (m_isSyncListenerLocal) if (m_isSyncListenerLocal)
{ {
if (m_localSyncListener!=null && m_localSyncListener.IsListening) if (m_localSyncListener!=null && m_localSyncListener.IsListening)
@ -3400,5 +3312,137 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
} }
///////////////////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////////////////
public enum PropertyUpdateSource
{
Local,
BySync
}
public class PropertySyncInfo
{
private ulong m_lastUpdateTimeStamp;
public ulong LastUpdateTimeStamp
{
get { return m_lastUpdateTimeStamp; }
}
private string m_lastUpdateSyncID;
public string LastUpdateSyncID
{
get { return m_lastUpdateSyncID; }
}
/// <summary>
/// The value of the most recent value sent/received by Sync Module.
/// For property with simple types, the value is copied directly.
/// For property with complex data structures, the value (values of
/// subproperties) is serialized and stored.
/// </summary>
private Object m_lastUpdateValue;
public Object LastUpdateValue
{
get { return m_lastUpdateValue; }
}
/// <summary>
/// Record the time the last sync message about this property is received.
/// This value is only meaninful when m_lastUpdateSource==BySync
/// </summary>
private ulong m_lastSyncUpdateRecvTime;
public ulong LastSyncUpdateRecvTime
{
get { return m_lastSyncUpdateRecvTime; }
set { m_lastSyncUpdateRecvTime = value; }
}
private PropertyUpdateSource m_lastUpdateSource;
public PropertyUpdateSource LastUpdateSource
{
get { return m_lastUpdateSource; }
}
private Object m_syncInfoLock = new Object();
/// <summary>
/// Update SyncInfo when the property is updated locally.
/// </summary>
/// <param name="ts">the time </param>
/// <param name="syncID"></param>
public void UpdateSyncInfoLocally(ulong ts, string syncID, Object pValue)
{
lock (m_syncInfoLock)
{
m_lastUpdateValue = pValue;
m_lastUpdateTimeStamp = ts;
m_lastUpdateSyncID = syncID;
m_lastUpdateSource = PropertyUpdateSource.Local;
}
}
/// <summary>
/// Update SyncInfo when the property is updated by receiving a sync
/// message.
/// </summary>
/// <param name="ts"></param>
/// <param name="syncID"></param>
public void UpdateSyncInfoBySync(ulong ts, string syncID, ulong recvTS, Object pValue)
{
lock (m_syncInfoLock)
{
m_lastUpdateValue = pValue;
m_lastUpdateTimeStamp = ts;
m_lastUpdateSyncID = syncID;
m_lastSyncUpdateRecvTime = recvTS;
m_lastUpdateSource = PropertyUpdateSource.BySync;
}
}
}
public class PrimSyncInfo
{
#region Members
public static long TimeOutThreshold;
private Dictionary<SceneObjectPartProperties, PropertySyncInfo> m_propertiesSyncInfo;
public Dictionary<SceneObjectPartProperties, PropertySyncInfo> PropertiesSyncInfo
{
get { return m_propertiesSyncInfo; }
}
private ulong m_PrimLastUpdateTime;
public ulong PrimLastUpdateTime
{
get { return m_PrimLastUpdateTime; }
}
#endregion //Members
#region Constructor
public PrimSyncInfo()
{
m_propertiesSyncInfo = new Dictionary<SceneObjectPartProperties, PropertySyncInfo>();
foreach (SceneObjectPartProperties property in Enum.GetValues(typeof(SceneObjectPartProperties)))
{
PropertySyncInfo syncInfo = new PropertySyncInfo();
m_propertiesSyncInfo.Add(property, syncInfo);
}
}
#endregion //Constructor
public void UpdatePropertySyncInfoLocally(SceneObjectPartProperties property, ulong lastUpdateTS, string syncID, Object pValue)
{
m_propertiesSyncInfo[property].UpdateSyncInfoLocally(lastUpdateTS, syncID, pValue);
}
public void UpdatePropertySyncInfoBySync(SceneObjectPartProperties property, ulong lastUpdateTS, string syncID, Object pValue, ulong recvTS)
{
m_propertiesSyncInfo[property].UpdateSyncInfoBySync(lastUpdateTS, syncID, recvTS, pValue);
}
}
} }

View File

@ -52,8 +52,9 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IRegionSyncModule public interface IRegionSyncModule
{ {
bool Active { get; } //if true, this RegionSyncModule is connected into the synchronization overlay bool Active { get; } //if true, this RegionSyncModule is connected into the synchronization overlay
string ActorID { get; } string ActorID { get; } //might be phased out soon
DSGActorTypes DSGActorType { get; set; } string SyncID { get; }
//DSGActorTypes DSGActorType { get; set; }
bool IsSyncRelay { get; } bool IsSyncRelay { get; }
/// <summary> /// <summary>