Switched to use ScheduleFullUpdates() and ScheduleTerseUpdates() as the funnel to catch any property updates, so as to update bucket's sync

timestamp correctly. Code good for compilation, runtime not tested yet.
dsg
Huaiyu (Kitty) Liu 2011-02-11 15:31:13 -08:00
parent 5ef659520e
commit 7a331b6a8f
22 changed files with 521 additions and 314 deletions

View File

@ -611,7 +611,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
} }
so.IsSelected = false; // fudge.... so.IsSelected = false; // fudge....
so.ScheduleGroupForFullUpdate(); //so.ScheduleGroupForFullUpdate();
so.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //just force it to sychronize all properties
} }
// In case it is later dropped again, don't let // In case it is later dropped again, don't let

View File

@ -352,7 +352,8 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps
rootGroup.LinkToGroup(allparts[j]); rootGroup.LinkToGroup(allparts[j]);
} }
rootGroup.ScheduleGroupForFullUpdate(); //rootGroup.ScheduleGroupForFullUpdate();
rootGroup.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //seems like new object
pos = m_scene.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale(), false); pos = m_scene.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale(), false);
responsedata["int_response_code"] = 200; //501; //410; //404; responsedata["int_response_code"] = 200; //501; //410; //404;

View File

@ -1581,7 +1581,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (destination != null && !CrossPrimGroupIntoNewRegion(destination, grp, silent)) if (destination != null && !CrossPrimGroupIntoNewRegion(destination, grp, silent))
{ {
grp.OffsetForNewRegion(oldGroupPosition); grp.OffsetForNewRegion(oldGroupPosition);
grp.ScheduleGroupForFullUpdate(); //grp.ScheduleGroupForFullUpdate();
grp.ScheduleGroupForFullUpdate(SceneObjectPartProperties.Position);
} }
} }

View File

@ -600,7 +600,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
// if not, we set it's position in world. // if not, we set it's position in world.
if (!attachment) if (!attachment)
{ {
group.ScheduleGroupForFullUpdate(); //group.ScheduleGroupForFullUpdate();
group.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //new object
float offsetHeight = 0; float offsetHeight = 0;
pos = m_Scene.GetNewRezLocation( pos = m_Scene.GetNewRezLocation(
@ -698,7 +699,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
rootPart.ParentGroup.ResumeScripts(); rootPart.ParentGroup.ResumeScripts();
rootPart.ScheduleFullUpdate(); //rootPart.ScheduleFullUpdate();
rootPart.ScheduleFullUpdate(SceneObjectPartProperties.FullUpdate);
} }
if (!m_Scene.Permissions.BypassPermissions()) if (!m_Scene.Permissions.BypassPermissions())

View File

@ -321,7 +321,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//RegionSyncMessage.HandleSuccess(LogHeader(), msg, String.Format("Object \"{0}\" ({1}) ({1}) updated.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString())); //RegionSyncMessage.HandleSuccess(LogHeader(), msg, String.Format("Object \"{0}\" ({1}) ({1}) updated.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()));
//else //else
//RegionSyncMessage.HandleSuccess(LogHeader(), msg, String.Format("Object \"{0}\" ({1}) ({1}) added.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString())); //RegionSyncMessage.HandleSuccess(LogHeader(), msg, String.Format("Object \"{0}\" ({1}) ({1}) added.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()));
sog.ScheduleGroupForFullUpdate(); //sog.ScheduleGroupForFullUpdate();
} }
return; return;
} }

View File

@ -550,7 +550,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//the prim is not the root-part, set the offset position //the prim is not the root-part, set the offset position
primToUpdate.OffsetPosition = pos; primToUpdate.OffsetPosition = pos;
parent.HasGroupChanged = true; parent.HasGroupChanged = true;
parent.ScheduleGroupForTerseUpdate(); //parent.ScheduleGroupForTerseUpdate();
parent.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.OffsetPosition);
} }
} }

View File

@ -181,8 +181,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
get { return m_isSyncRelay; } get { return m_isSyncRelay; }
} }
private Dictionary<string, string> m_primPropertyBucketMap = new Dictionary<string, string>(); private Dictionary<SceneObjectPartProperties, string> m_primPropertyBucketMap = new Dictionary<SceneObjectPartProperties, string>();
public Dictionary<string, string> PrimPropertyBucketMap public Dictionary<SceneObjectPartProperties, string> PrimPropertyBucketMap
{ {
get { return m_primPropertyBucketMap; } get { return m_primPropertyBucketMap; }
} }
@ -225,6 +225,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
m_propertyBucketDescription.Add(physicsBucketName); m_propertyBucketDescription.Add(physicsBucketName);
m_maxNumOfPropertyBuckets = 2; m_maxNumOfPropertyBuckets = 2;
/*
foreach (string pName in SceneObjectPart.PropertyList) foreach (string pName in SceneObjectPart.PropertyList)
{ {
switch (pName){ switch (pName){
@ -252,6 +253,36 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
break; break;
} }
} }
* */
foreach (SceneObjectPartProperties property in Enum.GetValues(typeof(SceneObjectPartProperties)))
{
switch (property)
{
case SceneObjectPartProperties.GroupPosition:
case SceneObjectPartProperties.OffsetPosition:
case SceneObjectPartProperties.Scale:
case SceneObjectPartProperties.Velocity:
case SceneObjectPartProperties.AngularVelocity:
case SceneObjectPartProperties.RotationOffset:
case SceneObjectPartProperties.Position:
case SceneObjectPartProperties.Size:
case SceneObjectPartProperties.Force:
case SceneObjectPartProperties.RotationalVelocity:
case SceneObjectPartProperties.PA_Acceleration:
case SceneObjectPartProperties.Torque:
case SceneObjectPartProperties.Orientation:
case SceneObjectPartProperties.IsPhysical:
case SceneObjectPartProperties.Flying:
case SceneObjectPartProperties.Buoyancy:
m_primPropertyBucketMap.Add(property, physicsBucketName);
break;
default:
//all other properties belong to the "General" bucket.
m_primPropertyBucketMap.Add(property, generalBucketName);
break;
}
}
} }
private bool IsSyncingWithOtherActors() private bool IsSyncingWithOtherActors()

View File

@ -236,7 +236,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
part.Shape.Media[face] = me; part.Shape.Media[face] = me;
UpdateMediaUrl(part, UUID.Zero); UpdateMediaUrl(part, UUID.Zero);
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(SceneObjectPartProperties.MediaUrl);
part.TriggerScriptChangedEvent(Changed.MEDIA); part.TriggerScriptChangedEvent(Changed.MEDIA);
} }
@ -421,7 +422,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap
UpdateMediaUrl(part, agentId); UpdateMediaUrl(part, agentId);
// Arguably, we could avoid sending a full update to the avatar that just changed the texture. // Arguably, we could avoid sending a full update to the avatar that just changed the texture.
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(SceneObjectPartProperties.Shape);
part.ScheduleFullUpdate(SceneObjectPartProperties.MediaUrl); //not an efficient way to taint two properties, but should not have bad side effects
part.TriggerScriptChangedEvent(Changed.MEDIA); part.TriggerScriptChangedEvent(Changed.MEDIA);
@ -499,7 +502,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
UpdateMediaUrl(part, agentId); UpdateMediaUrl(part, agentId);
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(SceneObjectPartProperties.MediaUrl);
part.TriggerScriptChangedEvent(Changed.MEDIA); part.TriggerScriptChangedEvent(Changed.MEDIA);

View File

@ -148,7 +148,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
part.GetProperties(remoteClient); part.GetProperties(remoteClient);
part.TriggerScriptChangedEvent(Changed.OWNER); part.TriggerScriptChangedEvent(Changed.OWNER);
group.ResumeScripts(); group.ResumeScripts();
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(SceneObjectPartProperties.FullUpdate); //quite some properties changed, let's just force all to be synchronized
break; break;

View File

@ -59,7 +59,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// <summary> /// <summary>
/// The mapping of a property (identified by its name) to the index of a bucket. /// The mapping of a property (identified by its name) to the index of a bucket.
/// </summary> /// </summary>
Dictionary<string, string> PrimPropertyBucketMap { get; } Dictionary<SceneObjectPartProperties, string> PrimPropertyBucketMap { get; }
/// <summary> /// <summary>
/// The text description of the properties in each bucket, e.g. "General", "Physics" /// The text description of the properties in each bucket, e.g. "General", "Physics"
/// </summary> /// </summary>

