Added functions to sync on RemoveObject event. Object can now be removed from either script-engine
or Scene and can be synced. Problem: there is significant delay form when an object is removed on one actor, to the time it also disappears from the viewer attaching to the other actor.dsg
parent
384895cbdd
commit
130915f669
|
@ -20,6 +20,7 @@ using System.Threading;
|
|||
using System.Text;
|
||||
|
||||
using Mono.Addins;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//KittyL: created 12/17/2010, to start DSG Symmetric Synch implementation
|
||||
|
@ -87,6 +88,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
|
||||
//Register for the OnPostSceneCreation event
|
||||
m_scene.EventManager.OnPostSceneCreation += OnPostSceneCreation;
|
||||
m_scene.EventManager.OnObjectBeingRemovedFromScene += new EventManager.ObjectBeingRemovedFromScene(RegionSyncModule_OnObjectBeingRemovedFromScene);
|
||||
}
|
||||
|
||||
//Called after AddRegion() has been called for all region modules of the scene
|
||||
|
@ -229,18 +231,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
foreach (SceneObjectGroup sog in primUpdates)
|
||||
{
|
||||
//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 (m_isSyncRelay || CheckObjectForSendingUpdate(sog))
|
||||
if (m_isSyncRelay || (!sog.IsDeleted && CheckObjectForSendingUpdate(sog)))
|
||||
{
|
||||
//send
|
||||
List<SyncConnector> syncConnectors = GetSyncConnectorsForObjectUpdates(sog);
|
||||
|
||||
foreach (SyncConnector connector in syncConnectors)
|
||||
{
|
||||
string sogxml = SceneObjectSerializer.ToXml2Format(sog);
|
||||
SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedObject, sogxml);
|
||||
connector.EnqueueOutgoingUpdate(sog.UUID, syncMsg.ToBytes());
|
||||
}
|
||||
|
||||
string sogxml = SceneObjectSerializer.ToXml2Format(sog);
|
||||
SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedObject, sogxml);
|
||||
SendObjectUpdateToRelevantSyncConnectors(sog, syncMsg);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
@ -294,6 +290,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
}
|
||||
|
||||
|
||||
|
||||
#endregion //IRegionSyncModule
|
||||
|
||||
#region ICommandableModule Members
|
||||
|
@ -394,6 +391,18 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
m_log.Warn("[REGION SYNC MODULE]: StatsTimerElapsed -- NOT yet implemented.");
|
||||
}
|
||||
|
||||
private void SendObjectUpdateToRelevantSyncConnectors(SceneObjectGroup sog, SymmetricSyncMessage syncMsg)
|
||||
{
|
||||
List<SyncConnector> syncConnectors = GetSyncConnectorsForObjectUpdates(sog);
|
||||
|
||||
foreach (SyncConnector connector in syncConnectors)
|
||||
{
|
||||
//string sogxml = SceneObjectSerializer.ToXml2Format(sog);
|
||||
//SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedObject, sogxml);
|
||||
connector.EnqueueOutgoingUpdate(sog.UUID, syncMsg.ToBytes());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if we need to send out an update message for the given object.
|
||||
/// </summary>
|
||||
|
@ -401,9 +410,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
/// <returns></returns>
|
||||
private bool CheckObjectForSendingUpdate(SceneObjectGroup sog)
|
||||
{
|
||||
if (sog == null || sog.IsDeleted)
|
||||
return false;
|
||||
|
||||
//If any part in the object has the last update caused by this actor itself, then send the update
|
||||
foreach (SceneObjectPart part in sog.Parts)
|
||||
{
|
||||
|
@ -742,6 +748,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
//HandleAddNewObject(sog);
|
||||
return;
|
||||
}
|
||||
case SymmetricSyncMessage.MsgType.RemovedObject:
|
||||
{
|
||||
HandleRemovedObject(msg);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -780,6 +791,49 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
}
|
||||
}
|
||||
|
||||
private void HandleRemovedObject(SymmetricSyncMessage msg)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Get the parameters from data
|
||||
//ulong regionHandle = data["regionHandle"].AsULong();
|
||||
//uint localID = data["UUID"].AsUInteger();
|
||||
UUID sogUUID = data["UUID"].AsUUID();
|
||||
|
||||
SceneObjectGroup sog = m_scene.SceneGraph.GetGroupByPrim(sogUUID);
|
||||
if (sog != null)
|
||||
{
|
||||
m_scene.DeleteSceneObjectBySynchronization(sog);
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<string> exceptions = new HashSet<string>();
|
||||
private OSDMap DeserializeMessage(SymmetricSyncMessage msg)
|
||||
{
|
||||
OSDMap data = null;
|
||||
try
|
||||
{
|
||||
data = OSDParser.DeserializeJson(Encoding.ASCII.GetString(msg.Data, 0, msg.Length)) as OSDMap;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
lock (exceptions)
|
||||
// If this is a new message, then print the underlying data that caused it
|
||||
if (!exceptions.Contains(e.Message))
|
||||
m_log.Error(LogHeader + " " + Encoding.ASCII.GetString(msg.Data, 0, msg.Length));
|
||||
data = null;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private void HandleAddNewObject(SceneObjectGroup sog)
|
||||
{
|
||||
//RegionSyncModule only add object to SceneGraph. Any actor specific actions will be implemented
|
||||
|
@ -792,7 +846,28 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Send a sync message to remove the given objects in all connected actors, if this is a relay node.
|
||||
/// UUID is used for identified a removed object.
|
||||
/// </summary>
|
||||
/// <param name="sog"></param>
|
||||
private void RegionSyncModule_OnObjectBeingRemovedFromScene(SceneObjectGroup sog)
|
||||
{
|
||||
//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))
|
||||
{
|
||||
OSDMap data = new OSDMap(1);
|
||||
//data["regionHandle"] = OSD.FromULong(regionHandle);
|
||||
//data["localID"] = OSD.FromUInteger(sog.LocalId);
|
||||
data["UUID"] = OSD.FromUUID(sog.UUID);
|
||||
|
||||
SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.RemovedObject, OSDParser.SerializeJsonString(data));
|
||||
SendObjectUpdateToRelevantSyncConnectors(sog, rsm);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endregion //RegionSyncModule members and functions
|
||||
|
||||
|
|
|
@ -620,6 +620,45 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
return m_sceneGraph.AddOrUpdateObjectBySynchronization(sog);
|
||||
}
|
||||
|
||||
//Similar to DeleteSceneObject, except that this does not change LastUpdateActorID and LastUpdateTimeStamp
|
||||
public void DeleteSceneObjectBySynchronization(SceneObjectGroup group)
|
||||
{
|
||||
// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
|
||||
|
||||
//SceneObjectPart rootPart = group.GetChildPart(group.UUID);
|
||||
|
||||
// Serialise calls to RemoveScriptInstances to avoid
|
||||
// deadlocking on m_parts inside SceneObjectGroup
|
||||
lock (m_deleting_scene_object)
|
||||
{
|
||||
group.RemoveScriptInstances(true);
|
||||
}
|
||||
|
||||
SceneObjectPart[] partList = group.Parts;
|
||||
|
||||
foreach (SceneObjectPart part in partList)
|
||||
{
|
||||
if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0))
|
||||
{
|
||||
PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed?
|
||||
}
|
||||
else if (part.PhysActor != null)
|
||||
{
|
||||
PhysicsScene.RemovePrim(part.PhysActor);
|
||||
part.PhysActor = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (UnlinkSceneObject(group, false))
|
||||
{
|
||||
EventManager.TriggerObjectBeingRemovedFromScene(group);
|
||||
EventManager.TriggerParcelPrimCountTainted();
|
||||
}
|
||||
|
||||
bool silent = false; //do not suppress broadcasting changes to other clients, for debugging with viewers
|
||||
group.DeleteGroupFromScene(silent);
|
||||
|
||||
}
|
||||
|
||||
#endregion //SYMMETRIC SYNC
|
||||
|
||||
|
@ -2364,6 +2403,15 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
group.DeleteGroupFromScene(silent);
|
||||
|
||||
// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
|
||||
|
||||
//SYMMETRIC SYNC
|
||||
//Set the ActorID and TimeStamp info for this latest update
|
||||
foreach (SceneObjectPart part in group.Parts)
|
||||
{
|
||||
part.SyncInfoUpdate();
|
||||
}
|
||||
//end of SYMMETRIC SYNC
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -4952,7 +4952,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
private void SyncInfoUpdate()
|
||||
public void SyncInfoUpdate()
|
||||
{
|
||||
//Trick: calling UpdateTimestamp here makes sure that when an object was received and de-serialized, before
|
||||
// its parts are linked together, neither TimeStamp or ActorID will be modified. This is because during de-serialization,
|
||||
|
|
Loading…
Reference in New Issue