From 90dd5844d64643246fb8bccf356614eb7e07d61c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 26 Sep 2012 21:28:43 +0100 Subject: Add basic undo/redo regression tests. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 12 +- .../Scenes/Tests/SceneObjectUndoRedoTests.cs | 130 +++++++++++++++++++++ .../Scenes/Tests/SceneObjectUserGroupTests.cs | 3 +- 3 files changed, 137 insertions(+), 8 deletions(-) create mode 100644 OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 411dcc7..63eb387 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3191,9 +3191,9 @@ namespace OpenSim.Region.Framework.Scenes } } - // m_log.DebugFormat( - // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", - // Name, LocalId, forGroup, m_undo.Count); +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", +// Name, LocalId, forGroup, m_undo.Count); if (ParentGroup.GetSceneMaxUndo() > 0) { @@ -3204,9 +3204,9 @@ namespace OpenSim.Region.Framework.Scenes if (m_redo.Count > 0) m_redo.Clear(); - // m_log.DebugFormat( - // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", - // Name, LocalId, forGroup, m_undo.Count); +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", +// Name, LocalId, forGroup, m_undo.Count); } } } diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs new file mode 100644 index 0000000..1e317c6 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs @@ -0,0 +1,130 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.Framework.Scenes.Tests +{ + /// + /// Tests for undo/redo + /// + public class SceneObjectUndoRedoTests : OpenSimTestCase + { + [Test] + public void TestUndoRedoResizeSceneObject() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + Vector3 firstSize = new Vector3(2, 3, 4); + Vector3 secondSize = new Vector3(5, 6, 7); + + Scene scene = new SceneHelpers().SetupScene(); + SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene); + + // TODO: It happens to be the case that we are not storing undo states for SOPs which are not yet in a SOG, + // which is the way that AddSceneObject() sets up the object (i.e. it creates the SOP first). However, + // this is somewhat by chance. Really, we shouldn't be storing undo states at all if the object is not + // in a scene. + Assert.That(g1.RootPart.UndoCount, Is.EqualTo(0)); + + g1.GroupResize(firstSize); + Assert.That(g1.RootPart.UndoCount, Is.EqualTo(1)); + + g1.GroupResize(secondSize); + Assert.That(g1.RootPart.UndoCount, Is.EqualTo(2)); + + g1.RootPart.Undo(); + Assert.That(g1.RootPart.UndoCount, Is.EqualTo(1)); + Assert.That(g1.GroupScale, Is.EqualTo(firstSize)); + + g1.RootPart.Redo(); + Assert.That(g1.RootPart.UndoCount, Is.EqualTo(2)); + Assert.That(g1.GroupScale, Is.EqualTo(secondSize)); + } + + [Test] + public void TestUndoBeyondAvailable() + { + TestHelpers.InMethod(); + + Vector3 newSize = new Vector3(2, 3, 4); + + Scene scene = new SceneHelpers().SetupScene(); + SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene); + Vector3 originalSize = g1.GroupScale; + + g1.RootPart.Undo(); + + Assert.That(g1.RootPart.UndoCount, Is.EqualTo(0)); + Assert.That(g1.GroupScale, Is.EqualTo(originalSize)); + + g1.GroupResize(newSize); + Assert.That(g1.RootPart.UndoCount, Is.EqualTo(1)); + Assert.That(g1.GroupScale, Is.EqualTo(newSize)); + + g1.RootPart.Undo(); + g1.RootPart.Undo(); + + Assert.That(g1.RootPart.UndoCount, Is.EqualTo(0)); + Assert.That(g1.GroupScale, Is.EqualTo(originalSize)); + } + + [Test] + public void TestRedoBeyondAvailable() + { + TestHelpers.InMethod(); + + Vector3 newSize = new Vector3(2, 3, 4); + + Scene scene = new SceneHelpers().SetupScene(); + SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene); + Vector3 originalSize = g1.GroupScale; + + g1.RootPart.Redo(); + + Assert.That(g1.RootPart.UndoCount, Is.EqualTo(0)); + Assert.That(g1.GroupScale, Is.EqualTo(originalSize)); + + g1.GroupResize(newSize); + g1.RootPart.Undo(); + g1.RootPart.Redo(); + g1.RootPart.Redo(); + + Assert.That(g1.RootPart.UndoCount, Is.EqualTo(1)); + Assert.That(g1.GroupScale, Is.EqualTo(newSize)); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs index c7eaff9..2b79271 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs @@ -44,7 +44,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.Framework.Scenes.Tests { [TestFixture] - public class SceneObjectUserGroupTests + public class SceneObjectUserGroupTests : OpenSimTestCase { /// /// Test share with group object functionality @@ -54,7 +54,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void TestShareWithGroup() { TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); -- cgit v1.1 From 327320d1a7acbba969d26c281f92f64ce8ff365f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 26 Sep 2012 22:49:44 +0100 Subject: Enforce existing 5 action hardcoded undo limit. This was present in the code but not enforced, which led to a memory leak over time as part properties were changed, whether by viewer, script or another source. This commit enforces that limit, which will soon become configurable. Regression test for undo limit added Should help with http://opensimulator.org/mantis/view.php?id=6279 --- OpenSim/Region/Framework/Scenes/Scene.cs | 6 ++- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 59 ++++++++++++---------- .../Scenes/Tests/SceneObjectUndoRedoTests.cs | 27 ++++++++++ 3 files changed, 65 insertions(+), 27 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e9d1d42..872c061 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -151,7 +151,8 @@ namespace OpenSim.Region.Framework.Scenes // TODO: need to figure out how allow client agents but deny // root agents when ACL denies access to root agent public bool m_strictAccessControl = true; - public int MaxUndoCount = 5; + + public int MaxUndoCount { get; set; } // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; public bool LoginLock = false; @@ -931,6 +932,9 @@ namespace OpenSim.Region.Framework.Scenes WestBorders.Add(westBorder); BordersLocked = false; + // TODO: At some point this should be made configurable. + MaxUndoCount = 5; + m_eventManager = new EventManager(); m_permissions = new ScenePermissions(this); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 63eb387..9e78242 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -266,8 +266,8 @@ namespace OpenSim.Region.Framework.Scenes private string m_sitAnimation = "SIT"; private string m_text = String.Empty; private string m_touchName = String.Empty; - private readonly Stack m_undo = new Stack(5); - private readonly Stack m_redo = new Stack(5); + private readonly List m_undo = new List(5); + private readonly List m_redo = new List(5); private bool m_passTouches = false; private bool m_passCollisions = false; @@ -3176,7 +3176,7 @@ namespace OpenSim.Region.Framework.Scenes { if (m_undo.Count > 0) { - UndoState last = m_undo.Peek(); + UndoState last = m_undo[m_undo.Count - 1]; if (last != null) { // TODO: May need to fix for group comparison @@ -3199,7 +3199,10 @@ namespace OpenSim.Region.Framework.Scenes { UndoState nUndo = new UndoState(this, forGroup); - m_undo.Push(nUndo); + m_undo.Add(nUndo); + + if (m_undo.Count > ParentGroup.GetSceneMaxUndo()) + m_undo.RemoveAt(0); if (m_redo.Count > 0) m_redo.Clear(); @@ -3245,21 +3248,24 @@ namespace OpenSim.Region.Framework.Scenes if (m_undo.Count > 0) { - UndoState goback = m_undo.Pop(); + UndoState goback = m_undo[m_undo.Count - 1]; + m_undo.RemoveAt(m_undo.Count - 1); - if (goback != null) + UndoState nUndo = null; + + if (ParentGroup.GetSceneMaxUndo() > 0) { - UndoState nUndo = null; - - if (ParentGroup.GetSceneMaxUndo() > 0) - { - nUndo = new UndoState(this, goback.ForGroup); - } + nUndo = new UndoState(this, goback.ForGroup); + } + + goback.PlaybackState(this); - goback.PlaybackState(this); + if (nUndo != null) + { + m_redo.Add(nUndo); - if (nUndo != null) - m_redo.Push(nUndo); + if (m_redo.Count > ParentGroup.GetSceneMaxUndo()) + m_redo.RemoveAt(0); } } @@ -3279,20 +3285,21 @@ namespace OpenSim.Region.Framework.Scenes if (m_redo.Count > 0) { - UndoState gofwd = m_redo.Pop(); - - if (gofwd != null) + UndoState gofwd = m_redo[m_redo.Count - 1]; + m_redo.RemoveAt(m_redo.Count - 1); + + if (ParentGroup.GetSceneMaxUndo() > 0) { - if (ParentGroup.GetSceneMaxUndo() > 0) - { - UndoState nUndo = new UndoState(this, gofwd.ForGroup); - - m_undo.Push(nUndo); - } - - gofwd.PlayfwdState(this); + UndoState nUndo = new UndoState(this, gofwd.ForGroup); + + m_undo.Add(nUndo); + + if (m_undo.Count > ParentGroup.GetSceneMaxUndo()) + m_undo.RemoveAt(0); } + gofwd.PlayfwdState(this); + // m_log.DebugFormat( // "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", // Name, LocalId, m_redo.Count); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs index 1e317c6..c93562d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs @@ -76,6 +76,33 @@ namespace OpenSim.Region.Framework.Scenes.Tests } [Test] + public void TestUndoLimit() + { + TestHelpers.InMethod(); + + Vector3 firstSize = new Vector3(2, 3, 4); + Vector3 secondSize = new Vector3(5, 6, 7); + Vector3 thirdSize = new Vector3(8, 9, 10); + Vector3 fourthSize = new Vector3(11, 12, 13); + + Scene scene = new SceneHelpers().SetupScene(); + scene.MaxUndoCount = 2; + SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene); + + g1.GroupResize(firstSize); + g1.GroupResize(secondSize); + g1.GroupResize(thirdSize); + g1.GroupResize(fourthSize); + + g1.RootPart.Undo(); + g1.RootPart.Undo(); + g1.RootPart.Undo(); + + Assert.That(g1.RootPart.UndoCount, Is.EqualTo(0)); + Assert.That(g1.GroupScale, Is.EqualTo(secondSize)); + } + + [Test] public void TestUndoBeyondAvailable() { TestHelpers.InMethod(); -- cgit v1.1 From 36e3123069fb7524d3872d095c0f54c155c55a28 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 26 Sep 2012 23:17:21 +0100 Subject: Make it possible to rescale SOGs when they are not in a scene. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 54 +++++++++++----------- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 20 ++++---- 2 files changed, 40 insertions(+), 34 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index ac26be7..85a37e9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2703,29 +2703,32 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale); - RootPart.StoreUndoState(true); - - scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X)); - scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y)); - scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z)); - PhysicsActor pa = m_rootPart.PhysActor; - if (pa != null && pa.IsPhysical) + RootPart.StoreUndoState(true); + + if (Scene != null) { - scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X)); - scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y)); - scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z)); + scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X)); + scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y)); + scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z)); + + if (pa != null && pa.IsPhysical) + { + scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X)); + scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y)); + scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z)); + } } float x = (scale.X / RootPart.Scale.X); float y = (scale.Y / RootPart.Scale.Y); float z = (scale.Z / RootPart.Scale.Z); - SceneObjectPart[] parts; - if (x > 1.0f || y > 1.0f || z > 1.0f) + SceneObjectPart[] parts = m_parts.GetArray(); + + if (Scene != null & (x > 1.0f || y > 1.0f || z > 1.0f)) { - parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { SceneObjectPart obPart = parts[i]; @@ -2739,7 +2742,7 @@ namespace OpenSim.Region.Framework.Scenes if (pa != null && pa.IsPhysical) { - if (oldSize.X * x > m_scene.m_maxPhys) + if (oldSize.X * x > Scene.m_maxPhys) { f = m_scene.m_maxPhys / oldSize.X; a = f / x; @@ -2747,7 +2750,7 @@ namespace OpenSim.Region.Framework.Scenes y *= a; z *= a; } - else if (oldSize.X * x < m_scene.m_minPhys) + else if (oldSize.X * x < Scene.m_minPhys) { f = m_scene.m_minPhys / oldSize.X; a = f / x; @@ -2756,7 +2759,7 @@ namespace OpenSim.Region.Framework.Scenes z *= a; } - if (oldSize.Y * y > m_scene.m_maxPhys) + if (oldSize.Y * y > Scene.m_maxPhys) { f = m_scene.m_maxPhys / oldSize.Y; a = f / y; @@ -2764,7 +2767,7 @@ namespace OpenSim.Region.Framework.Scenes y *= a; z *= a; } - else if (oldSize.Y * y < m_scene.m_minPhys) + else if (oldSize.Y * y < Scene.m_minPhys) { f = m_scene.m_minPhys / oldSize.Y; a = f / y; @@ -2773,7 +2776,7 @@ namespace OpenSim.Region.Framework.Scenes z *= a; } - if (oldSize.Z * z > m_scene.m_maxPhys) + if (oldSize.Z * z > Scene.m_maxPhys) { f = m_scene.m_maxPhys / oldSize.Z; a = f / z; @@ -2781,7 +2784,7 @@ namespace OpenSim.Region.Framework.Scenes y *= a; z *= a; } - else if (oldSize.Z * z < m_scene.m_minPhys) + else if (oldSize.Z * z < Scene.m_minPhys) { f = m_scene.m_minPhys / oldSize.Z; a = f / z; @@ -2792,7 +2795,7 @@ namespace OpenSim.Region.Framework.Scenes } else { - if (oldSize.X * x > m_scene.m_maxNonphys) + if (oldSize.X * x > Scene.m_maxNonphys) { f = m_scene.m_maxNonphys / oldSize.X; a = f / x; @@ -2800,7 +2803,7 @@ namespace OpenSim.Region.Framework.Scenes y *= a; z *= a; } - else if (oldSize.X * x < m_scene.m_minNonphys) + else if (oldSize.X * x < Scene.m_minNonphys) { f = m_scene.m_minNonphys / oldSize.X; a = f / x; @@ -2809,7 +2812,7 @@ namespace OpenSim.Region.Framework.Scenes z *= a; } - if (oldSize.Y * y > m_scene.m_maxNonphys) + if (oldSize.Y * y > Scene.m_maxNonphys) { f = m_scene.m_maxNonphys / oldSize.Y; a = f / y; @@ -2817,7 +2820,7 @@ namespace OpenSim.Region.Framework.Scenes y *= a; z *= a; } - else if (oldSize.Y * y < m_scene.m_minNonphys) + else if (oldSize.Y * y < Scene.m_minNonphys) { f = m_scene.m_minNonphys / oldSize.Y; a = f / y; @@ -2826,7 +2829,7 @@ namespace OpenSim.Region.Framework.Scenes z *= a; } - if (oldSize.Z * z > m_scene.m_maxNonphys) + if (oldSize.Z * z > Scene.m_maxNonphys) { f = m_scene.m_maxNonphys / oldSize.Z; a = f / z; @@ -2834,7 +2837,7 @@ namespace OpenSim.Region.Framework.Scenes y *= a; z *= a; } - else if (oldSize.Z * z < m_scene.m_minNonphys) + else if (oldSize.Z * z < Scene.m_minNonphys) { f = m_scene.m_minNonphys / oldSize.Z; a = f / z; @@ -2858,7 +2861,6 @@ namespace OpenSim.Region.Framework.Scenes RootPart.Resize(prevScale); // RootPart.IgnoreUndoUpdate = false; - parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { SceneObjectPart obPart = parts[i]; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 9e78242..018e4fc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2368,16 +2368,20 @@ namespace OpenSim.Region.Framework.Scenes /// public void Resize(Vector3 scale) { - scale.X = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.X)); - scale.Y = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Y)); - scale.Z = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Z)); - PhysicsActor pa = PhysActor; - if (pa != null && pa.IsPhysical) + + if (ParentGroup.Scene != null) { - scale.X = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.X)); - scale.Y = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Y)); - scale.Z = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Z)); + scale.X = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.X)); + scale.Y = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Y)); + scale.Z = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Z)); + + if (pa != null && pa.IsPhysical) + { + scale.X = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.X)); + scale.Y = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Y)); + scale.Z = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Z)); + } } // m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); -- cgit v1.1 From 31c636f1e48db2a42950e2ec0e8c7eba2c16616c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 26 Sep 2012 23:25:50 +0100 Subject: refactor: Change control structures in SOP.StoreUndoState() to reduce nesting. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 88 +++++++++++----------- 1 file changed, 43 insertions(+), 45 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 018e4fc..8710c3e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3170,64 +3170,62 @@ namespace OpenSim.Region.Framework.Scenes public void StoreUndoState(bool forGroup) { - if (!Undoing) + if (Undoing) { - if (!IgnoreUndoUpdate) +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId); + return; + } + + if (IgnoreUndoUpdate) + { +// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId); + return; + } + + if (ParentGroup == null) + return; + + lock (m_undo) + { + if (m_undo.Count > 0) { - if (ParentGroup != null) + UndoState last = m_undo[m_undo.Count - 1]; + if (last != null) { - lock (m_undo) + // TODO: May need to fix for group comparison + if (last.Compare(this)) { - if (m_undo.Count > 0) - { - UndoState last = m_undo[m_undo.Count - 1]; - if (last != null) - { - // TODO: May need to fix for group comparison - if (last.Compare(this)) - { - // m_log.DebugFormat( - // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}", - // Name, LocalId, m_undo.Count); - - return; - } - } - } - +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}", +// Name, LocalId, m_undo.Count); + + return; + } + } + } + // m_log.DebugFormat( // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", // Name, LocalId, forGroup, m_undo.Count); - - if (ParentGroup.GetSceneMaxUndo() > 0) - { - UndoState nUndo = new UndoState(this, forGroup); - - m_undo.Add(nUndo); - if (m_undo.Count > ParentGroup.GetSceneMaxUndo()) - m_undo.RemoveAt(0); - - if (m_redo.Count > 0) - m_redo.Clear(); - + if (ParentGroup.GetSceneMaxUndo() > 0) + { + UndoState nUndo = new UndoState(this, forGroup); + + m_undo.Add(nUndo); + + if (m_undo.Count > ParentGroup.GetSceneMaxUndo()) + m_undo.RemoveAt(0); + + if (m_redo.Count > 0) + m_redo.Clear(); + // m_log.DebugFormat( // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", // Name, LocalId, forGroup, m_undo.Count); - } - } - } } -// else -// { -// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId); -// } } -// else -// { -// m_log.DebugFormat( -// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId); -// } } /// -- cgit v1.1 From b9934fc4dbb1267409fa7264f3dd83a98959ea87 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 26 Sep 2012 23:31:10 +0100 Subject: Don't store undo states if a scene object is manipulated when it is not in a scene. Adds regression test for this. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 6 +++--- .../Scenes/Tests/SceneObjectUndoRedoTests.cs | 23 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 8710c3e..3d4bc3c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3170,6 +3170,9 @@ namespace OpenSim.Region.Framework.Scenes public void StoreUndoState(bool forGroup) { + if (ParentGroup == null || ParentGroup.Scene == null) + return; + if (Undoing) { // m_log.DebugFormat( @@ -3183,9 +3186,6 @@ namespace OpenSim.Region.Framework.Scenes return; } - if (ParentGroup == null) - return; - lock (m_undo) { if (m_undo.Count > 0) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs index c93562d..133fac5 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs @@ -103,6 +103,29 @@ namespace OpenSim.Region.Framework.Scenes.Tests } [Test] + public void TestNoUndoOnObjectsNotInScene() + { + TestHelpers.InMethod(); + + Vector3 firstSize = new Vector3(2, 3, 4); + Vector3 secondSize = new Vector3(5, 6, 7); + Vector3 thirdSize = new Vector3(8, 9, 10); + Vector3 fourthSize = new Vector3(11, 12, 13); + + Scene scene = new SceneHelpers().SetupScene(); + SceneObjectGroup g1 = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); + + g1.GroupResize(firstSize); + g1.GroupResize(secondSize); + + Assert.That(g1.RootPart.UndoCount, Is.EqualTo(0)); + + g1.RootPart.Undo(); + + Assert.That(g1.GroupScale, Is.EqualTo(secondSize)); + } + + [Test] public void TestUndoBeyondAvailable() { TestHelpers.InMethod(); -- cgit v1.1 From 2bf42f30af5030890b8e3ff5bb29074a1f0e9085 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 27 Sep 2012 00:12:34 +0100 Subject: Add MaxPrimsUndo config setting to [Startup] section of OpenSim.ini. This controls how many undo steps the simulator will store for each prim. Default is now 20 rather than 5 as it briefly was. The default number could be increased through this is a memory tradeoff which will scale with the number of prims in the sim and level of activity. --- OpenSim/Region/Framework/Scenes/Scene.cs | 5 ++--- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 8 -------- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 12 ++++++------ .../Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs | 2 -- .../Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs | 4 ++++ 5 files changed, 12 insertions(+), 19 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 872c061..2e03874 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -742,6 +742,8 @@ namespace OpenSim.Region.Framework.Scenes //Animation states m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); + MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20); + PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims); CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims); @@ -932,9 +934,6 @@ namespace OpenSim.Region.Framework.Scenes WestBorders.Add(westBorder); BordersLocked = false; - // TODO: At some point this should be made configurable. - MaxUndoCount = 5; - m_eventManager = new EventManager(); m_permissions = new ScenePermissions(this); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 85a37e9..45bbbda 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1119,14 +1119,6 @@ namespace OpenSim.Region.Framework.Scenes parts[i].UUID = UUID.Random(); } - // helper provided for parts. - public int GetSceneMaxUndo() - { - if (m_scene != null) - return m_scene.MaxUndoCount; - return 5; - } - // justincc: I don't believe this hack is needed any longer, especially since the physics // parts of set AbsolutePosition were already commented out. By changing HasGroupChanged to false // this method was preventing proper reload of scene objects. diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 3d4bc3c..3f10b34 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3209,13 +3209,13 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", // Name, LocalId, forGroup, m_undo.Count); - if (ParentGroup.GetSceneMaxUndo() > 0) + if (ParentGroup.Scene.MaxUndoCount > 0) { UndoState nUndo = new UndoState(this, forGroup); m_undo.Add(nUndo); - if (m_undo.Count > ParentGroup.GetSceneMaxUndo()) + if (m_undo.Count > ParentGroup.Scene.MaxUndoCount) m_undo.RemoveAt(0); if (m_redo.Count > 0) @@ -3255,7 +3255,7 @@ namespace OpenSim.Region.Framework.Scenes UndoState nUndo = null; - if (ParentGroup.GetSceneMaxUndo() > 0) + if (ParentGroup.Scene.MaxUndoCount > 0) { nUndo = new UndoState(this, goback.ForGroup); } @@ -3266,7 +3266,7 @@ namespace OpenSim.Region.Framework.Scenes { m_redo.Add(nUndo); - if (m_redo.Count > ParentGroup.GetSceneMaxUndo()) + if (m_redo.Count > ParentGroup.Scene.MaxUndoCount) m_redo.RemoveAt(0); } } @@ -3290,13 +3290,13 @@ namespace OpenSim.Region.Framework.Scenes UndoState gofwd = m_redo[m_redo.Count - 1]; m_redo.RemoveAt(m_redo.Count - 1); - if (ParentGroup.GetSceneMaxUndo() > 0) + if (ParentGroup.Scene.MaxUndoCount > 0) { UndoState nUndo = new UndoState(this, gofwd.ForGroup); m_undo.Add(nUndo); - if (m_undo.Count > ParentGroup.GetSceneMaxUndo()) + if (m_undo.Count > ParentGroup.Scene.MaxUndoCount) m_undo.RemoveAt(0); } diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs index e931859..89647d6 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs @@ -62,8 +62,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(g1Post.RootPart.Scale.X, Is.EqualTo(2)); Assert.That(g1Post.RootPart.Scale.Y, Is.EqualTo(3)); Assert.That(g1Post.RootPart.Scale.Z, Is.EqualTo(4)); - - Assert.That(g1Post.RootPart.UndoCount, Is.EqualTo(1)); } /// diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs index 133fac5..96973de 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs @@ -52,6 +52,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Vector3 secondSize = new Vector3(5, 6, 7); Scene scene = new SceneHelpers().SetupScene(); + scene.MaxUndoCount = 20; SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene); // TODO: It happens to be the case that we are not storing undo states for SOPs which are not yet in a SOG, @@ -113,6 +114,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Vector3 fourthSize = new Vector3(11, 12, 13); Scene scene = new SceneHelpers().SetupScene(); + scene.MaxUndoCount = 20; SceneObjectGroup g1 = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); g1.GroupResize(firstSize); @@ -133,6 +135,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Vector3 newSize = new Vector3(2, 3, 4); Scene scene = new SceneHelpers().SetupScene(); + scene.MaxUndoCount = 20; SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene); Vector3 originalSize = g1.GroupScale; @@ -160,6 +163,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Vector3 newSize = new Vector3(2, 3, 4); Scene scene = new SceneHelpers().SetupScene(); + scene.MaxUndoCount = 20; SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene); Vector3 originalSize = g1.GroupScale; -- cgit v1.1