View File

@ -2197,7 +2197,8 @@ namespace OpenSim.Region.Framework.Scenes
// to find out if scripts should be activated at all. // to find out if scripts should be activated at all.
group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); group.CreateScriptInstances(param, true, DefaultScriptEngine, 3);
group.ScheduleGroupForFullUpdate(); //group.ScheduleGroupForFullUpdate();
group.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //new object, all properties have new value
return group; return group;
} }
@ -2262,7 +2263,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
sog.SetOwnerId(ownerID); sog.SetOwnerId(ownerID);
sog.SetGroup(groupID, remoteClient); sog.SetGroup(groupID, remoteClient);
sog.ScheduleGroupForFullUpdate(); //sog.ScheduleGroupForFullUpdate();
sog.ScheduleGroupForFullUpdate(SceneObjectPartProperties.OwnerID);
SceneObjectPart[] partList = sog.Parts; SceneObjectPart[] partList = sog.Parts;

View File

@ -212,7 +212,8 @@ namespace OpenSim.Region.Framework.Scenes
if (part.ParentGroup.IsAttachment) if (part.ParentGroup.IsAttachment)
isAttachment = true; isAttachment = true;
else else
part.ParentGroup.ScheduleGroupForFullUpdate(); //part.ParentGroup.ScheduleGroupForFullUpdate();
part.ParentGroup.ScheduleGroupForFullUpdate(SceneObjectPartProperties.IsSelected);
// If it's not an attachment, and we are allowed to move it, // If it's not an attachment, and we are allowed to move it,
// then we might have done so. If we moved across a parcel // then we might have done so. If we moved across a parcel

View File

@ -2391,7 +2391,8 @@ namespace OpenSim.Region.Framework.Scenes
sceneObject.SetGroup(groupID, null); sceneObject.SetGroup(groupID, null);
} }
sceneObject.ScheduleGroupForFullUpdate(); //sceneObject.ScheduleGroupForFullUpdate();
sceneObject.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //new object, all properties have new value
return sceneObject; return sceneObject;
} }
@ -4490,7 +4491,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
{ {
((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(); //((SceneObjectGroup)ent).ScheduleGroupForFullUpdate();
((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(SceneObjectPartProperties.None); //This is not due to property being updated, hence passing "None" property.
} }
} }
} }

View File

@ -383,7 +383,8 @@ namespace OpenSim.Region.Framework.Scenes
sceneObject.AttachToScene(m_parentScene); sceneObject.AttachToScene(m_parentScene);
if (sendClientUpdates) if (sendClientUpdates)
sceneObject.ScheduleGroupForFullUpdate(); //sceneObject.ScheduleGroupForFullUpdate();
sceneObject.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None);
Entities.Add(sceneObject); Entities.Add(sceneObject);
@ -1747,22 +1748,11 @@ namespace OpenSim.Region.Framework.Scenes
} }
//SYMMETRIC SYNC //SYMMETRIC SYNC
//set timestamp
/*
long timeStamp = DateTime.Now.Ticks;
string actorID = m_parentScene.GetSyncActorID();
foreach (SceneObjectGroup sog in afterDelinkGroups)
{
if (m_parentScene.RegionSyncModule != null)
{
sog.SyncInfoUpdate(timeStamp, actorID); ;
}
}
* */
//Send out DelinkObject message to other actors to sychronize their object list //Send out DelinkObject message to other actors to sychronize their object list
m_parentScene.RegionSyncModule.SendDeLinkObject(prims, beforeDelinkGroups, afterDelinkGroups); if (m_parentScene.RegionSyncModule != null)
{
m_parentScene.RegionSyncModule.SendDeLinkObject(prims, beforeDelinkGroups, afterDelinkGroups);
}
//Schedule updates as in legacy OpenSim code, to send updates to viewers connected to this actor (at least needed for client managers). //Schedule updates as in legacy OpenSim code, to send updates to viewers connected to this actor (at least needed for client managers).
//But timestamp won't be changed, so that when other actors get the update, they's simple ignore the updates since they already get them //But timestamp won't be changed, so that when other actors get the update, they's simple ignore the updates since they already get them
foreach (SceneObjectGroup sog in afterDelinkGroups) foreach (SceneObjectGroup sog in afterDelinkGroups)
@ -1905,7 +1895,8 @@ namespace OpenSim.Region.Framework.Scenes
copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 1); copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 1);
copy.HasGroupChanged = true; copy.HasGroupChanged = true;
copy.ScheduleGroupForFullUpdate(); //copy.ScheduleGroupForFullUpdate();
copy.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //new object, all property values are new
copy.ResumeScripts(); copy.ResumeScripts();
// required for physics to update it's position // required for physics to update it's position
@ -1974,7 +1965,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
//if we need to debug the script engine with a viewer attaching to it, //if we need to debug the script engine with a viewer attaching to it,
//we need to schedule updates to be sent to the viewer //we need to schedule updates to be sent to the viewer
oldSog.ScheduleGroupForFullUpdate(); oldSog.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None);
} }
} }
else else

View File

