diff options
-rw-r--r-- | CONTRIBUTORS.txt | 1 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 5 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 62 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 167 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs | 184 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs | 3 | ||||
-rw-r--r-- | bin/OpenSim.ini.example | 4 | ||||
-rw-r--r-- | bin/OpenSimDefaults.ini | 4 |
9 files changed, 314 insertions, 118 deletions
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index f334b3d..2d02a82 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt | |||
@@ -209,3 +209,4 @@ In addition, we would like to thank: | |||
209 | * The NANT Developers | 209 | * The NANT Developers |
210 | * Microsoft (.NET, MSSQL-Adapters) | 210 | * Microsoft (.NET, MSSQL-Adapters) |
211 | *x | 211 | *x |
212 | |||
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e9d1d42..2e03874 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -151,7 +151,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
151 | // TODO: need to figure out how allow client agents but deny | 151 | // TODO: need to figure out how allow client agents but deny |
152 | // root agents when ACL denies access to root agent | 152 | // root agents when ACL denies access to root agent |
153 | public bool m_strictAccessControl = true; | 153 | public bool m_strictAccessControl = true; |
154 | public int MaxUndoCount = 5; | 154 | |
155 | public int MaxUndoCount { get; set; } | ||
155 | 156 | ||
156 | // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; | 157 | // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; |
157 | public bool LoginLock = false; | 158 | public bool LoginLock = false; |
@@ -741,6 +742,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
741 | //Animation states | 742 | //Animation states |
742 | m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); | 743 | m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); |
743 | 744 | ||
745 | MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20); | ||
746 | |||
744 | PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims); | 747 | PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims); |
745 | CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims); | 748 | CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims); |
746 | 749 | ||
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index ac26be7..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 | |||
1119 | parts[i].UUID = UUID.Random(); | 1119 | parts[i].UUID = UUID.Random(); |
1120 | } | 1120 | } |
1121 | 1121 | ||
1122 | // helper provided for parts. | ||
1123 | public int GetSceneMaxUndo() | ||
1124 | { | ||
1125 | if (m_scene != null) | ||
1126 | return m_scene.MaxUndoCount; | ||
1127 | return 5; | ||
1128 | } | ||
1129 | |||
1130 | // justincc: I don't believe this hack is needed any longer, especially since the physics | 1122 | // justincc: I don't believe this hack is needed any longer, especially since the physics |
1131 | // parts of set AbsolutePosition were already commented out. By changing HasGroupChanged to false | 1123 | // parts of set AbsolutePosition were already commented out. By changing HasGroupChanged to false |
1132 | // this method was preventing proper reload of scene objects. | 1124 | // this method was preventing proper reload of scene objects. |
@@ -2703,29 +2695,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
2703 | // m_log.DebugFormat( | 2695 | // m_log.DebugFormat( |
2704 | // "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale); | 2696 | // "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale); |
2705 | 2697 | ||
2706 | RootPart.StoreUndoState(true); | ||
2707 | |||
2708 | scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X)); | ||
2709 | scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y)); | ||
2710 | scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z)); | ||
2711 | |||
2712 | PhysicsActor pa = m_rootPart.PhysActor; | 2698 | PhysicsActor pa = m_rootPart.PhysActor; |
2713 | 2699 | ||
2714 | if (pa != null && pa.IsPhysical) | 2700 | RootPart.StoreUndoState(true); |
2701 | |||
2702 | if (Scene != null) | ||
2715 | { | 2703 | { |
2716 | scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X)); | 2704 | scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X)); |
2717 | scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y)); | 2705 | scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y)); |
2718 | scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z)); | 2706 | scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z)); |
2707 | |||
2708 | if (pa != null && pa.IsPhysical) | ||
2709 | { | ||
2710 | scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X)); | ||
2711 | scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y)); | ||
2712 | scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z)); | ||
2713 | } | ||
2719 | } | 2714 | } |
2720 | 2715 | ||
2721 | float x = (scale.X / RootPart.Scale.X); | 2716 | float x = (scale.X / RootPart.Scale.X); |
2722 | float y = (scale.Y / RootPart.Scale.Y); | 2717 | float y = (scale.Y / RootPart.Scale.Y); |
2723 | float z = (scale.Z / RootPart.Scale.Z); | 2718 | float z = (scale.Z / RootPart.Scale.Z); |
2724 | 2719 | ||
2725 | SceneObjectPart[] parts; | 2720 | SceneObjectPart[] parts = m_parts.GetArray(); |
2726 | if (x > 1.0f || y > 1.0f || z > 1.0f) | 2721 | |
2722 | if (Scene != null & (x > 1.0f || y > 1.0f || z > 1.0f)) | ||
2727 | { | 2723 | { |
2728 | parts = m_parts.GetArray(); | ||
2729 | for (int i = 0; i < parts.Length; i++) | 2724 | for (int i = 0; i < parts.Length; i++) |
2730 | { | 2725 | { |
2731 | SceneObjectPart obPart = parts[i]; | 2726 | SceneObjectPart obPart = parts[i]; |
@@ -2739,7 +2734,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2739 | 2734 | ||
2740 | if (pa != null && pa.IsPhysical) | 2735 | if (pa != null && pa.IsPhysical) |
2741 | { | 2736 | { |
2742 | if (oldSize.X * x > m_scene.m_maxPhys) | 2737 | if (oldSize.X * x > Scene.m_maxPhys) |
2743 | { | 2738 | { |
2744 | f = m_scene.m_maxPhys / oldSize.X; | 2739 | f = m_scene.m_maxPhys / oldSize.X; |
2745 | a = f / x; | 2740 | a = f / x; |
@@ -2747,7 +2742,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2747 | y *= a; | 2742 | y *= a; |
2748 | z *= a; | 2743 | z *= a; |
2749 | } | 2744 | } |
2750 | else if (oldSize.X * x < m_scene.m_minPhys) | 2745 | else if (oldSize.X * x < Scene.m_minPhys) |
2751 | { | 2746 | { |
2752 | f = m_scene.m_minPhys / oldSize.X; | 2747 | f = m_scene.m_minPhys / oldSize.X; |
2753 | a = f / x; | 2748 | a = f / x; |
@@ -2756,7 +2751,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2756 | z *= a; | 2751 | z *= a; |
2757 | } | 2752 | } |
2758 | 2753 | ||
2759 | if (oldSize.Y * y > m_scene.m_maxPhys) | 2754 | if (oldSize.Y * y > Scene.m_maxPhys) |
2760 | { | 2755 | { |
2761 | f = m_scene.m_maxPhys / oldSize.Y; | 2756 | f = m_scene.m_maxPhys / oldSize.Y; |
2762 | a = f / y; | 2757 | a = f / y; |
@@ -2764,7 +2759,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2764 | y *= a; | 2759 | y *= a; |
2765 | z *= a; | 2760 | z *= a; |
2766 | } | 2761 | } |
2767 | else if (oldSize.Y * y < m_scene.m_minPhys) | 2762 | else if (oldSize.Y * y < Scene.m_minPhys) |
2768 | { | 2763 | { |
2769 | f = m_scene.m_minPhys / oldSize.Y; | 2764 | f = m_scene.m_minPhys / oldSize.Y; |
2770 | a = f / y; | 2765 | a = f / y; |
@@ -2773,7 +2768,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2773 | z *= a; | 2768 | z *= a; |
2774 | } | 2769 | } |
2775 | 2770 | ||
2776 | if (oldSize.Z * z > m_scene.m_maxPhys) | 2771 | if (oldSize.Z * z > Scene.m_maxPhys) |
2777 | { | 2772 | { |
2778 | f = m_scene.m_maxPhys / oldSize.Z; | 2773 | f = m_scene.m_maxPhys / oldSize.Z; |
2779 | a = f / z; | 2774 | a = f / z; |
@@ -2781,7 +2776,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2781 | y *= a; | 2776 | y *= a; |
2782 | z *= a; | 2777 | z *= a; |
2783 | } | 2778 | } |
2784 | else if (oldSize.Z * z < m_scene.m_minPhys) | 2779 | else if (oldSize.Z * z < Scene.m_minPhys) |
2785 | { | 2780 | { |
2786 | f = m_scene.m_minPhys / oldSize.Z; | 2781 | f = m_scene.m_minPhys / oldSize.Z; |
2787 | a = f / z; | 2782 | a = f / z; |
@@ -2792,7 +2787,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2792 | } | 2787 | } |
2793 | else | 2788 | else |
2794 | { | 2789 | { |
2795 | if (oldSize.X * x > m_scene.m_maxNonphys) | 2790 | if (oldSize.X * x > Scene.m_maxNonphys) |
2796 | { | 2791 | { |
2797 | f = m_scene.m_maxNonphys / oldSize.X; | 2792 | f = m_scene.m_maxNonphys / oldSize.X; |
2798 | a = f / x; | 2793 | a = f / x; |
@@ -2800,7 +2795,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2800 | y *= a; | 2795 | y *= a; |
2801 | z *= a; | 2796 | z *= a; |
2802 | } | 2797 | } |
2803 | else if (oldSize.X * x < m_scene.m_minNonphys) | 2798 | else if (oldSize.X * x < Scene.m_minNonphys) |
2804 | { | 2799 | { |
2805 | f = m_scene.m_minNonphys / oldSize.X; | 2800 | f = m_scene.m_minNonphys / oldSize.X; |
2806 | a = f / x; | 2801 | a = f / x; |
@@ -2809,7 +2804,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2809 | z *= a; | 2804 | z *= a; |
2810 | } | 2805 | } |
2811 | 2806 | ||
2812 | if (oldSize.Y * y > m_scene.m_maxNonphys) | 2807 | if (oldSize.Y * y > Scene.m_maxNonphys) |
2813 | { | 2808 | { |
2814 | f = m_scene.m_maxNonphys / oldSize.Y; | 2809 | f = m_scene.m_maxNonphys / oldSize.Y; |
2815 | a = f / y; | 2810 | a = f / y; |
@@ -2817,7 +2812,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2817 | y *= a; | 2812 | y *= a; |
2818 | z *= a; | 2813 | z *= a; |
2819 | } | 2814 | } |
2820 | else if (oldSize.Y * y < m_scene.m_minNonphys) | 2815 | else if (oldSize.Y * y < Scene.m_minNonphys) |
2821 | { | 2816 | { |
2822 | f = m_scene.m_minNonphys / oldSize.Y; | 2817 | f = m_scene.m_minNonphys / oldSize.Y; |
2823 | a = f / y; | 2818 | a = f / y; |
@@ -2826,7 +2821,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2826 | z *= a; | 2821 | z *= a; |
2827 | } | 2822 | } |
2828 | 2823 | ||
2829 | if (oldSize.Z * z > m_scene.m_maxNonphys) | 2824 | if (oldSize.Z * z > Scene.m_maxNonphys) |
2830 | { | 2825 | { |
2831 | f = m_scene.m_maxNonphys / oldSize.Z; | 2826 | f = m_scene.m_maxNonphys / oldSize.Z; |
2832 | a = f / z; | 2827 | a = f / z; |
@@ -2834,7 +2829,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2834 | y *= a; | 2829 | y *= a; |
2835 | z *= a; | 2830 | z *= a; |
2836 | } | 2831 | } |
2837 | else if (oldSize.Z * z < m_scene.m_minNonphys) | 2832 | else if (oldSize.Z * z < Scene.m_minNonphys) |
2838 | { | 2833 | { |
2839 | f = m_scene.m_minNonphys / oldSize.Z; | 2834 | f = m_scene.m_minNonphys / oldSize.Z; |
2840 | a = f / z; | 2835 | a = f / z; |
@@ -2858,7 +2853,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2858 | RootPart.Resize(prevScale); | 2853 | RootPart.Resize(prevScale); |
2859 | // RootPart.IgnoreUndoUpdate = false; | 2854 | // RootPart.IgnoreUndoUpdate = false; |
2860 | 2855 | ||
2861 | parts = m_parts.GetArray(); | ||
2862 | for (int i = 0; i < parts.Length; i++) | 2856 | for (int i = 0; i < parts.Length; i++) |
2863 | { | 2857 | { |
2864 | SceneObjectPart obPart = parts[i]; | 2858 | SceneObjectPart obPart = parts[i]; |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 411dcc7..3f10b34 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -266,8 +266,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
266 | private string m_sitAnimation = "SIT"; | 266 | private string m_sitAnimation = "SIT"; |
267 | private string m_text = String.Empty; | 267 | private string m_text = String.Empty; |
268 | private string m_touchName = String.Empty; | 268 | private string m_touchName = String.Empty; |
269 | private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5); | 269 | private readonly List<UndoState> m_undo = new List<UndoState>(5); |
270 | private readonly Stack<UndoState> m_redo = new Stack<UndoState>(5); | 270 | private readonly List<UndoState> m_redo = new List<UndoState>(5); |
271 | 271 | ||
272 | private bool m_passTouches = false; | 272 | private bool m_passTouches = false; |
273 | private bool m_passCollisions = false; | 273 | private bool m_passCollisions = false; |
@@ -2368,16 +2368,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
2368 | /// <param name="scale"></param> | 2368 | /// <param name="scale"></param> |
2369 | public void Resize(Vector3 scale) | 2369 | public void Resize(Vector3 scale) |
2370 | { | 2370 | { |
2371 | scale.X = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.X)); | ||
2372 | scale.Y = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Y)); | ||
2373 | scale.Z = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Z)); | ||
2374 | |||
2375 | PhysicsActor pa = PhysActor; | 2371 | PhysicsActor pa = PhysActor; |
2376 | if (pa != null && pa.IsPhysical) | 2372 | |
2373 | if (ParentGroup.Scene != null) | ||
2377 | { | 2374 | { |
2378 | scale.X = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.X)); | 2375 | scale.X = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.X)); |
2379 | scale.Y = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Y)); | 2376 | scale.Y = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Y)); |
2380 | scale.Z = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Z)); | 2377 | scale.Z = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Z)); |
2378 | |||
2379 | if (pa != null && pa.IsPhysical) | ||
2380 | { | ||
2381 | scale.X = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.X)); | ||
2382 | scale.Y = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Y)); | ||
2383 | scale.Z = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Z)); | ||
2384 | } | ||
2381 | } | 2385 | } |
2382 | 2386 | ||
2383 | // m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); | 2387 | // m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); |
@@ -3166,61 +3170,62 @@ namespace OpenSim.Region.Framework.Scenes | |||
3166 | 3170 | ||
3167 | public void StoreUndoState(bool forGroup) | 3171 | public void StoreUndoState(bool forGroup) |
3168 | { | 3172 | { |
3169 | if (!Undoing) | 3173 | if (ParentGroup == null || ParentGroup.Scene == null) |
3174 | return; | ||
3175 | |||
3176 | if (Undoing) | ||
3170 | { | 3177 | { |
3171 | if (!IgnoreUndoUpdate) | 3178 | // m_log.DebugFormat( |
3179 | // "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId); | ||
3180 | return; | ||
3181 | } | ||
3182 | |||
3183 | if (IgnoreUndoUpdate) | ||
3184 | { | ||
3185 | // m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId); | ||
3186 | return; | ||
3187 | } | ||
3188 | |||
3189 | lock (m_undo) | ||
3190 | { | ||
3191 | if (m_undo.Count > 0) | ||
3172 | { | 3192 | { |
3173 | if (ParentGroup != null) | 3193 | UndoState last = m_undo[m_undo.Count - 1]; |
3194 | if (last != null) | ||
3174 | { | 3195 | { |
3175 | lock (m_undo) | 3196 | // TODO: May need to fix for group comparison |
3197 | if (last.Compare(this)) | ||
3176 | { | 3198 | { |
3177 | if (m_undo.Count > 0) | 3199 | // m_log.DebugFormat( |
3178 | { | 3200 | // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}", |
3179 | UndoState last = m_undo.Peek(); | 3201 | // Name, LocalId, m_undo.Count); |
3180 | if (last != null) | 3202 | |
3181 | { | 3203 | return; |
3182 | // TODO: May need to fix for group comparison | ||
3183 | if (last.Compare(this)) | ||
3184 | { | ||
3185 | // m_log.DebugFormat( | ||
3186 | // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}", | ||
3187 | // Name, LocalId, m_undo.Count); | ||
3188 | |||
3189 | return; | ||
3190 | } | ||
3191 | } | ||
3192 | } | ||
3193 | |||
3194 | // m_log.DebugFormat( | ||
3195 | // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", | ||
3196 | // Name, LocalId, forGroup, m_undo.Count); | ||
3197 | |||
3198 | if (ParentGroup.GetSceneMaxUndo() > 0) | ||
3199 | { | ||
3200 | UndoState nUndo = new UndoState(this, forGroup); | ||
3201 | |||
3202 | m_undo.Push(nUndo); | ||
3203 | |||
3204 | if (m_redo.Count > 0) | ||
3205 | m_redo.Clear(); | ||
3206 | |||
3207 | // m_log.DebugFormat( | ||
3208 | // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", | ||
3209 | // Name, LocalId, forGroup, m_undo.Count); | ||
3210 | } | ||
3211 | } | 3204 | } |
3212 | } | 3205 | } |
3213 | } | 3206 | } |
3214 | // else | 3207 | |
3215 | // { | 3208 | // m_log.DebugFormat( |
3216 | // m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId); | 3209 | // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", |
3217 | // } | 3210 | // Name, LocalId, forGroup, m_undo.Count); |
3211 | |||
3212 | if (ParentGroup.Scene.MaxUndoCount > 0) | ||
3213 | { | ||
3214 | UndoState nUndo = new UndoState(this, forGroup); | ||
3215 | |||
3216 | m_undo.Add(nUndo); | ||
3217 | |||
3218 | if (m_undo.Count > ParentGroup.Scene.MaxUndoCount) | ||
3219 | m_undo.RemoveAt(0); | ||
3220 | |||
3221 | if (m_redo.Count > 0) | ||
3222 | m_redo.Clear(); | ||
3223 | |||
3224 | // m_log.DebugFormat( | ||
3225 | // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", | ||
3226 | // Name, LocalId, forGroup, m_undo.Count); | ||
3227 | } | ||
3218 | } | 3228 | } |
3219 | // else | ||
3220 | // { | ||
3221 | // m_log.DebugFormat( | ||
3222 | // "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId); | ||
3223 | // } | ||
3224 | } | 3229 | } |
3225 | 3230 | ||
3226 | /// <summary> | 3231 | /// <summary> |
@@ -3245,21 +3250,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
3245 | 3250 | ||
3246 | if (m_undo.Count > 0) | 3251 | if (m_undo.Count > 0) |
3247 | { | 3252 | { |
3248 | UndoState goback = m_undo.Pop(); | 3253 | UndoState goback = m_undo[m_undo.Count - 1]; |
3254 | m_undo.RemoveAt(m_undo.Count - 1); | ||
3249 | 3255 | ||
3250 | if (goback != null) | 3256 | UndoState nUndo = null; |
3257 | |||
3258 | if (ParentGroup.Scene.MaxUndoCount > 0) | ||
3251 | { | 3259 | { |
3252 | UndoState nUndo = null; | 3260 | nUndo = new UndoState(this, goback.ForGroup); |
3253 | 3261 | } | |
3254 | if (ParentGroup.GetSceneMaxUndo() > 0) | 3262 | |
3255 | { | 3263 | goback.PlaybackState(this); |
3256 | nUndo = new UndoState(this, goback.ForGroup); | ||
3257 | } | ||
3258 | 3264 | ||
3259 | goback.PlaybackState(this); | 3265 | if (nUndo != null) |
3266 | { | ||
3267 | m_redo.Add(nUndo); | ||
3260 | 3268 | ||
3261 | if (nUndo != null) | 3269 | if (m_redo.Count > ParentGroup.Scene.MaxUndoCount) |
3262 | m_redo.Push(nUndo); | 3270 | m_redo.RemoveAt(0); |
3263 | } | 3271 | } |
3264 | } | 3272 | } |
3265 | 3273 | ||
@@ -3279,20 +3287,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
3279 | 3287 | ||
3280 | if (m_redo.Count > 0) | 3288 | if (m_redo.Count > 0) |
3281 | { | 3289 | { |
3282 | UndoState gofwd = m_redo.Pop(); | 3290 | UndoState gofwd = m_redo[m_redo.Count - 1]; |
3283 | 3291 | m_redo.RemoveAt(m_redo.Count - 1); | |
3284 | if (gofwd != null) | 3292 | |
3293 | if (ParentGroup.Scene.MaxUndoCount > 0) | ||
3285 | { | 3294 | { |
3286 | if (ParentGroup.GetSceneMaxUndo() > 0) | 3295 | UndoState nUndo = new UndoState(this, gofwd.ForGroup); |
3287 | { | 3296 | |
3288 | UndoState nUndo = new UndoState(this, gofwd.ForGroup); | 3297 | m_undo.Add(nUndo); |
3289 | 3298 | ||
3290 | m_undo.Push(nUndo); | 3299 | if (m_undo.Count > ParentGroup.Scene.MaxUndoCount) |
3291 | } | 3300 | m_undo.RemoveAt(0); |
3292 | |||
3293 | gofwd.PlayfwdState(this); | ||
3294 | } | 3301 | } |
3295 | 3302 | ||
3303 | gofwd.PlayfwdState(this); | ||
3304 | |||
3296 | // m_log.DebugFormat( | 3305 | // m_log.DebugFormat( |
3297 | // "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", | 3306 | // "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", |
3298 | // Name, LocalId, m_redo.Count); | 3307 | // Name, LocalId, m_redo.Count); |
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 | |||
62 | Assert.That(g1Post.RootPart.Scale.X, Is.EqualTo(2)); | 62 | Assert.That(g1Post.RootPart.Scale.X, Is.EqualTo(2)); |
63 | Assert.That(g1Post.RootPart.Scale.Y, Is.EqualTo(3)); | 63 | Assert.That(g1Post.RootPart.Scale.Y, Is.EqualTo(3)); |
64 | Assert.That(g1Post.RootPart.Scale.Z, Is.EqualTo(4)); | 64 | Assert.That(g1Post.RootPart.Scale.Z, Is.EqualTo(4)); |
65 | |||
66 | Assert.That(g1Post.RootPart.UndoCount, Is.EqualTo(1)); | ||
67 | } | 65 | } |
68 | 66 | ||
69 | /// <summary> | 67 | /// <summary> |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs new file mode 100644 index 0000000..96973de --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs | |||
@@ -0,0 +1,184 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Reflection; | ||
30 | using NUnit.Framework; | ||
31 | using OpenMetaverse; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Framework.Communications; | ||
34 | using OpenSim.Region.Framework.Scenes; | ||
35 | using OpenSim.Tests.Common; | ||
36 | using OpenSim.Tests.Common.Mock; | ||
37 | |||
38 | namespace OpenSim.Region.Framework.Scenes.Tests | ||
39 | { | ||
40 | /// <summary> | ||
41 | /// Tests for undo/redo | ||
42 | /// </summary> | ||
43 | public class SceneObjectUndoRedoTests : OpenSimTestCase | ||
44 | { | ||
45 | [Test] | ||
46 | public void TestUndoRedoResizeSceneObject() | ||
47 | { | ||
48 | TestHelpers.InMethod(); | ||
49 | // TestHelpers.EnableLogging(); | ||
50 | |||
51 | Vector3 firstSize = new Vector3(2, 3, 4); | ||
52 | Vector3 secondSize = new Vector3(5, 6, 7); | ||
53 | |||
54 | Scene scene = new SceneHelpers().SetupScene(); | ||
55 | scene.MaxUndoCount = 20; | ||
56 | SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene); | ||
57 | |||
58 | // TODO: It happens to be the case that we are not storing undo states for SOPs which are not yet in a SOG, | ||
59 | // which is the way that AddSceneObject() sets up the object (i.e. it creates the SOP first). However, | ||
60 | // this is somewhat by chance. Really, we shouldn't be storing undo states at all if the object is not | ||
61 | // in a scene. | ||
62 | Assert.That(g1.RootPart.UndoCount, Is.EqualTo(0)); | ||
63 | |||
64 | g1.GroupResize(firstSize); | ||
65 | Assert.That(g1.RootPart.UndoCount, Is.EqualTo(1)); | ||
66 | |||
67 | g1.GroupResize(secondSize); | ||
68 | Assert.That(g1.RootPart.UndoCount, Is.EqualTo(2)); | ||
69 | |||
70 | g1.RootPart.Undo(); | ||
71 | Assert.That(g1.RootPart.UndoCount, Is.EqualTo(1)); | ||
72 | Assert.That(g1.GroupScale, Is.EqualTo(firstSize)); | ||
73 | |||
74 | g1.RootPart.Redo(); | ||
75 | Assert.That(g1.RootPart.UndoCount, Is.EqualTo(2)); | ||
76 | Assert.That(g1.GroupScale, Is.EqualTo(secondSize)); | ||
77 | } | ||
78 | |||
79 | [Test] | ||
80 | public void TestUndoLimit() | ||
81 | { | ||
82 | TestHelpers.InMethod(); | ||
83 | |||
84 | Vector3 firstSize = new Vector3(2, 3, 4); | ||
85 | Vector3 secondSize = new Vector3(5, 6, 7); | ||
86 | Vector3 thirdSize = new Vector3(8, 9, 10); | ||
87 | Vector3 fourthSize = new Vector3(11, 12, 13); | ||
88 | |||
89 | Scene scene = new SceneHelpers().SetupScene(); | ||
90 | scene.MaxUndoCount = 2; | ||
91 | SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene); | ||
92 | |||
93 | g1.GroupResize(firstSize); | ||
94 | g1.GroupResize(secondSize); | ||
95 | g1.GroupResize(thirdSize); | ||
96 | g1.GroupResize(fourthSize); | ||
97 | |||
98 | g1.RootPart.Undo(); | ||
99 | g1.RootPart.Undo(); | ||
100 | g1.RootPart.Undo(); | ||
101 | |||
102 | Assert.That(g1.RootPart.UndoCount, Is.EqualTo(0)); | ||
103 | Assert.That(g1.GroupScale, Is.EqualTo(secondSize)); | ||
104 | } | ||
105 | |||
106 | [Test] | ||
107 | public void TestNoUndoOnObjectsNotInScene() | ||
108 | { | ||
109 | TestHelpers.InMethod(); | ||
110 | |||
111 | Vector3 firstSize = new Vector3(2, 3, 4); | ||
112 | Vector3 secondSize = new Vector3(5, 6, 7); | ||
113 | Vector3 thirdSize = new Vector3(8, 9, 10); | ||
114 | Vector3 fourthSize = new Vector3(11, 12, 13); | ||
115 | |||
116 | Scene scene = new SceneHelpers().SetupScene(); | ||
117 | scene.MaxUndoCount = 20; | ||
118 | SceneObjectGroup g1 = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); | ||
119 | |||
120 | g1.GroupResize(firstSize); | ||
121 | g1.GroupResize(secondSize); | ||
122 | |||
123 | Assert.That(g1.RootPart.UndoCount, Is.EqualTo(0)); | ||
124 | |||
125 | g1.RootPart.Undo(); | ||
126 | |||
127 | Assert.That(g1.GroupScale, Is.EqualTo(secondSize)); | ||
128 | } | ||
129 | |||
130 | [Test] | ||
131 | public void TestUndoBeyondAvailable() | ||
132 | { | ||
133 | TestHelpers.InMethod(); | ||
134 | |||
135 | Vector3 newSize = new Vector3(2, 3, 4); | ||
136 | |||
137 | Scene scene = new SceneHelpers().SetupScene(); | ||
138 | scene.MaxUndoCount = 20; | ||
139 | SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene); | ||
140 | Vector3 originalSize = g1.GroupScale; | ||
141 | |||
142 | g1.RootPart.Undo(); | ||
143 | |||
144 | Assert.That(g1.RootPart.UndoCount, Is.EqualTo(0)); | ||
145 | Assert.That(g1.GroupScale, Is.EqualTo(originalSize)); | ||
146 | |||
147 | g1.GroupResize(newSize); | ||
148 | Assert.That(g1.RootPart.UndoCount, Is.EqualTo(1)); | ||
149 | Assert.That(g1.GroupScale, Is.EqualTo(newSize)); | ||
150 | |||
151 | g1.RootPart.Undo(); | ||
152 | g1.RootPart.Undo(); | ||
153 | |||
154 | Assert.That(g1.RootPart.UndoCount, Is.EqualTo(0)); | ||
155 | Assert.That(g1.GroupScale, Is.EqualTo(originalSize)); | ||
156 | } | ||
157 | |||
158 | [Test] | ||
159 | public void TestRedoBeyondAvailable() | ||
160 | { | ||
161 | TestHelpers.InMethod(); | ||
162 | |||
163 | Vector3 newSize = new Vector3(2, 3, 4); | ||
164 | |||
165 | Scene scene = new SceneHelpers().SetupScene(); | ||
166 | scene.MaxUndoCount = 20; | ||
167 | SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene); | ||
168 | Vector3 originalSize = g1.GroupScale; | ||
169 | |||
170 | g1.RootPart.Redo(); | ||
171 | |||
172 | Assert.That(g1.RootPart.UndoCount, Is.EqualTo(0)); | ||
173 | Assert.That(g1.GroupScale, Is.EqualTo(originalSize)); | ||
174 | |||
175 | g1.GroupResize(newSize); | ||
176 | g1.RootPart.Undo(); | ||
177 | g1.RootPart.Redo(); | ||
178 | g1.RootPart.Redo(); | ||
179 | |||
180 | Assert.That(g1.RootPart.UndoCount, Is.EqualTo(1)); | ||
181 | Assert.That(g1.GroupScale, Is.EqualTo(newSize)); | ||
182 | } | ||
183 | } | ||
184 | } \ 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; | |||
44 | namespace OpenSim.Region.Framework.Scenes.Tests | 44 | namespace OpenSim.Region.Framework.Scenes.Tests |
45 | { | 45 | { |
46 | [TestFixture] | 46 | [TestFixture] |
47 | public class SceneObjectUserGroupTests | 47 | public class SceneObjectUserGroupTests : OpenSimTestCase |
48 | { | 48 | { |
49 | /// <summary> | 49 | /// <summary> |
50 | /// Test share with group object functionality | 50 | /// Test share with group object functionality |
@@ -54,7 +54,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
54 | public void TestShareWithGroup() | 54 | public void TestShareWithGroup() |
55 | { | 55 | { |
56 | TestHelpers.InMethod(); | 56 | TestHelpers.InMethod(); |
57 | // log4net.Config.XmlConfigurator.Configure(); | ||
58 | 57 | ||
59 | UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); | 58 | UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); |
60 | 59 | ||
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index b21a214..c7df7bb 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example | |||
@@ -97,6 +97,10 @@ | |||
97 | ;; from the selected region_info_source. | 97 | ;; from the selected region_info_source. |
98 | ; allow_regionless = false | 98 | ; allow_regionless = false |
99 | 99 | ||
100 | ;# {MaxPrimUndos} {} {Maximum number of undos avialable for position, rotation and scale changes of each prim} {} 20 | ||
101 | ;; Increasing the number of undos available number will increase memory usage. | ||
102 | MaxPrimUndos = 20 | ||
103 | |||
100 | ;# {NonPhysicalPrimMin} {} {Minimum size of nonphysical prims?} {} 0.001 | 104 | ;# {NonPhysicalPrimMin} {} {Minimum size of nonphysical prims?} {} 0.001 |
101 | ;; Minimum size for non-physical prims. Affects resizing of existing | 105 | ;; Minimum size for non-physical prims. Affects resizing of existing |
102 | ;; prims. This can be overriden in the region config file (as | 106 | ;; prims. This can be overriden in the region config file (as |
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 315ffbe..9c32abd 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini | |||
@@ -85,6 +85,10 @@ | |||
85 | ;; from the selected region_info_source. | 85 | ;; from the selected region_info_source. |
86 | allow_regionless = false | 86 | allow_regionless = false |
87 | 87 | ||
88 | ; Maximum number of position, rotation and scale changes for each prim that the simulator will store for later undos | ||
89 | ; Increasing this number will increase memory usage. | ||
90 | MaxPrimUndos = 20 | ||
91 | |||
88 | ; Maximum size of non physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonPhysicalPrimMax!). | 92 | ; Maximum size of non physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonPhysicalPrimMax!). |
89 | NonPhysicalPrimMax = 256 | 93 | NonPhysicalPrimMax = 256 |
90 | 94 | ||