From 5b68343361cbd000a2f024b37797ec235abb7207 Mon Sep 17 00:00:00 2001
From: Tom Grimshaw
Date: Sun, 4 Jul 2010 19:28:39 -0700
Subject: The majority of the Undo fix. There is still an issue with Rotation
which i'll address next; however position undo and scale undo should be
working just fine now. Also removed some residual debug logging.
---
OpenSim/Framework/UndoStack.cs | 9 ++-
.../Region/Framework/Scenes/SceneObjectGroup.cs | 38 +++++-----
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 61 ++++++++---------
.../Scenes/Serialization/SceneObjectSerializer.cs | 4 +-
OpenSim/Region/Framework/Scenes/UndoState.cs | 80 ++++++++++++++++++++--
5 files changed, 135 insertions(+), 57 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Framework/UndoStack.cs b/OpenSim/Framework/UndoStack.cs
index 3799180..4cd779a 100644
--- a/OpenSim/Framework/UndoStack.cs
+++ b/OpenSim/Framework/UndoStack.cs
@@ -88,7 +88,14 @@ namespace OpenSim.Framework
public T Peek()
{
- return m_undolist[m_undolist.Count - 1];
+ if (m_undolist.Count > 0)
+ {
+ return m_undolist[m_undolist.Count - 1];
+ }
+ else
+ {
+ return default(T);
+ }
}
public void Clear()
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index da664da..34712b8 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -355,7 +355,7 @@ namespace OpenSim.Region.Framework.Scenes
{
foreach(SceneObjectPart p in m_parts.Values)
{
- p.StoreUndoState(true);
+ p.StoreUndoState(UndoType.STATE_GROUP_ROTATION);
}
}
finally
@@ -435,7 +435,6 @@ namespace OpenSim.Region.Framework.Scenes
get { return m_rootPart.GroupPosition; }
set
{
-
Vector3 val = value;
if ((m_scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || m_scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W)
@@ -464,7 +463,7 @@ namespace OpenSim.Region.Framework.Scenes
foreach (SceneObjectPart part in m_parts.Values)
{
part.IgnoreUndoUpdate = false;
- part.StoreUndoState(true);
+ part.StoreUndoState(UndoType.STATE_GROUP_POSITION);
part.GroupPosition = val;
}
lockPartsForRead(false);
@@ -1488,7 +1487,7 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient)
{
- part.StoreUndoState();
+ part.StoreUndoState(UndoType.STATE_PRIM_ALL);
part.OnGrab(offsetPos, remoteClient);
}
@@ -3245,6 +3244,9 @@ namespace OpenSim.Region.Framework.Scenes
prevScale.X *= x;
prevScale.Y *= y;
prevScale.Z *= z;;
+
+ part.IgnoreUndoUpdate = false;
+ part.StoreUndoState(UndoType.STATE_GROUP_SCALE);
part.IgnoreUndoUpdate = true;
part.Resize(prevScale);
part.IgnoreUndoUpdate = false;
@@ -3253,11 +3255,12 @@ namespace OpenSim.Region.Framework.Scenes
{
foreach (SceneObjectPart obPart in m_parts.Values)
{
- obPart.IgnoreUndoUpdate = false;
- obPart.StoreUndoState(true);
- obPart.IgnoreUndoUpdate = true;
if (obPart.UUID != m_rootPart.UUID)
{
+ obPart.IgnoreUndoUpdate = false;
+ obPart.StoreUndoState(UndoType.STATE_GROUP_SCALE);
+ obPart.IgnoreUndoUpdate = true;
+
Vector3 currentpos = new Vector3(obPart.OffsetPosition);
currentpos.X *= x;
currentpos.Y *= y;
@@ -3296,14 +3299,11 @@ namespace OpenSim.Region.Framework.Scenes
///
public void UpdateGroupPosition(Vector3 pos)
{
- foreach (SceneObjectPart part in Children.Values)
- {
- part.StoreUndoState();
- }
if (m_scene.EventManager.TriggerGroupMove(UUID, pos))
{
if (IsAttachment)
{
+ m_rootPart.StoreUndoState(UndoType.STATE_GROUP_POSITION);
m_rootPart.AttachedPos = pos;
}
if (RootPart.GetStatusSandbox())
@@ -3336,7 +3336,7 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart part = GetChildPart(localID);
foreach (SceneObjectPart parts in Children.Values)
{
- parts.StoreUndoState();
+ parts.StoreUndoState(UndoType.STATE_PRIM_POSITION);
}
if (part != null)
{
@@ -3361,7 +3361,7 @@ namespace OpenSim.Region.Framework.Scenes
{
foreach (SceneObjectPart part in Children.Values)
{
- part.StoreUndoState();
+ part.StoreUndoState(UndoType.STATE_PRIM_POSITION);
}
Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
Vector3 oldPos =
@@ -3409,7 +3409,7 @@ namespace OpenSim.Region.Framework.Scenes
{
foreach (SceneObjectPart parts in Children.Values)
{
- parts.StoreUndoState();
+ parts.StoreUndoState(UndoType.STATE_GROUP_ROTATION);
}
m_rootPart.UpdateRotation(rot);
@@ -3433,7 +3433,7 @@ namespace OpenSim.Region.Framework.Scenes
{
foreach (SceneObjectPart parts in Children.Values)
{
- parts.StoreUndoState();
+ parts.StoreUndoState(UndoType.STATE_GROUP_ROTATION);
}
m_rootPart.UpdateRotation(rot);
@@ -3460,7 +3460,7 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart part = GetChildPart(localID);
foreach (SceneObjectPart parts in Children.Values)
{
- parts.StoreUndoState();
+ parts.StoreUndoState(UndoType.STATE_PRIM_ROTATION);
}
if (part != null)
{
@@ -3496,7 +3496,7 @@ namespace OpenSim.Region.Framework.Scenes
part.UpdateRotation(rot);
part.OffsetPosition = pos;
part.IgnoreUndoUpdate = false;
- part.StoreUndoState();
+ part.StoreUndoState(UndoType.STATE_PRIM_ROTATION);
}
}
}
@@ -3510,7 +3510,7 @@ namespace OpenSim.Region.Framework.Scenes
Quaternion axRot = rot;
Quaternion oldParentRot = m_rootPart.RotationOffset;
- m_rootPart.StoreUndoState();
+ m_rootPart.StoreUndoState(UndoType.STATE_PRIM_ROTATION);
m_rootPart.UpdateRotation(rot);
if (m_rootPart.PhysActor != null)
{
@@ -3542,7 +3542,7 @@ namespace OpenSim.Region.Framework.Scenes
if (childpart != m_rootPart)
{
childpart.IgnoreUndoUpdate = false;
- childpart.StoreUndoState();
+ childpart.StoreUndoState(UndoType.STATE_PRIM_ROTATION);
}
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 72ad281..93a23ca 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -697,7 +697,7 @@ namespace OpenSim.Region.Framework.Scenes
get { return m_offsetPosition; }
set
{
- StoreUndoState();
+ StoreUndoState(UndoType.STATE_PRIM_POSITION);
m_offsetPosition = value;
if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -759,7 +759,7 @@ namespace OpenSim.Region.Framework.Scenes
set
{
- StoreUndoState();
+ StoreUndoState(UndoType.STATE_PRIM_ROTATION);
m_rotationOffset = value;
PhysicsActor actor = PhysActor;
@@ -958,7 +958,7 @@ namespace OpenSim.Region.Framework.Scenes
get { return m_shape.Scale; }
set
{
- StoreUndoState();
+ StoreUndoState(UndoType.STATE_PRIM_SCALE);
if (m_shape != null)
{
m_shape.Scale = value;
@@ -1522,7 +1522,7 @@ namespace OpenSim.Region.Framework.Scenes
{
m_redo.Clear();
}
- StoreUndoState();
+ StoreUndoState(UndoType.STATE_ALL);
}
public byte ConvertScriptUintToByte(uint indata)
@@ -2721,7 +2721,7 @@ namespace OpenSim.Region.Framework.Scenes
///
public void Resize(Vector3 scale)
{
- StoreUndoState();
+ StoreUndoState(UndoType.STATE_PRIM_SCALE);
m_shape.Scale = scale;
ParentGroup.HasGroupChanged = true;
@@ -3504,13 +3504,11 @@ namespace OpenSim.Region.Framework.Scenes
m_parentGroup.ScheduleGroupForTerseUpdate();
//m_parentGroup.ScheduleGroupForFullUpdate();
}
- public void StoreUndoState()
+ public void StoreUndoState(UndoType type)
{
- StoreUndoState(false);
- }
- public void StoreUndoState(bool group)
- {
- if (!Undoing)
+
+
+ if (!Undoing && (m_parentGroup == null || m_parentGroup.RootPart == null || !m_parentGroup.RootPart.Undoing))
{
if (!IgnoreUndoUpdate)
{
@@ -3521,17 +3519,25 @@ namespace OpenSim.Region.Framework.Scenes
if (m_undo.Count > 0)
{
UndoState last = m_undo.Peek();
- if (last != null)
- {
- if (last.Compare(this))
- return;
- }
+
}
if (m_parentGroup.GetSceneMaxUndo() > 0)
{
- UndoState nUndo = new UndoState(this);
- nUndo.GroupChange = group;
+ UndoState lastUndo = m_undo.Peek();
+
+ UndoState nUndo = new UndoState(this, type);
+
+ if (lastUndo != null)
+ {
+ TimeSpan ts = DateTime.Now.Subtract(lastUndo.LastUpdated);
+ if (ts.TotalMilliseconds < 500)
+ {
+ //Delete the last entry since it was less than 500 milliseconds ago
+ nUndo.Merge(lastUndo);
+ m_undo.Pop();
+ }
+ }
m_undo.Push(nUndo);
}
@@ -4008,20 +4014,13 @@ namespace OpenSim.Region.Framework.Scenes
if (m_undo.Count > 0)
{
UndoState nUndo = null;
- if (m_parentGroup.GetSceneMaxUndo() > 0)
- {
- nUndo = new UndoState(this);
- }
UndoState goback = m_undo.Pop();
- m_log.Debug("Got goback");
- if (goback == null)
- {
- m_log.Debug("it's null");
- }
- else
+ if (m_parentGroup.GetSceneMaxUndo() > 0)
{
- m_log.Debug(goback.GroupPosition.ToString());
+ nUndo = new UndoState(this, goback.Type);
}
+
+
if (goback != null)
{
goback.PlaybackState(this);
@@ -4036,13 +4035,13 @@ namespace OpenSim.Region.Framework.Scenes
{
lock (m_redo)
{
+ UndoState gofwd = m_redo.Pop();
if (m_parentGroup.GetSceneMaxUndo() > 0)
{
- UndoState nUndo = new UndoState(this);
+ UndoState nUndo = new UndoState(this, gofwd.Type);
m_undo.Push(nUndo);
}
- UndoState gofwd = m_redo.Pop();
if (gofwd != null)
gofwd.PlayfwdState(this);
}
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 5bdaa17..77e477f 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -105,7 +105,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
sceneObject.AddPart(part);
part.LinkNum = linkNum;
part.TrimPermissions();
- part.StoreUndoState();
+ part.StoreUndoState(UndoType.STATE_ALL);
reader.Close();
sr.Close();
}
@@ -231,7 +231,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
if (originalLinkNum != 0)
part.LinkNum = originalLinkNum;
- part.StoreUndoState();
+ part.StoreUndoState(UndoType.STATE_ALL);
reader.Close();
sr.Close();
}
diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs
index 77381ab..ad05351 100644
--- a/OpenSim/Region/Framework/Scenes/UndoState.cs
+++ b/OpenSim/Region/Framework/Scenes/UndoState.cs
@@ -27,26 +27,43 @@
using OpenMetaverse;
using OpenSim.Region.Framework.Interfaces;
+using System;
namespace OpenSim.Region.Framework.Scenes
{
+ [Flags]
+ public enum UndoType
+ {
+ STATE_PRIM_POSITION = 1,
+ STATE_PRIM_ROTATION = 2,
+ STATE_PRIM_SCALE = 4,
+ STATE_PRIM_ALL = 7,
+ STATE_GROUP_POSITION = 8,
+ STATE_GROUP_ROTATION = 16,
+ STATE_GROUP_SCALE = 32,
+ STATE_GROUP_ALL = 56,
+ STATE_ALL = 63
+ }
+
public class UndoState
{
public Vector3 Position = Vector3.Zero;
public Vector3 Scale = Vector3.Zero;
public Quaternion Rotation = Quaternion.Identity;
- public bool GroupChange = false;
public Vector3 GroupPosition = Vector3.Zero;
public Quaternion GroupRotation = Quaternion.Identity;
public Vector3 GroupScale = Vector3.Zero;
+ public DateTime LastUpdated = DateTime.Now;
+ public UndoType Type;
- public UndoState(SceneObjectPart part)
+ public UndoState(SceneObjectPart part, UndoType type)
{
+ Type = type;
if (part != null)
{
if (part.ParentID == 0)
{
- GroupScale = part.Shape.Scale;
+ GroupScale = part.ParentGroup.RootPart.Shape.Scale;
//FUBAR WARNING: Do NOT get the group's absoluteposition here
//or you'll experience a loop and/or a stack issue
@@ -55,6 +72,7 @@ namespace OpenSim.Region.Framework.Scenes
Position = part.ParentGroup.RootPart.AbsolutePosition;
Rotation = part.RotationOffset;
Scale = part.Shape.Scale;
+ LastUpdated = DateTime.Now;
}
else
{
@@ -67,10 +85,54 @@ namespace OpenSim.Region.Framework.Scenes
Position = part.OffsetPosition;
Rotation = part.RotationOffset;
Scale = part.Shape.Scale;
+ LastUpdated = DateTime.Now;
}
}
}
-
+ public void Merge(UndoState last)
+ {
+ if ((Type & UndoType.STATE_GROUP_POSITION) == 0 || ((last.Type & UndoType.STATE_GROUP_POSITION) >= (Type & UndoType.STATE_GROUP_POSITION)))
+ {
+ GroupPosition = last.GroupPosition;
+ Position = last.Position;
+ }
+ if ((Type & UndoType.STATE_GROUP_SCALE) == 0 || ((last.Type & UndoType.STATE_GROUP_SCALE) >= (Type & UndoType.STATE_GROUP_SCALE)))
+ {
+ Console.WriteLine("Setting groupscale to " + last.GroupScale.ToString());
+ GroupScale = last.GroupScale;
+ Scale = last.Scale;
+ }
+ if ((Type & UndoType.STATE_GROUP_ROTATION) == 0 || ((last.Type & UndoType.STATE_GROUP_ROTATION) >= (Type & UndoType.STATE_GROUP_ROTATION)))
+ {
+ GroupRotation = last.GroupRotation;
+ Rotation = last.Rotation;
+ }
+ if ((Type & UndoType.STATE_PRIM_POSITION) == 0 || ((last.Type & UndoType.STATE_PRIM_POSITION) >= (Type & UndoType.STATE_PRIM_POSITION)))
+ {
+ Position = last.Position;
+ }
+ if ((Type & UndoType.STATE_PRIM_SCALE) == 0 || ((last.Type & UndoType.STATE_PRIM_SCALE) >= (Type & UndoType.STATE_PRIM_SCALE)))
+ {
+ Scale = last.Scale;
+ }
+ if ((Type & UndoType.STATE_PRIM_ROTATION) == 0 || ((last.Type & UndoType.STATE_PRIM_ROTATION) >= (Type & UndoType.STATE_PRIM_ROTATION)))
+ {
+ Rotation = last.Rotation;
+ }
+ Type = Type | last.Type;
+ }
+ public bool Compare(UndoState undo)
+ {
+ if (undo == null || Position == null) return false;
+ if (undo.Position == Position && undo.Rotation == Rotation && undo.Scale == Scale && undo.GroupPosition == GroupPosition && undo.GroupScale == GroupScale && undo.GroupRotation == GroupRotation)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
public bool Compare(SceneObjectPart part)
{
if (part != null)
@@ -96,6 +158,14 @@ namespace OpenSim.Region.Framework.Scenes
public void PlaybackState(SceneObjectPart part)
{
+ bool GroupChange = false;
+ if ((Type & UndoType.STATE_GROUP_POSITION) != 0
+ || (Type & UndoType.STATE_GROUP_ROTATION) != 0
+ || (Type & UndoType.STATE_GROUP_SCALE) != 0)
+ {
+ GroupChange = true;
+ }
+
if (part != null)
{
part.Undoing = true;
@@ -113,6 +183,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (GroupChange)
{
+ part.ParentGroup.RootPart.Undoing = true;
if (Position != Vector3.Zero)
{
//Calculate the scale...
@@ -125,6 +196,7 @@ namespace OpenSim.Region.Framework.Scenes
part.ParentGroup.Rotation = GroupRotation;
}
+ part.ParentGroup.RootPart.Undoing = false;
}
else
{
--
cgit v1.1