@ -1022,7 +1022,8 @@ namespace OpenSim.Region.Framework.Scenes
RootPart.RemFlag(PrimFlags.TemporaryOnRez); RootPart.RemFlag(PrimFlags.TemporaryOnRez);
AttachToBackup(); AttachToBackup();
m_scene.EventManager.TriggerParcelPrimCountTainted(); m_scene.EventManager.TriggerParcelPrimCountTainted();
m_rootPart.ScheduleFullUpdate(); //m_rootPart.ScheduleFullUpdate();
m_rootPart.ScheduleFullUpdate(SceneObjectPartProperties.AttachmentPoint); //Physics properties, such as Position, OffsetPosition, etc, should be tainted in ApplyPhysics()
m_rootPart.ClearUndoState(); m_rootPart.ClearUndoState();
} }
@ -1295,7 +1296,8 @@ namespace OpenSim.Region.Framework.Scenes
m_scene.RemoveGroupTarget(this); m_scene.RemoveGroupTarget(this);
} }
ScheduleGroupForFullUpdate(); //ScheduleGroupForFullUpdate();
ScheduleGroupForFullUpdate(SceneObjectPartProperties.Flags);
} }
public void SetText(string text, Vector3 color, double alpha) public void SetText(string text, Vector3 color, double alpha)
@ -1307,7 +1309,8 @@ namespace OpenSim.Region.Framework.Scenes
Text = text; Text = text;
HasGroupChanged = true; HasGroupChanged = true;
m_rootPart.ScheduleFullUpdate(); //m_rootPart.ScheduleFullUpdate();
m_rootPart.ScheduleFullUpdate(SceneObjectPartProperties.Text);
} }
/// <summary> /// <summary>
@ -1541,7 +1544,8 @@ namespace OpenSim.Region.Framework.Scenes
dupe.HasGroupChanged = true; dupe.HasGroupChanged = true;
dupe.AttachToBackup(); dupe.AttachToBackup();
ScheduleGroupForFullUpdate(); //ScheduleGroupForFullUpdate();
ScheduleGroupForFullUpdate(SceneObjectPartProperties.None); //This full-update is triggered by copying, no property changed
} }
return dupe; return dupe;
@ -1794,7 +1798,8 @@ namespace OpenSim.Region.Framework.Scenes
ApplyNextOwnerPermissions(); ApplyNextOwnerPermissions();
} }
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(SceneObjectPartProperties.OwnerID);
} }
/// <summary> /// <summary>
@ -1919,33 +1924,38 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary> /// <summary>
/// Schedule a full update for this scene object /// Schedule a full update for this scene object
/// </summary> /// </summary>
public void ScheduleGroupForFullUpdate() //public void ScheduleGroupForFullUpdate()
public void ScheduleGroupForFullUpdate(SceneObjectPartProperties property)
{ {
// if (IsAttachment) // if (IsAttachment)
// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, LocalId); // m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, LocalId);
checkAtTargets(); checkAtTargets();
RootPart.ScheduleFullUpdate(); //RootPart.ScheduleFullUpdate();
RootPart.ScheduleFullUpdate(property);
SceneObjectPart[] parts = m_parts.GetArray(); SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++) for (int i = 0; i < parts.Length; i++)
{ {
SceneObjectPart part = parts[i]; SceneObjectPart part = parts[i];
if (part != RootPart) if (part != RootPart)
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(property);
} }
} }
/// <summary> /// <summary>
/// Schedule a terse update for this scene object /// Schedule a terse update for this scene object
/// </summary> /// </summary>
public void ScheduleGroupForTerseUpdate() //public void ScheduleGroupForTerseUpdate()
public void ScheduleGroupForTerseUpdate(SceneObjectPartProperties property)
{ {
// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); // m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID);
SceneObjectPart[] parts = m_parts.GetArray(); SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++) for (int i = 0; i < parts.Length; i++)
parts[i].ScheduleTerseUpdate(); //parts[i].ScheduleTerseUpdate();
parts[i].ScheduleTerseUpdate(property);
} }
/// <summary> /// <summary>
@ -2703,7 +2713,8 @@ namespace OpenSim.Region.Framework.Scenes
HasGroupChanged = true; HasGroupChanged = true;
part.TriggerScriptChangedEvent(Changed.SCALE); part.TriggerScriptChangedEvent(Changed.SCALE);
ScheduleGroupForFullUpdate(); //ScheduleGroupForFullUpdate();
ScheduleGroupForFullUpdate(SceneObjectPartProperties.None); //above actions only update Scale for the given part, and part.Resize() will taint Scale as updated
//if (part.UUID == m_rootPart.UUID) //if (part.UUID == m_rootPart.UUID)
//{ //{
@ -2855,7 +2866,8 @@ namespace OpenSim.Region.Framework.Scenes
part.StoreUndoState(); part.StoreUndoState();
HasGroupChanged = true; HasGroupChanged = true;
m_rootPart.TriggerScriptChangedEvent(Changed.SCALE); m_rootPart.TriggerScriptChangedEvent(Changed.SCALE);
ScheduleGroupForTerseUpdate(); //ScheduleGroupForTerseUpdate();
ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Scale);
} }
} }
@ -2896,7 +2908,8 @@ namespace OpenSim.Region.Framework.Scenes
//we need to do a terse update even if the move wasn't allowed //we need to do a terse update even if the move wasn't allowed
// so that the position is reset in the client (the object snaps back) // so that the position is reset in the client (the object snaps back)
ScheduleGroupForTerseUpdate(); //ScheduleGroupForTerseUpdate();
ScheduleGroupForTerseUpdate(SceneObjectPartProperties.GroupPosition);
} }
/// <summary> /// <summary>
@ -2959,7 +2972,8 @@ namespace OpenSim.Region.Framework.Scenes
AbsolutePosition = newPos; AbsolutePosition = newPos;
HasGroupChanged = true; HasGroupChanged = true;
ScheduleGroupForTerseUpdate(); //ScheduleGroupForTerseUpdate();
ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Position);
} }
public void OffsetForNewRegion(Vector3 offset) public void OffsetForNewRegion(Vector3 offset)
@ -2991,7 +3005,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
HasGroupChanged = true; HasGroupChanged = true;
ScheduleGroupForTerseUpdate(); //ScheduleGroupForTerseUpdate();
ScheduleGroupForTerseUpdate(SceneObjectPartProperties.None); //Above actions only update m_rootPart's RotationOffset, and m_rootPart.UpdateRotation will taint RotationOffset as updated
} }
/// <summary> /// <summary>
@ -3017,7 +3032,8 @@ namespace OpenSim.Region.Framework.Scenes
AbsolutePosition = pos; AbsolutePosition = pos;
HasGroupChanged = true; HasGroupChanged = true;
ScheduleGroupForTerseUpdate(); //ScheduleGroupForTerseUpdate();
ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Position); //RotationOffset is only updated for m_rootPart, and m_rootPart.UpdateRotation should already taint RotationOffset as updated
} }
/// <summary> /// <summary>
@ -3104,7 +3120,8 @@ namespace OpenSim.Region.Framework.Scenes
Quaternion newRot = primsRot * oldParentRot; Quaternion newRot = primsRot * oldParentRot;
newRot *= Quaternion.Inverse(axRot); newRot *= Quaternion.Inverse(axRot);
prim.RotationOffset = newRot; prim.RotationOffset = newRot;
prim.ScheduleTerseUpdate(); //prim.ScheduleTerseUpdate();
prim.ScheduleTerseUpdate(SceneObjectPartProperties.RotationOffset | SceneObjectPartProperties.OffsetPosition);
} }
} }
@ -3118,7 +3135,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
m_rootPart.ScheduleTerseUpdate(); //m_rootPart.ScheduleTerseUpdate();
m_rootPart.ScheduleTerseUpdate(SceneObjectPartProperties.RotationOffset);
} }
#endregion #endregion

View File

@ -311,7 +311,8 @@ namespace OpenSim.Region.Framework.Scenes
/// ///
/// TODO - This should be an enumeration /// TODO - This should be an enumeration
/// </summary> /// </summary>
private byte m_updateFlag; //private byte m_updateFlag;
protected byte m_updateFlag;
private PhysicsActor m_physActor; private PhysicsActor m_physActor;
protected Vector3 m_acceleration; protected Vector3 m_acceleration;
@ -352,6 +353,7 @@ namespace OpenSim.Region.Framework.Scenes
private bool m_forceMouselook; private bool m_forceMouselook;
// TODO: Collision sound should have default. // TODO: Collision sound should have default.
//private UUID m_collisionSound;
protected UUID m_collisionSound; protected UUID m_collisionSound;
private float m_collisionSoundVolume; private float m_collisionSoundVolume;
@ -2749,7 +2751,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
//m_parentGroup.RootPart.m_groupPosition = newpos; //m_parentGroup.RootPart.m_groupPosition = newpos;
} }
ScheduleTerseUpdate(); //ScheduleTerseUpdate();
ScheduleTerseUpdate(SceneObjectPartProperties.Position);
//SendTerseUpdateToAllClients(); //SendTerseUpdateToAllClients();
} }
@ -2839,7 +2842,8 @@ namespace OpenSim.Region.Framework.Scenes
m_shape.Scale = scale; m_shape.Scale = scale;
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
ScheduleFullUpdate(); //ScheduleFullUpdate();
ScheduleFullUpdate(SceneObjectPartProperties.Scale);
} }
public void RotLookAt(Quaternion target, float strength, float damping) public void RotLookAt(Quaternion target, float strength, float damping)
@ -2881,7 +2885,8 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary> /// <summary>
/// Schedules this prim for a full update /// Schedules this prim for a full update
/// </summary> /// </summary>
public void ScheduleFullUpdate() //public void ScheduleFullUpdate() :: SYMMETRIC SYNC: changed the interface so that we can identify which property triggers calling this function
public virtual void ScheduleFullUpdate(SceneObjectPartProperties sopProperty)
{ {
// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); // m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId);
@ -2909,20 +2914,14 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}", // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}",
// UUID, Name, TimeStampFull); // UUID, Name, TimeStampFull);
//SYMMETRIC SYNC
//update information (timestamp, actorID, etc) needed for synchronization across copies of Scene
//SyncInfoUpdate();
//end of SYMMETRIC SYNC
} }
/// <summary> /// <summary>
/// Schedule a terse update for this prim. Terse updates only send position, /// Schedule a terse update for this prim. Terse updates only send position,
/// rotation, velocity, rotational velocity and shape information. /// rotation, velocity, rotational velocity and shape information.
/// </summary> /// </summary>
public void ScheduleTerseUpdate() //public void ScheduleTerseUpdate()
public virtual void ScheduleTerseUpdate(SceneObjectPartProperties sopProperty)
{ {
if (m_updateFlag < 1) if (m_updateFlag < 1)
{ {
@ -2937,13 +2936,6 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}", // "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}",
// UUID, Name, TimeStampTerse); // UUID, Name, TimeStampTerse);
//SYMMETRIC SYNC
//update information (timestamp, actorID, etc) needed for synchronization across copies of Scene
//SyncInfoUpdate();
//end of SYMMETRIC SYNC
} }
} }
@ -2981,8 +2973,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
//public void SculptTextureCallback(UUID textureID, AssetBase texture) public void SculptTextureCallback(UUID textureID, AssetBase texture)
public virtual void SculptTextureCallback(UUID textureID, AssetBase texture)
{ {
if (m_shape.SculptEntry) if (m_shape.SculptEntry)
{ {
@ -3164,10 +3155,10 @@ namespace OpenSim.Region.Framework.Scenes
ClearUpdateSchedule(); ClearUpdateSchedule();
//SYMMETRIC SYNC //SYMMETRIC SYNC
if (m_parentGroup.Scene.RegionSyncModule == null) if (m_parentGroup.Scene.RegionSyncModule != null)
return; {
m_parentGroup.Scene.RegionSyncModule.QueueSceneObjectPartForUpdate((SceneObjectPart)this); m_parentGroup.Scene.RegionSyncModule.QueueSceneObjectPartForUpdate((SceneObjectPart)this);
}
//end of SYMMETRIC SYNC //end of SYMMETRIC SYNC
} }
@ -3274,8 +3265,7 @@ namespace OpenSim.Region.Framework.Scenes
}); });
} }
//public void SetAttachmentPoint(uint AttachmentPoint) public void SetAttachmentPoint(uint AttachmentPoint)
public virtual void SetAttachmentPoint(uint AttachmentPoint)
{ {
this.AttachmentPoint = AttachmentPoint; this.AttachmentPoint = AttachmentPoint;
@ -3291,8 +3281,7 @@ namespace OpenSim.Region.Framework.Scenes
// save the attachment point. // save the attachment point.
//if (AttachmentPoint != 0) //if (AttachmentPoint != 0)
//{ //{
m_shape.State = (byte)AttachmentPoint; m_shape.State = (byte)AttachmentPoint;
//} //}
} }
@ -3633,14 +3622,16 @@ namespace OpenSim.Region.Framework.Scenes
Text = text; Text = text;
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
ScheduleFullUpdate(); //ScheduleFullUpdate();
ScheduleFullUpdate(SceneObjectPartProperties.Text);
} }
public void StopLookAt() public void StopLookAt()
{ {
m_parentGroup.stopLookAt(); m_parentGroup.stopLookAt();
m_parentGroup.ScheduleGroupForTerseUpdate(); //m_parentGroup.ScheduleGroupForTerseUpdate();
m_parentGroup.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.None);//in stopLookAt(), PhysicsActor shall already take care of tainting which properties have been updated
} }
/// <summary> /// <summary>
@ -3662,7 +3653,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_parentGroup.stopMoveToTarget(); m_parentGroup.stopMoveToTarget();
m_parentGroup.ScheduleGroupForTerseUpdate(); //m_parentGroup.ScheduleGroupForTerseUpdate();
m_parentGroup.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.None); //in stopMoveToTarget(), PhysicsActor shall already take care of tainting which properties have been updated
//m_parentGroup.ScheduleGroupForFullUpdate(); //m_parentGroup.ScheduleGroupForFullUpdate();
} }
@ -4210,8 +4202,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
ScheduleFullUpdate(); //ScheduleFullUpdate();
ScheduleFullUpdate(SceneObjectPartProperties.Shape);
} }
public void UpdateGroupPosition(Vector3 pos) public void UpdateGroupPosition(Vector3 pos)
@ -4222,7 +4214,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
GroupPosition = newPos; GroupPosition = newPos;
ScheduleTerseUpdate(); //ScheduleTerseUpdate();
ScheduleFullUpdate(SceneObjectPartProperties.GroupPosition);
} }
} }
@ -4254,7 +4247,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
OffsetPosition = newPos; OffsetPosition = newPos;
ScheduleTerseUpdate(); //ScheduleTerseUpdate();
ScheduleFullUpdate(SceneObjectPartProperties.OffsetPosition);
} }
} }
@ -4543,7 +4537,8 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
ScheduleFullUpdate(); //ScheduleFullUpdate();
ScheduleFullUpdate(SceneObjectPartProperties.Flags);
} }
public void UpdateRotation(Quaternion rot) public void UpdateRotation(Quaternion rot)
@ -4555,7 +4550,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
RotationOffset = rot; RotationOffset = rot;
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
ScheduleTerseUpdate(); //ScheduleTerseUpdate();
ScheduleFullUpdate(SceneObjectPartProperties.RotationOffset);
} }
} }
@ -4563,8 +4559,7 @@ namespace OpenSim.Region.Framework.Scenes
/// Update the shape of this part. /// Update the shape of this part.
/// </summary> /// </summary>
/// <param name="shapeBlock"></param> /// <param name="shapeBlock"></param>
//public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock) public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock)
public virtual void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock)
{ {
m_shape.PathBegin = shapeBlock.PathBegin; m_shape.PathBegin = shapeBlock.PathBegin;
m_shape.PathEnd = shapeBlock.PathEnd; m_shape.PathEnd = shapeBlock.PathEnd;
@ -4601,7 +4596,8 @@ namespace OpenSim.Region.Framework.Scenes
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
TriggerScriptChangedEvent(Changed.SHAPE); TriggerScriptChangedEvent(Changed.SHAPE);
ScheduleFullUpdate(); //ScheduleFullUpdate();
ScheduleFullUpdate(SceneObjectPartProperties.Shape);
} }
/// <summary> /// <summary>
@ -4639,8 +4635,7 @@ namespace OpenSim.Region.Framework.Scenes
/// Update the texture entry for this part. /// Update the texture entry for this part.
/// </summary> /// </summary>
/// <param name="textureEntry"></param> /// <param name="textureEntry"></param>
//public void UpdateTextureEntry(byte[] textureEntry) public void UpdateTextureEntry(byte[] textureEntry)
public virtual void UpdateTextureEntry(byte[] textureEntry)
{ {
m_shape.TextureEntry = textureEntry; m_shape.TextureEntry = textureEntry;
TriggerScriptChangedEvent(Changed.TEXTURE); TriggerScriptChangedEvent(Changed.TEXTURE);
@ -4649,7 +4644,8 @@ namespace OpenSim.Region.Framework.Scenes
//This is madness.. //This is madness..
//ParentGroup.ScheduleGroupForFullUpdate(); //ParentGroup.ScheduleGroupForFullUpdate();
//This is sparta //This is sparta
ScheduleFullUpdate(); //ScheduleFullUpdate();
ScheduleFullUpdate(SceneObjectPartProperties.Shape);
} }
public void aggregateScriptEvents() public void aggregateScriptEvents()
@ -4717,7 +4713,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents() since m_parentGroup == null", Name, LocalId); // "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents() since m_parentGroup == null", Name, LocalId);
ScheduleFullUpdate(); //ScheduleFullUpdate();
ScheduleFullUpdate(SceneObjectPartProperties.Flags);
return; return;
} }
@ -4740,7 +4737,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents()", Name, LocalId); // "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents()", Name, LocalId);
ScheduleFullUpdate(); //ScheduleFullUpdate();
ScheduleFullUpdate(SceneObjectPartProperties.Flags);
} }
} }
@ -4944,44 +4942,6 @@ namespace OpenSim.Region.Framework.Scenes
set { m_lastUpdateTimeStamp = value; } set { m_lastUpdateTimeStamp = value; }
} }
/// <summary>
/// Schedules this prim for a full update, without changing the timestamp or actorID (info on when and who modified any property).
/// NOTE: this is the same as the original SceneObjectPart.ScheduleFullUpdate().
/// </summary>
public void ScheduleFullUpdate_SyncInfoUnchanged()
{
//m_log.DebugFormat("[SCENE OBJECT PART]: ScheduleFullUpdate_SyncInfoUnchanged for {0} {1}", Name, LocalId);
if (m_parentGroup != null)
{
m_parentGroup.QueueForUpdateCheck();
}
int timeNow = Util.UnixTimeSinceEpoch();
// If multiple updates are scheduled on the same second, we still need to perform all of them
// So we'll force the issue by bumping up the timestamp so that later processing sees these need
// to be performed.
if (timeNow <= TimeStampFull)
{
TimeStampFull += 1;
}
else
{
TimeStampFull = (uint)timeNow;
}
m_updateFlag = 2;
// m_log.DebugFormat(
// "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}",
// UUID, Name, TimeStampFull);
}
#endregion #endregion
} }
@ -5037,6 +4997,164 @@ namespace OpenSim.Region.Framework.Scenes
} }
/*
public enum SceneObjectPartProperties:ulong
{
//Following properties copied from SceneObjectSerializer(),
AllowedDrop = (ulong) 1<<0,
CreatorID = (ulong) 1<<1,
CreatorData = (ulong) 1 <<2,
FolderID = (ulong) 1 << 3,
InventorySerial = (ulong) 1 << 4,
TaskInventory = (ulong) 1 << 5,
//UUID",
//LocalId",
Name = (ulong) 1 << 6,
Material = (ulong) 1 <<7,
PassTouches = (ulong) 1 << 8,
RegionHandle = (ulong) 1 << 9,
ScriptAccessPin = (ulong) 1 << 10,
GroupPosition = (ulong) 1 << 11,
OffsetPosition = (ulong) 1 << 12,
RotationOffset = (ulong) 1 << 13,
Velocity = (ulong) 1 << 14,
AngularVelocity = (ulong) 1 << 15,
//"Acceleration",
SOP_Acceleration = (ulong) 1 << 16, //SOP and PA read/write their own local copies of acceleration, so we distinguish the copies
Description = (ulong) 1 << 17,
Color = (ulong) 1 << 18,
Text = (ulong) 1 << 19,
SitName = (ulong) 1 << 20,
TouchName = (ulong) 1 << 21,
LinkNum = (ulong) 1 << 22,
ClickAction = (ulong) 1 << 23,
Shape = (ulong) 1 << 24,
Scale = (ulong) 1 << 25,
UpdateFlag = (ulong) 1 << 26,
SitTargetOrientation = (ulong) 1 << 27,
SitTargetPosition = (ulong) 1 << 28,
SitTargetPositionLL = (ulong) 1 << 29,
SitTargetOrientationLL = (ulong) 1 << 30,
ParentID = (ulong)1 << 31,
CreationDate = (ulong) 1 << 32,
Category = (ulong) 1 << 33,
SalePrice = (ulong) 1 << 34,
ObjectSaleType = (ulong) 1 << 35,
OwnershipCost = (ulong) 1 << 36,
GroupID = (ulong) 1 << 37,
OwnerID = (ulong) 1 << 38,
LastOwnerID = (ulong) 1 << 39,
BaseMask = (ulong) 1 << 40,
OwnerMask = (ulong) 1 << 41,
GroupMask = (ulong) 1 << 42,
EveryoneMask = (ulong) 1 << 43,
NextOwnerMask = (ulong) 1 << 44,
Flags = (ulong) 1 << 45,
CollisionSound = (ulong) 1 << 46,
CollisionSoundVolume = (ulong) 1 << 47,
MediaUrl = (ulong) 1 << 48,
TextureAnimation = (ulong) 1 << 49,
ParticleSystem = (ulong) 1 << 50,
//Property names below copied from PhysicsActor, they are necessary in synchronization, but not covered the above properties
//Physics properties "Velocity" is covered above
Position = (ulong) 1 << 51,
Size = (ulong) 1 << 52,
Force = (ulong) 1 << 53,
RotationalVelocity = (ulong) 1 << 54,
PA_Acceleration = (ulong) 1 << 55,
Torque = (ulong) 1 << 56,
Orientation = (ulong) 1 << 57,
IsPhysical = (ulong) 1 << 58,
Flying = (ulong) 1 << 59,
Buoyancy = (ulong) 1 << 60,
//To be handled
AttachmentPoint = (ulong)1 << 61,
FullUpdate = UInt64.MaxValue
}
*/
public enum SceneObjectPartProperties
{
None,
//Following properties copied from SceneObjectSerializer(),
AllowedDrop ,
CreatorID ,
CreatorData ,
FolderID ,
InventorySerial,
TaskInventory,
//UUID",
//LocalId",
Name,
Material,
PassTouches,
RegionHandle,
ScriptAccessPin,
GroupPosition,
OffsetPosition,
RotationOffset,
Velocity,
AngularVelocity,
//"Acceleration",
SOP_Acceleration, //SOP and PA read/write their own local copies of acceleration, so we distinguish the copies
Description,
Color,
Text,
SitName,
TouchName,
LinkNum,
ClickAction,
Shape,
Scale,
UpdateFlag,
SitTargetOrientation,
SitTargetPosition,
SitTargetPositionLL,
SitTargetOrientationLL,
ParentID,
CreationDate,
Category,
SalePrice,
ObjectSaleType,
OwnershipCost,
GroupID,
OwnerID,
LastOwnerID,
BaseMask,
OwnerMask,
GroupMask,
EveryoneMask,
NextOwnerMask,
Flags,
CollisionSound,
CollisionSoundVolume,
MediaUrl,
TextureAnimation,
ParticleSystem,
//Property names below copied from PhysicsActor, they are necessary in synchronization, but not covered the above properties
//Physics properties "Velocity" is covered above
Position,
Size,
Force,
RotationalVelocity,
PA_Acceleration,
Torque,
Orientation,
IsPhysical,
Flying,
Buoyancy,
//To be handled in serialization/deserizaltion for synchronization
IsSelected,
AttachmentPoint,
AttachedPos,
Sound, //This indicates any Sound related property has changed: Sound, SoundGain, SoundFlags,SoundRadius,
//Addition properties to be added here
//Client Manager may want to add some property here that viewers care about and should be synchronized across actors
FullUpdate,
}
public class SceneObjectPart : SceneObjectPartBase public class SceneObjectPart : SceneObjectPartBase
{ {
@ -5064,10 +5182,8 @@ namespace OpenSim.Region.Framework.Scenes
//TODO: serialization and deserialization processors to be added in SceneObjectSerializer //TODO: serialization and deserialization processors to be added in SceneObjectSerializer
//The following variables are initialized when RegionSyncModule reads the config file for mapping of properties and buckets //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 Dictionary<SceneObjectPartProperties, string> m_primPropertyBucketMap = null;
private static List<string> m_propertyBucketNames = 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 string m_localActorID = "";
//private static int m_bucketCount = 0; //private static int m_bucketCount = 0;
@ -5076,6 +5192,8 @@ 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, 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.
@ -5084,6 +5202,7 @@ namespace OpenSim.Region.Framework.Scenes
//The list of each prim's properties. This is the list of properties that matter in synchronizing prim copies on different actors. //The list of each prim's properties. This is the list of properties that matter in synchronizing prim copies on different actors.
//This list is created based on properties included in the serialization/deserialization process (see SceneObjectSerializer()) and the //This list is created based on properties included in the serialization/deserialization process (see SceneObjectSerializer()) and the
//properties Physics Engine needs to synchronize to other actors. //properties Physics Engine needs to synchronize to other actors.
/*
public static List<string> PropertyList = new List<string>() public static List<string> PropertyList = new List<string>()
{ {
//Following properties copied from SceneObjectSerializer() //Following properties copied from SceneObjectSerializer()
@ -5154,9 +5273,10 @@ namespace OpenSim.Region.Framework.Scenes
"Flying", "Flying",
"Buoyancy", "Buoyancy",
}; };
* */
public static void InitializePropertyBucketInfo(Dictionary<string, string> propertyBucketMap, List<string> bucketNames, string actorID) public static void InitializePropertyBucketInfo(Dictionary<SceneObjectPartProperties, string> propertyBucketMap, List<string> bucketNames, string actorID)
{ {
m_primPropertyBucketMap = propertyBucketMap; m_primPropertyBucketMap = propertyBucketMap;
m_propertyBucketNames = bucketNames; m_propertyBucketNames = bucketNames;
@ -5202,51 +5322,18 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
/// <summary>
/// Update the properties of this SOP with the values in updatedPart.
/// </summary>
/// <param name="updatedPart"></param>
/// <param name="bucketName"></param>
private void GeneralBucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName) private void GeneralBucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName)
{ {
//NOTE!!!!!!!! Need to cast the local copy to SceneObjectPartBase in order not to trigger UpdateBucketSyncInfo(),
//since the property updates inside this function are not due to local operations.
SceneObjectPartBase localPart = (SceneObjectPartBase)this;
lock (m_bucketUpdateLocks[bucketName]) lock (m_bucketUpdateLocks[bucketName])
{ {
localPart.AllowedDrop = updatedPart.AllowedDrop;
localPart.Shape = updatedPart.Shape;
bool collisionSoundUpdated = UpdateCollisionSound(updatedPart.CollisionSound);
m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp;
m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID;
if (collisionSoundUpdated)
{
//If the local actor is Script Engine, it will catch this evnet and trigger aggregateScriptEvents()
m_parentGroup.Scene.EventManager.TriggerAggregateScriptEvents(this);
}
} }
} }
private void PhysicsBucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName) private void PhysicsBucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName)
{ {
//NOTE!!!!!!!! Need to cast the local copy to SceneObjectPartBase in order not to trigger UpdateBucketSyncInfo(),
//since the property updates inside this function are not due to local operations.
SceneObjectPartBase localPart = (SceneObjectPartBase)this;
lock (m_bucketUpdateLocks[bucketName]) lock (m_bucketUpdateLocks[bucketName])
{ {
localPart.GroupPosition = updatedPart.GroupPosition;
m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp;
m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID;
} }
} }
@ -5279,6 +5366,10 @@ 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)
@ -5290,16 +5381,59 @@ namespace OpenSim.Region.Framework.Scenes
m_syncEnabled = true; m_syncEnabled = true;
} }
//For tainitng and clearing taints, do i need to lock on m_bucketSyncTaint?
public void TaintBucketSyncInfo(SceneObjectPartProperties property)
{
if (m_syncEnabled && m_bucketSyncTainted.Count > 0)
{
string bucketName = m_primPropertyBucketMap[property];
m_bucketSyncTainted[bucketName] = true;
}
}
/*
public void ClearBucketTaint()
{
if (m_syncEnabled && m_bucketSyncTainted.Count > 0)
{
foreach (KeyValuePair<string, bool> pair in m_bucketSyncTainted)
{
pair.Value = false;
}
}
}
* */
/// <summary>
/// Update the timestamp information of each property bucket, and clear out the taint on each bucket.
/// </summary>
public void UpdateTaintedBucketSyncInfo()
{
if (m_syncEnabled)
{
long timeStamp = DateTime.Now.Ticks;
foreach (KeyValuePair<string, BucketSyncInfo> pair in m_bucketSyncInfoList)
{
string bucketName = pair.Key;
if (m_bucketSyncTainted[bucketName])
{
m_bucketSyncInfoList[bucketName].UpdateSyncInfo(timeStamp, m_localActorID);
m_bucketSyncTainted[bucketName] = false;
}
}
}
}
/// <summary> /// <summary>
/// Update the timestamp and actorID information of the bucket the given property belongs to. /// Update the timestamp and actorID information of the bucket the given property belongs to.
/// </summary> /// </summary>
/// <param name="propertyName">Name of the property. Make sure the spelling is consistent with what are defined in PropertyList</param> /// <param name="propertyName">Name of the property. Make sure the spelling is consistent with what are defined in PropertyList</param>
public void UpdateBucketSyncInfo(string propertyName) public void UpdateBucketSyncInfo(SceneObjectPartProperties property)
{ {
if (m_syncEnabled && m_bucketSyncInfoList != null && m_bucketSyncInfoList.Count > 0) if (m_syncEnabled && m_bucketSyncInfoList != null && m_bucketSyncInfoList.Count > 0)
{ {
//int bucketIndex = m_primPropertyBucketMap[propertyName]; //int bucketIndex = m_primPropertyBucketMap[propertyName];
string bucketName = m_primPropertyBucketMap[propertyName]; string bucketName = m_primPropertyBucketMap[property];
long timeStamp = DateTime.Now.Ticks; long timeStamp = DateTime.Now.Ticks;
if (m_bucketSyncInfoList.ContainsKey(bucketName)) if (m_bucketSyncInfoList.ContainsKey(bucketName))
{ {
@ -5371,95 +5505,53 @@ namespace OpenSim.Region.Framework.Scenes
} }
#region new property access functions public override void ScheduleFullUpdate(SceneObjectPartProperties property)
//(only properties relevant for synchronization purpose are implemented here)
new public bool AllowedDrop
{ {
get { return base.AllowedDrop; } base.ScheduleFullUpdate(property);
set TaintBucketSyncInfo(property);
{ }
base.AllowedDrop = value;
UpdateBucketSyncInfo("AllowedDrop"); public override void ScheduleTerseUpdate(SceneObjectPartProperties property)
} {
base.ScheduleTerseUpdate(property);
TaintBucketSyncInfo(property);
} }
/// <summary> /// <summary>
/// The position of the entire group that this prim belongs to. /// Schedules this prim for a full update, without changing the timestamp or actorID (info on when and who modified any property).
/// NOTE: this is the same as the original SceneObjectPart.ScheduleFullUpdate().
/// </summary> /// </summary>
new public Vector3 GroupPosition public void ScheduleFullUpdate_SyncInfoUnchanged()
{ {
get { return base.GroupPosition; } //m_log.DebugFormat("[SCENE OBJECT PART]: ScheduleFullUpdate_SyncInfoUnchanged for {0} {1}", Name, LocalId);
set
if (m_parentGroup != null)
{ {
base.GroupPosition = value; m_parentGroup.QueueForUpdateCheck();
UpdateBucketSyncInfo("GroupPosition");
} }
}
new public Vector3 OffsetPosition int timeNow = Util.UnixTimeSinceEpoch();
{
get { return base.OffsetPosition; } // If multiple updates are scheduled on the same second, we still need to perform all of them
set // So we'll force the issue by bumping up the timestamp so that later processing sees these need
// to be performed.
if (timeNow <= TimeStampFull)
{ {
base.OffsetPosition = value; TimeStampFull += 1;
UpdateBucketSyncInfo("OffsetPosition");
} }
} else
new public PrimitiveBaseShape Shape
{
get { return base.Shape; }
set
{ {
base.Shape = value; TimeStampFull = (uint)timeNow;
UpdateBucketSyncInfo("Shape");
} }
m_updateFlag = 2;
// m_log.DebugFormat(
// "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}",
// UUID, Name, TimeStampFull);
} }
//For functions that update SOP properties, override them so that when they are called from SOPBase (but the object itself is an instance of SOP)
//the following implementations will be called instead of the same name functions in SOPBase.
public override void SculptTextureCallback(UUID textureID, AssetBase texture)
{
base.SculptTextureCallback(textureID, texture);
UpdateBucketSyncInfo("Shape");
}
public override void SetAttachmentPoint(uint AttachmentPoint)
{
base.SetAttachmentPoint(AttachmentPoint);
UpdateBucketSyncInfo("Shape");
}
public void UpdateExtraParam(ushort type, bool inUse, byte[] data)
{
base.UpdateExtraParam(type, inUse, data);
UpdateBucketSyncInfo("Shape");
}
public override void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock)
{
base.UpdateShape(shapeBlock);
UpdateBucketSyncInfo("Shape");
}
public override void UpdateTextureEntry(byte[] textureEntry)
{
base.UpdateTextureEntry(textureEntry);
UpdateBucketSyncInfo("Shape");
}
public override void Resize(Vector3 scale)
{
base.Resize(scale);
UpdateBucketSyncInfo("Scale");
}
#endregion //new property access functions
private bool UpdateCollisionSound(UUID updatedCollisionSound) private bool UpdateCollisionSound(UUID updatedCollisionSound)
{ {
if (this.CollisionSound != updatedCollisionSound) if (this.CollisionSound != updatedCollisionSound)
@ -5469,7 +5561,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
return false; return false;
} }
} }
//end of SYMMETRIC SYNC //end of SYMMETRIC SYNC

View File

@ -294,7 +294,7 @@ namespace OpenSim.Region.Framework.Scenes
m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
m_part.ParentGroup.AddActiveScriptCount(1); m_part.ParentGroup.AddActiveScriptCount(1);
m_part.ScheduleFullUpdate(); m_part.ScheduleFullUpdate(SceneObjectPartProperties.Flags | SceneObjectPartProperties.TaskInventory);
return; return;
} }
@ -322,7 +322,7 @@ namespace OpenSim.Region.Framework.Scenes
m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
m_part.ParentGroup.AddActiveScriptCount(1); m_part.ParentGroup.AddActiveScriptCount(1);
m_part.ScheduleFullUpdate(); m_part.ScheduleFullUpdate(SceneObjectPartProperties.Flags | SceneObjectPartProperties.TaskInventory);
} }
} }
} }
@ -546,7 +546,7 @@ namespace OpenSim.Region.Framework.Scenes
m_part.ParentGroup.HasGroupChanged = true; m_part.ParentGroup.HasGroupChanged = true;
//SYMMETRIC SYNC: add ScheduleFullUpdate to enable synchronization across actors //SYMMETRIC SYNC: add ScheduleFullUpdate to enable synchronization across actors
m_part.ScheduleFullUpdate(); m_part.ScheduleFullUpdate(SceneObjectPartProperties.TaskInventory | SceneObjectPartProperties.InventorySerial);
} }
/// <summary> /// <summary>
@ -766,7 +766,7 @@ namespace OpenSim.Region.Framework.Scenes
if (!ContainsScripts()) if (!ContainsScripts())
m_part.RemFlag(PrimFlags.Scripted); m_part.RemFlag(PrimFlags.Scripted);
m_part.ScheduleFullUpdate(); m_part.ScheduleFullUpdate(SceneObjectPartProperties.TaskInventory);
return type; return type;

View File

@ -91,7 +91,8 @@ namespace OpenSim.Region.Framework.Scenes
part.RotationOffset = Rotation; part.RotationOffset = Rotation;
if (Scale != Vector3.Zero) if (Scale != Vector3.Zero)
part.Resize(Scale); part.Resize(Scale);
part.ParentGroup.ScheduleGroupForTerseUpdate(); //part.ParentGroup.ScheduleGroupForTerseUpdate();
part.ParentGroup.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Scale);
} }
else else
{ {
@ -99,7 +100,8 @@ namespace OpenSim.Region.Framework.Scenes
part.OffsetPosition = Position; part.OffsetPosition = Position;
part.UpdateRotation(Rotation); part.UpdateRotation(Rotation);
if (Scale != Vector3.Zero) if (Scale != Vector3.Zero)
part.Resize(Scale); part.ScheduleTerseUpdate(); part.Resize(Scale); //part.ScheduleTerseUpdate();
part.ScheduleTerseUpdate(SceneObjectPartProperties.Scale);
} }
part.Undoing = false; part.Undoing = false;
@ -119,7 +121,8 @@ namespace OpenSim.Region.Framework.Scenes
part.UpdateRotation(Rotation); part.UpdateRotation(Rotation);
if (Scale != Vector3.Zero) if (Scale != Vector3.Zero)
part.Resize(Scale); part.Resize(Scale);
part.ParentGroup.ScheduleGroupForTerseUpdate(); //part.ParentGroup.ScheduleGroupForTerseUpdate();
part.ParentGroup.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Scale);
} }
else else
{ {
@ -129,7 +132,9 @@ namespace OpenSim.Region.Framework.Scenes
part.UpdateRotation(Rotation); part.UpdateRotation(Rotation);
if (Scale != Vector3.Zero) if (Scale != Vector3.Zero)
part.Resize(Scale); part.Resize(Scale);
part.ScheduleTerseUpdate(); //part.ScheduleTerseUpdate();
part.ScheduleTerseUpdate(SceneObjectPartProperties.Scale);
} }
part.Undoing = false; part.Undoing = false;

View File

@ -290,7 +290,8 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
((SceneObjectGroup)ent).ApplyPhysics(true); ((SceneObjectGroup)ent).ApplyPhysics(true);
((SceneObjectGroup)ent).AttachToBackup(); ((SceneObjectGroup)ent).AttachToBackup();
((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected. ((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected.
((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(); //((SceneObjectGroup)ent).ScheduleGroupForFullUpdate();
((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //don't know what properties to taint, so just taint all
} }
catch(Exception e) catch(Exception e)
{ {

View File

@ -640,7 +640,8 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
{ {
s_tree.Scale += copse.m_rate; s_tree.Scale += copse.m_rate;
s_tree.ParentGroup.HasGroupChanged = true; s_tree.ParentGroup.HasGroupChanged = true;
s_tree.ScheduleFullUpdate(); //s_tree.ScheduleFullUpdate();
s_tree.ScheduleFullUpdate(SceneObjectPartProperties.Scale);
} }
} }
else else

View File

@ -1411,7 +1411,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
m_host.ClickAction = (byte)action; m_host.ClickAction = (byte)action;
if (m_host.ParentGroup != null) m_host.ParentGroup.HasGroupChanged = true; if (m_host.ParentGroup != null) m_host.ParentGroup.HasGroupChanged = true;
m_host.ScheduleFullUpdate(); //m_host.ScheduleFullUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.ClickAction);
return; return;
} }
@ -1679,7 +1680,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
part.ParentGroup.HasGroupChanged = true; part.ParentGroup.HasGroupChanged = true;
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(SceneObjectPartProperties.Shape);
} }
/// <summary> /// <summary>
@ -1714,7 +1716,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
part.ParentGroup.HasGroupChanged = true; part.ParentGroup.HasGroupChanged = true;
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(SceneObjectPartProperties.Shape);
} }
public LSL_Vector llGetColor(int face) public LSL_Vector llGetColor(int face)
@ -1982,40 +1985,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
targetPos.z = ground; targetPos.z = ground;
SceneObjectGroup parent = part.ParentGroup; SceneObjectGroup parent = part.ParentGroup;
LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos);
//KittyL: edited below parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
if ((World.ScriptEngineToSceneConnectorModule == null))
{
parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
}
else
{
object[] valParams = new object[1];
Vector3 pos = new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z);
valParams[0] = (Vector3)pos;
World.ScriptEngineToSceneConnectorModule.SendSetPrimProperties(m_host.ParentGroup.LocX, m_host.ParentGroup.LocY, m_host.UUID, "pos", (object)valParams);
}
} }
else else
{ {
LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos);
part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
//KittyL: edited below SceneObjectGroup parent = part.ParentGroup;
if ((World.ScriptEngineToSceneConnectorModule == null)) parent.HasGroupChanged = true;
{ //parent.ScheduleGroupForTerseUpdate();
part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); parent.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.OffsetPosition);
SceneObjectGroup parent = part.ParentGroup;
parent.HasGroupChanged = true;
parent.ScheduleGroupForTerseUpdate();
}
else
{
object[] valParams = new object[3];
valParams[0] = (object)rel_vec.x;
valParams[1] = (object)rel_vec.y;
valParams[2] = (object)rel_vec.z;
World.ScriptEngineToSceneConnectorModule.SendSetPrimProperties(m_host.ParentGroup.LocX, m_host.ParentGroup.LocY, m_host.UUID, "pos", (object)valParams);
}
} }
} }
@ -2361,7 +2340,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.SoundFlags = 1; // looping m_host.SoundFlags = 1; // looping
m_host.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable? m_host.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable?
m_host.ScheduleFullUpdate(); //m_host.ScheduleFullUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound);
m_host.SendFullUpdateToAllClients(); m_host.SendFullUpdateToAllClients();
} }
@ -2381,7 +2361,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
prim.SoundFlags = 1; // looping prim.SoundFlags = 1; // looping
prim.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable? prim.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable?
prim.ScheduleFullUpdate(); //prim.ScheduleFullUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound);
prim.SendFullUpdateToAllClients(); prim.SendFullUpdateToAllClients();
} }
} }
@ -2393,7 +2374,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.SoundFlags = 1; // looping m_host.SoundFlags = 1; // looping
m_host.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable? m_host.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable?
m_host.ScheduleFullUpdate(); //m_host.ScheduleFullUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound);
m_host.SendFullUpdateToAllClients(); m_host.SendFullUpdateToAllClients();
} }
@ -2435,7 +2417,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
part.SoundGain = 0; part.SoundGain = 0;
part.SoundFlags = 0; part.SoundFlags = 0;
part.SoundRadius = 0; part.SoundRadius = 0;
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound);
part.SendFullUpdateToAllClients(); part.SendFullUpdateToAllClients();
} }
m_host.ParentGroup.LoopSoundMasterPrim = null; m_host.ParentGroup.LoopSoundMasterPrim = null;
@ -2447,7 +2430,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.SoundGain = 0; m_host.SoundGain = 0;
m_host.SoundFlags = 0; m_host.SoundFlags = 0;
m_host.SoundRadius = 0; m_host.SoundRadius = 0;
m_host.ScheduleFullUpdate(); //m_host.ScheduleFullUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound);
m_host.SendFullUpdateToAllClients(); m_host.SendFullUpdateToAllClients();
} }
} }
@ -2457,7 +2441,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.SoundGain = 0; m_host.SoundGain = 0;
m_host.SoundFlags = 0; m_host.SoundFlags = 0;
m_host.SoundRadius = 0; m_host.SoundRadius = 0;
m_host.ScheduleFullUpdate(); //m_host.ScheduleFullUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound);
m_host.SendFullUpdateToAllClients(); m_host.SendFullUpdateToAllClients();
} }
} }
@ -3384,7 +3369,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
m_host.AngularVelocity = new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate)); m_host.AngularVelocity = new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate));
m_host.ScheduleTerseUpdate(); //m_host.ScheduleTerseUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.AngularVelocity);
m_host.SendTerseUpdateToAllClients(); m_host.SendTerseUpdateToAllClients();
m_host.ParentGroup.HasGroupChanged = true; m_host.ParentGroup.HasGroupChanged = true;
} }
@ -3664,7 +3650,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
parentPrim.TriggerScriptChangedEvent(Changed.LINK); parentPrim.TriggerScriptChangedEvent(Changed.LINK);
parentPrim.RootPart.CreateSelected = true; parentPrim.RootPart.CreateSelected = true;
parentPrim.HasGroupChanged = true; parentPrim.HasGroupChanged = true;
parentPrim.ScheduleGroupForFullUpdate(); //parentPrim.ScheduleGroupForFullUpdate();
//SYMMETRIC SYNC
//Schedule a LinkObject message for synchronization purpose. This will lead to enqueue a LinkObject message in SyncConnector's outgoingQueue,
//so should return quickly.
if (World.RegionSyncModule != null)
{
//Tell other actors to link the SceneObjectParts together as a new group.
//parentGroup.SyncInfoUpdate();
World.RegionSyncModule.SendLinkObject(parentPrim, parentPrim.RootPart, new List<SceneObjectPart>(childPrim.Parts));
}
m_host.ScheduleFullUpdate(SceneObjectPartProperties.None); //SendLinkObject above will synchronize the link operation, no need to taint updates here
//end of SYMMETRIC SYNC
if (client != null) if (client != null)
parentPrim.GetProperties(client); parentPrim.GetProperties(client);
@ -3722,15 +3719,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (linknum == ScriptBaseClass.LINK_ROOT) if (linknum == ScriptBaseClass.LINK_ROOT)
{ {
//SYMMETRIC SYNC
List<SceneObjectGroup> beforeDelinkGroups = new List<SceneObjectGroup>();
beforeDelinkGroups.Add(parentPrim);
List<SceneObjectGroup> afterDelinkGroups = new List<SceneObjectGroup>();
//end of SYMMETRIC SYNC
// Restructuring Multiple Prims. // Restructuring Multiple Prims.
List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
parts.Remove(parentPrim.RootPart); parts.Remove(parentPrim.RootPart);
foreach (SceneObjectPart part in parts) foreach (SceneObjectPart part in parts)
{ {
parentPrim.DelinkFromGroup(part.LocalId, true); parentPrim.DelinkFromGroup(part.LocalId, true);
//SYMMETRIC SYNC
afterDelinkGroups.Add(part.ParentGroup);
} }
parentPrim.HasGroupChanged = true; parentPrim.HasGroupChanged = true;
parentPrim.ScheduleGroupForFullUpdate(); //parentPrim.ScheduleGroupForFullUpdate();
//SYMMETRIC SYNC
//Send out DelinkObject message to other actors to sychronize their object list
if (World.RegionSyncModule != null)
{
World.RegionSyncModule.SendDeLinkObject(parts, beforeDelinkGroups, afterDelinkGroups);
}
parentPrim.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None);
//end of SYMMETRIC SYNC
parentPrim.TriggerScriptChangedEvent(Changed.LINK); parentPrim.TriggerScriptChangedEvent(Changed.LINK);
if (parts.Count > 0) if (parts.Count > 0)
@ -3743,7 +3756,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
newRoot.ParentGroup.LinkToGroup(part.ParentGroup); newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
} }
newRoot.ParentGroup.HasGroupChanged = true; newRoot.ParentGroup.HasGroupChanged = true;
newRoot.ParentGroup.ScheduleGroupForFullUpdate(); //newRoot.ParentGroup.ScheduleGroupForFullUpdate();
//SYMMETRIC SYNC
if (World.RegionSyncModule != null)
{
World.RegionSyncModule.SendLinkObject(newRoot.ParentGroup, newRoot, new List<SceneObjectPart>(newRoot.ParentGroup.Parts));
}
newRoot.ParentGroup.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None);
//end of SYMMETRIC SYNC
} }
} }
else else
@ -3753,7 +3774,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
parentPrim.DelinkFromGroup(childPrim.LocalId, true); parentPrim.DelinkFromGroup(childPrim.LocalId, true);
parentPrim.HasGroupChanged = true; parentPrim.HasGroupChanged = true;
parentPrim.ScheduleGroupForFullUpdate(); //parentPrim.ScheduleGroupForFullUpdate();
//SYMMETRIC SYNC
//Send out DelinkObject message to other actors to sychronize their object list
if (World.RegionSyncModule != null)
{
List<SceneObjectGroup> beforeDelinkGroups = new List<SceneObjectGroup>();
beforeDelinkGroups.Add(parentPrim);
List<SceneObjectGroup> afterDelinkGroups = new List<SceneObjectGroup>();
afterDelinkGroups.Add(childPrim.ParentGroup);
World.RegionSyncModule.SendDeLinkObject(new List<SceneObjectPart>(parentPrim.Parts), beforeDelinkGroups, afterDelinkGroups);
}
//end of SYMMETRIC SYNC
parentPrim.TriggerScriptChangedEvent(Changed.LINK); parentPrim.TriggerScriptChangedEvent(Changed.LINK);
} }
} }
@ -3765,6 +3798,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (parentPrim.RootPart.AttachmentPoint != 0) if (parentPrim.RootPart.AttachmentPoint != 0)
return; // Fail silently if attached return; // Fail silently if attached
//SYMMETRIC SYNC
List<SceneObjectGroup> beforeDelinkGroups = new List<SceneObjectGroup>();
beforeDelinkGroups.Add(parentPrim);
List<SceneObjectGroup> afterDelinkGroups = new List<SceneObjectGroup>();
SceneObjectPart rootPart = parentPrim.RootPart;
//end of SYMMETRIC SYNC
List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
parts.Remove(parentPrim.RootPart); parts.Remove(parentPrim.RootPart);
@ -3772,9 +3812,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{ {
parentPrim.DelinkFromGroup(part.LocalId, true); parentPrim.DelinkFromGroup(part.LocalId, true);
parentPrim.TriggerScriptChangedEvent(Changed.LINK); parentPrim.TriggerScriptChangedEvent(Changed.LINK);
//SYMMETRIC SYNC
afterDelinkGroups.Add(part.ParentGroup);
} }
parentPrim.HasGroupChanged = true; parentPrim.HasGroupChanged = true;
parentPrim.ScheduleGroupForFullUpdate(); //parentPrim.ScheduleGroupForFullUpdate();
//SYMMETRIC SYNC
if (World.RegionSyncModule != null)
{
parts.Add(rootPart);
afterDelinkGroups.Add(rootPart.ParentGroup);
World.RegionSyncModule.SendDeLinkObject(parts, beforeDelinkGroups, afterDelinkGroups);
}
parentPrim.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None);
//end of SYMMETRIC SYNC
} }
public LSL_String llGetLinkKey(int linknum) public LSL_String llGetLinkKey(int linknum)
@ -4012,7 +4063,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
Util.Clip((float)color.z, 0.0f, 1.0f)); Util.Clip((float)color.z, 0.0f, 1.0f));
m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f));
m_host.ParentGroup.HasGroupChanged = true; m_host.ParentGroup.HasGroupChanged = true;
m_host.ParentGroup.ScheduleGroupForFullUpdate(); //m_host.ParentGroup.ScheduleGroupForFullUpdate();
m_host.ParentGroup.ScheduleGroupForFullUpdate(SceneObjectPartProperties.Text);
} }
public LSL_Float llWater(LSL_Vector offset) public LSL_Float llWater(LSL_Vector offset)

View File

@ -2349,7 +2349,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
obj.ParentGroup.HasGroupChanged = true; obj.ParentGroup.HasGroupChanged = true;
obj.ScheduleFullUpdate(); //obj.ScheduleFullUpdate();
obj.ScheduleFullUpdate(SceneObjectPartProperties.Shape);
} }