diff options
author | Teravus Ovares | 2008-04-28 01:48:21 +0000 |
---|---|---|
committer | Teravus Ovares | 2008-04-28 01:48:21 +0000 |
commit | 1fb54b074c243bab1964b4a568d672e87d18655f (patch) | |
tree | 1a9a113d09b94a10e5113e1b2e613039029d52a7 /OpenSim | |
parent | * Added String(FileExtension) property to ITerrainLoader to allow us to deter... (diff) | |
download | opensim-SC_OLD-1fb54b074c243bab1964b4a568d672e87d18655f.zip opensim-SC_OLD-1fb54b074c243bab1964b4a568d672e87d18655f.tar.gz opensim-SC_OLD-1fb54b074c243bab1964b4a568d672e87d18655f.tar.bz2 opensim-SC_OLD-1fb54b074c243bab1964b4a568d672e87d18655f.tar.xz |
* Added basic 3-5 level undo on prim position/rotation/scale.
* In the future this should be a config option... and, hopefully this tides the builders over for a little while.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/IClientAPI.cs | 2 | ||||
-rw-r--r-- | OpenSim/Framework/UndoStack.cs | 128 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/ClientView.cs | 19 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/InnerScene.cs | 14 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/Scene.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs | 25 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/SceneObjectPart.cs | 69 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/UndoState.cs | 118 | ||||
-rw-r--r-- | OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | 1 |
9 files changed, 370 insertions, 8 deletions
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index fb32397..985e085 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -570,6 +570,8 @@ namespace OpenSim.Framework | |||
570 | event UUIDNameRequest OnTeleportHomeRequest; | 570 | event UUIDNameRequest OnTeleportHomeRequest; |
571 | 571 | ||
572 | event ScriptAnswer OnScriptAnswer; | 572 | event ScriptAnswer OnScriptAnswer; |
573 | |||
574 | event AgentSit OnUndo; | ||
573 | 575 | ||
574 | LLVector3 StartPos { get; set; } | 576 | LLVector3 StartPos { get; set; } |
575 | 577 | ||
diff --git a/OpenSim/Framework/UndoStack.cs b/OpenSim/Framework/UndoStack.cs new file mode 100644 index 0000000..0b97644 --- /dev/null +++ b/OpenSim/Framework/UndoStack.cs | |||
@@ -0,0 +1,128 @@ | |||
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 OpenSim 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.Collections.Generic; | ||
30 | using System.Text; | ||
31 | |||
32 | namespace OpenSim.Framework | ||
33 | { | ||
34 | /// <summary> | ||
35 | /// Undo stack. Deletes entries beyond a certain capacity | ||
36 | /// </summary> | ||
37 | /// <typeparam name="T"></typeparam> | ||
38 | [Serializable] | ||
39 | public class UndoStack<T> | ||
40 | { | ||
41 | |||
42 | private int m_new = 1; | ||
43 | private int m_old = 0; | ||
44 | private T[] m_Undos; | ||
45 | |||
46 | public bool IsFull | ||
47 | { | ||
48 | get | ||
49 | { | ||
50 | return m_new == m_old; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | |||
55 | public int Capacity | ||
56 | { | ||
57 | get | ||
58 | { | ||
59 | return m_Undos.Length - 1; | ||
60 | } | ||
61 | } | ||
62 | |||
63 | |||
64 | public UndoStack(int capacity) | ||
65 | { | ||
66 | m_Undos = new T[capacity + 1]; | ||
67 | } | ||
68 | |||
69 | public void Push(T item) | ||
70 | { | ||
71 | if (IsFull) | ||
72 | { | ||
73 | m_old++; | ||
74 | if (m_old >= m_Undos.Length) | ||
75 | m_old -= m_Undos.Length; | ||
76 | } | ||
77 | if (++m_new >= m_Undos.Length) | ||
78 | m_new -= m_Undos.Length; | ||
79 | m_Undos[m_new] = item; | ||
80 | } | ||
81 | |||
82 | public T Pop() | ||
83 | { | ||
84 | if (Count > 0) | ||
85 | { | ||
86 | T deleted = m_Undos[m_new]; | ||
87 | m_Undos[m_new--] = default(T); | ||
88 | if (m_new < 0) | ||
89 | m_new += m_Undos.Length; | ||
90 | return deleted; | ||
91 | } | ||
92 | else | ||
93 | throw new InvalidOperationException("Cannot pop from emtpy stack"); | ||
94 | } | ||
95 | |||
96 | public int Count | ||
97 | { | ||
98 | get | ||
99 | { | ||
100 | int count = m_new - m_old - 1; | ||
101 | if (count < 0) | ||
102 | count += m_Undos.Length; | ||
103 | return count; | ||
104 | } | ||
105 | } | ||
106 | |||
107 | |||
108 | public T Peek() | ||
109 | { | ||
110 | return m_Undos[m_new]; | ||
111 | } | ||
112 | |||
113 | |||
114 | public void Clear() | ||
115 | { | ||
116 | if (Count > 0) | ||
117 | { | ||
118 | for (int i = 0; i < m_Undos.Length; i++) | ||
119 | { | ||
120 | m_Undos[i] = default(T); | ||
121 | } | ||
122 | m_new = 1; | ||
123 | m_old = 0; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | } | ||
128 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 94de013..aac96d1 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs | |||
@@ -238,6 +238,7 @@ namespace OpenSim.Region.ClientStack | |||
238 | private ScriptAnswer handlerScriptAnswer = null; | 238 | private ScriptAnswer handlerScriptAnswer = null; |
239 | private RequestPayPrice handlerRequestPayPrice = null; | 239 | private RequestPayPrice handlerRequestPayPrice = null; |
240 | private ObjectDeselect handlerObjectDetach = null; | 240 | private ObjectDeselect handlerObjectDetach = null; |
241 | private AgentSit handlerOnUndo = null; | ||
241 | 242 | ||
242 | /* Properties */ | 243 | /* Properties */ |
243 | 244 | ||
@@ -799,6 +800,7 @@ namespace OpenSim.Region.ClientStack | |||
799 | 800 | ||
800 | public event ScriptAnswer OnScriptAnswer; | 801 | public event ScriptAnswer OnScriptAnswer; |
801 | public event RequestPayPrice OnRequestPayPrice; | 802 | public event RequestPayPrice OnRequestPayPrice; |
803 | public event AgentSit OnUndo; | ||
802 | 804 | ||
803 | #region Scene/Avatar to Client | 805 | #region Scene/Avatar to Client |
804 | 806 | ||
@@ -3884,6 +3886,23 @@ namespace OpenSim.Region.ClientStack | |||
3884 | // That means multiple object perms may be updated in a single packet. | 3886 | // That means multiple object perms may be updated in a single packet. |
3885 | 3887 | ||
3886 | break; | 3888 | break; |
3889 | |||
3890 | case PacketType.Undo: | ||
3891 | UndoPacket undoitem = (UndoPacket)Pack; | ||
3892 | if (undoitem.ObjectData.Length > 0) | ||
3893 | { | ||
3894 | for (int i = 0; i < undoitem.ObjectData.Length; i++) | ||
3895 | { | ||
3896 | LLUUID objiD = undoitem.ObjectData[i].ObjectID; | ||
3897 | handlerOnUndo = OnUndo; | ||
3898 | if (handlerOnUndo != null) | ||
3899 | { | ||
3900 | handlerOnUndo(this, objiD); | ||
3901 | } | ||
3902 | |||
3903 | } | ||
3904 | } | ||
3905 | break; | ||
3887 | case PacketType.ObjectDuplicateOnRay: | 3906 | case PacketType.ObjectDuplicateOnRay: |
3888 | ObjectDuplicateOnRayPacket dupeOnRay = (ObjectDuplicateOnRayPacket)Pack; | 3907 | ObjectDuplicateOnRayPacket dupeOnRay = (ObjectDuplicateOnRayPacket)Pack; |
3889 | 3908 | ||
diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index d00f601..8a48f6e 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs | |||
@@ -312,6 +312,20 @@ namespace OpenSim.Region.Environment.Scenes | |||
312 | } | 312 | } |
313 | 313 | ||
314 | } | 314 | } |
315 | |||
316 | public void HandleUndo(IClientAPI remoteClient, LLUUID primId) | ||
317 | { | ||
318 | if (primId != LLUUID.Zero) | ||
319 | { | ||
320 | SceneObjectPart part = m_parentScene.GetSceneObjectPart(primId); | ||
321 | if (part != null) | ||
322 | part.Undo(); | ||
323 | |||
324 | } | ||
325 | |||
326 | |||
327 | } | ||
328 | |||
315 | /// <summary> | 329 | /// <summary> |
316 | /// Event Handling routine for Attach Object | 330 | /// Event Handling routine for Attach Object |
317 | /// </summary> | 331 | /// </summary> |
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index a517e69..de4270f 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs | |||
@@ -78,6 +78,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
78 | private readonly Mutex updateLock; | 78 | private readonly Mutex updateLock; |
79 | public bool m_physicalPrim; | 79 | public bool m_physicalPrim; |
80 | public bool m_seeIntoRegionFromNeighbor; | 80 | public bool m_seeIntoRegionFromNeighbor; |
81 | public int MaxUndoCount = 5; | ||
81 | private int m_RestartTimerCounter; | 82 | private int m_RestartTimerCounter; |
82 | private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing | 83 | private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing |
83 | private int m_incrementsof15seconds = 0; | 84 | private int m_incrementsof15seconds = 0; |
@@ -1628,6 +1629,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
1628 | client.OnTeleportHomeRequest += TeleportClientHome; | 1629 | client.OnTeleportHomeRequest += TeleportClientHome; |
1629 | 1630 | ||
1630 | client.OnSetStartLocationRequest += SetHomeRezPoint; | 1631 | client.OnSetStartLocationRequest += SetHomeRezPoint; |
1632 | client.OnUndo += m_innerScene.HandleUndo; | ||
1631 | 1633 | ||
1632 | EventManager.TriggerOnNewClient(client); | 1634 | EventManager.TriggerOnNewClient(client); |
1633 | } | 1635 | } |
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index ba318a8..4711701 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs | |||
@@ -378,6 +378,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
378 | part.RegionHandle = m_regionHandle; | 378 | part.RegionHandle = m_regionHandle; |
379 | 379 | ||
380 | part.TrimPermissions(); | 380 | part.TrimPermissions(); |
381 | part.StoreUndoState(); | ||
381 | } | 382 | } |
382 | break; | 383 | break; |
383 | case XmlNodeType.EndElement: | 384 | case XmlNodeType.EndElement: |
@@ -436,6 +437,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
436 | { | 437 | { |
437 | SceneObjectPart Part = SceneObjectPart.FromXml(reader); | 438 | SceneObjectPart Part = SceneObjectPart.FromXml(reader); |
438 | AddPart(Part); | 439 | AddPart(Part); |
440 | Part.StoreUndoState(); | ||
439 | } | 441 | } |
440 | else | 442 | else |
441 | { | 443 | { |
@@ -703,6 +705,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
703 | m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_scene.m_physicalPrim); | 705 | m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_scene.m_physicalPrim); |
704 | AttachToBackup(); | 706 | AttachToBackup(); |
705 | m_rootPart.ScheduleFullUpdate(); | 707 | m_rootPart.ScheduleFullUpdate(); |
708 | m_rootPart.ClearUndoState(); | ||
709 | |||
706 | } | 710 | } |
707 | public void DetachToInventoryPrep() | 711 | public void DetachToInventoryPrep() |
708 | { | 712 | { |
@@ -731,6 +735,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
731 | private void SetPartAsNonRoot(SceneObjectPart part) | 735 | private void SetPartAsNonRoot(SceneObjectPart part) |
732 | { | 736 | { |
733 | part.ParentID = m_rootPart.LocalId; | 737 | part.ParentID = m_rootPart.LocalId; |
738 | part.ClearUndoState(); | ||
734 | } | 739 | } |
735 | 740 | ||
736 | /// <summary> | 741 | /// <summary> |
@@ -783,6 +788,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
783 | try | 788 | try |
784 | { | 789 | { |
785 | m_parts.Add(part.UUID, part); | 790 | m_parts.Add(part.UUID, part); |
791 | |||
786 | } | 792 | } |
787 | catch (Exception e) | 793 | catch (Exception e) |
788 | { | 794 | { |
@@ -803,6 +809,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
803 | if (part.UUID != m_rootPart.UUID) | 809 | if (part.UUID != m_rootPart.UUID) |
804 | { | 810 | { |
805 | part.ParentID = m_rootPart.LocalId; | 811 | part.ParentID = m_rootPart.LocalId; |
812 | |||
806 | } | 813 | } |
807 | } | 814 | } |
808 | } | 815 | } |
@@ -815,10 +822,17 @@ namespace OpenSim.Region.Environment.Scenes | |||
815 | foreach (SceneObjectPart part in m_parts.Values) | 822 | foreach (SceneObjectPart part in m_parts.Values) |
816 | { | 823 | { |
817 | part.UUID = LLUUID.Random(); | 824 | part.UUID = LLUUID.Random(); |
825 | |||
818 | } | 826 | } |
819 | } | 827 | } |
820 | } | 828 | } |
821 | 829 | // helper provided for parts. | |
830 | public int GetSceneMaxUndo() | ||
831 | { | ||
832 | if (m_scene != null) | ||
833 | return m_scene.MaxUndoCount; | ||
834 | return 5; | ||
835 | } | ||
822 | public void ResetChildPrimPhysicsPositions() | 836 | public void ResetChildPrimPhysicsPositions() |
823 | { | 837 | { |
824 | AbsolutePosition = AbsolutePosition; | 838 | AbsolutePosition = AbsolutePosition; |
@@ -845,12 +859,15 @@ namespace OpenSim.Region.Environment.Scenes | |||
845 | { | 859 | { |
846 | SceneObjectPart part = GetChildPart(localId); | 860 | SceneObjectPart part = GetChildPart(localId); |
847 | OnGrabPart(part, offsetPos, remoteClient); | 861 | OnGrabPart(part, offsetPos, remoteClient); |
862 | |||
848 | } | 863 | } |
849 | } | 864 | } |
850 | 865 | ||
851 | public virtual void OnGrabPart(SceneObjectPart part, LLVector3 offsetPos, IClientAPI remoteClient) | 866 | public virtual void OnGrabPart(SceneObjectPart part, LLVector3 offsetPos, IClientAPI remoteClient) |
852 | { | 867 | { |
868 | part.StoreUndoState(); | ||
853 | part.OnGrab(offsetPos, remoteClient); | 869 | part.OnGrab(offsetPos, remoteClient); |
870 | |||
854 | } | 871 | } |
855 | 872 | ||
856 | public virtual void OnGrabGroup(LLVector3 offsetPos, IClientAPI remoteClient) | 873 | public virtual void OnGrabGroup(LLVector3 offsetPos, IClientAPI remoteClient) |
@@ -1382,8 +1399,9 @@ namespace OpenSim.Region.Environment.Scenes | |||
1382 | { | 1399 | { |
1383 | m_parts.Add(newPart.UUID, newPart); | 1400 | m_parts.Add(newPart.UUID, newPart); |
1384 | } | 1401 | } |
1385 | 1402 | ||
1386 | SetPartAsNonRoot(newPart); | 1403 | SetPartAsNonRoot(newPart); |
1404 | |||
1387 | } | 1405 | } |
1388 | 1406 | ||
1389 | /// <summary> | 1407 | /// <summary> |
@@ -1758,6 +1776,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
1758 | { | 1776 | { |
1759 | LinkNonRootPart(part, oldGroupPosition, oldRootRotation); | 1777 | LinkNonRootPart(part, oldGroupPosition, oldRootRotation); |
1760 | } | 1778 | } |
1779 | part.ClearUndoState(); | ||
1761 | } | 1780 | } |
1762 | 1781 | ||
1763 | DetachFromBackup(objectGroup); | 1782 | DetachFromBackup(objectGroup); |
@@ -1781,7 +1800,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
1781 | public void DelinkFromGroup(uint partID) | 1800 | public void DelinkFromGroup(uint partID) |
1782 | { | 1801 | { |
1783 | SceneObjectPart linkPart = GetChildPart(partID); | 1802 | SceneObjectPart linkPart = GetChildPart(partID); |
1784 | 1803 | linkPart.ClearUndoState(); | |
1785 | if (null != linkPart) | 1804 | if (null != linkPart) |
1786 | { | 1805 | { |
1787 | // m_log.DebugFormat( | 1806 | // m_log.DebugFormat( |
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index 0db9b91..6cfe3e9 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | ||
29 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
30 | using System.Drawing; | 31 | using System.Drawing; |
31 | using System.Runtime.Serialization; | 32 | using System.Runtime.Serialization; |
@@ -106,6 +107,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
106 | [XmlIgnore] public LLVector3 m_attachedPos = LLVector3.Zero; | 107 | [XmlIgnore] public LLVector3 m_attachedPos = LLVector3.Zero; |
107 | [XmlIgnore] public LLUUID fromAssetID = LLUUID.Zero; | 108 | [XmlIgnore] public LLUUID fromAssetID = LLUUID.Zero; |
108 | 109 | ||
110 | [XmlIgnore] public bool m_undoing = false; | ||
111 | |||
109 | public Int32 CreationDate; | 112 | public Int32 CreationDate; |
110 | public uint ParentID = 0; | 113 | public uint ParentID = 0; |
111 | 114 | ||
@@ -123,6 +126,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
123 | public uint EveryoneMask = (uint)PermissionMask.None; | 126 | public uint EveryoneMask = (uint)PermissionMask.None; |
124 | public uint NextOwnerMask = (uint)PermissionMask.All; | 127 | public uint NextOwnerMask = (uint)PermissionMask.All; |
125 | 128 | ||
129 | private UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); | ||
130 | |||
126 | public LLObject.ObjectFlags Flags = LLObject.ObjectFlags.None; | 131 | public LLObject.ObjectFlags Flags = LLObject.ObjectFlags.None; |
127 | 132 | ||
128 | public uint ObjectFlags | 133 | public uint ObjectFlags |
@@ -266,6 +271,40 @@ namespace OpenSim.Region.Environment.Scenes | |||
266 | //return new LLQuaternion(axiomPartRotation.x, axiomPartRotation.y, axiomPartRotation.z, axiomPartRotation.w); | 271 | //return new LLQuaternion(axiomPartRotation.x, axiomPartRotation.y, axiomPartRotation.z, axiomPartRotation.w); |
267 | 272 | ||
268 | } | 273 | } |
274 | |||
275 | public void StoreUndoState() | ||
276 | { | ||
277 | if (!m_undoing) | ||
278 | { | ||
279 | if (m_parentGroup != null) | ||
280 | { | ||
281 | if (m_undo.Count > 0) | ||
282 | { | ||
283 | UndoState last = m_undo.Peek(); | ||
284 | if (last != null) | ||
285 | { | ||
286 | if (last.Compare(this)) | ||
287 | return; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | |||
292 | if (m_parentGroup.GetSceneMaxUndo() > 0) | ||
293 | { | ||
294 | UndoState nUndo = new UndoState(this); | ||
295 | |||
296 | m_undo.Push(nUndo); | ||
297 | |||
298 | } | ||
299 | } | ||
300 | } | ||
301 | } | ||
302 | |||
303 | public void ClearUndoState() | ||
304 | { | ||
305 | m_undo.Clear(); | ||
306 | StoreUndoState(); | ||
307 | } | ||
269 | 308 | ||
270 | public LLVector3 GroupPosition | 309 | public LLVector3 GroupPosition |
271 | { | 310 | { |
@@ -290,7 +329,9 @@ namespace OpenSim.Region.Environment.Scenes | |||
290 | return m_groupPosition; | 329 | return m_groupPosition; |
291 | } | 330 | } |
292 | set | 331 | set |
293 | { | 332 | { |
333 | StoreUndoState(); | ||
334 | |||
294 | m_groupPosition = value; | 335 | m_groupPosition = value; |
295 | 336 | ||
296 | if (PhysActor != null) | 337 | if (PhysActor != null) |
@@ -334,7 +375,10 @@ namespace OpenSim.Region.Environment.Scenes | |||
334 | public LLVector3 OffsetPosition | 375 | public LLVector3 OffsetPosition |
335 | { | 376 | { |
336 | get { return m_offsetPosition; } | 377 | get { return m_offsetPosition; } |
337 | set { m_offsetPosition = value; | 378 | set |
379 | { | ||
380 | StoreUndoState(); | ||
381 | m_offsetPosition = value; | ||
338 | try | 382 | try |
339 | { | 383 | { |
340 | // Hack to get the child prim to update world positions in the physics engine | 384 | // Hack to get the child prim to update world positions in the physics engine |
@@ -380,6 +424,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
380 | } | 424 | } |
381 | set | 425 | set |
382 | { | 426 | { |
427 | StoreUndoState(); | ||
383 | m_rotationOffset = value; | 428 | m_rotationOffset = value; |
384 | 429 | ||
385 | if (PhysActor != null) | 430 | if (PhysActor != null) |
@@ -650,7 +695,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
650 | { | 695 | { |
651 | get { return m_shape.Scale; } | 696 | get { return m_shape.Scale; } |
652 | set | 697 | set |
653 | { | 698 | { |
699 | StoreUndoState(); | ||
654 | m_shape.Scale = value; | 700 | m_shape.Scale = value; |
655 | TriggerScriptChangedEvent(Changed.SCALE); | 701 | TriggerScriptChangedEvent(Changed.SCALE); |
656 | } | 702 | } |
@@ -759,7 +805,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
759 | LLObject.ObjectFlags.CreateSelected; | 805 | LLObject.ObjectFlags.CreateSelected; |
760 | 806 | ||
761 | TrimPermissions(); | 807 | TrimPermissions(); |
762 | 808 | //m_undo = new UndoStack<UndoState>(ParentGroup.GetSceneMaxUndo()); | |
809 | |||
763 | ScheduleFullUpdate(); | 810 | ScheduleFullUpdate(); |
764 | } | 811 | } |
765 | 812 | ||
@@ -802,7 +849,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
802 | 849 | ||
803 | TrimPermissions(); | 850 | TrimPermissions(); |
804 | // ApplyPhysics(); | 851 | // ApplyPhysics(); |
805 | 852 | ||
806 | ScheduleFullUpdate(); | 853 | ScheduleFullUpdate(); |
807 | } | 854 | } |
808 | 855 | ||
@@ -1982,6 +2029,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
1982 | 2029 | ||
1983 | public void UpdateRotation(LLQuaternion rot) | 2030 | public void UpdateRotation(LLQuaternion rot) |
1984 | { | 2031 | { |
2032 | //StoreUndoState(); | ||
1985 | RotationOffset = new LLQuaternion(rot.X, rot.Y, rot.Z, rot.W); | 2033 | RotationOffset = new LLQuaternion(rot.X, rot.Y, rot.Z, rot.W); |
1986 | ScheduleTerseUpdate(); | 2034 | ScheduleTerseUpdate(); |
1987 | } | 2035 | } |
@@ -2097,6 +2145,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
2097 | /// <param name="scale"></param> | 2145 | /// <param name="scale"></param> |
2098 | public void Resize(LLVector3 scale) | 2146 | public void Resize(LLVector3 scale) |
2099 | { | 2147 | { |
2148 | StoreUndoState(); | ||
2100 | m_shape.Scale = scale; | 2149 | m_shape.Scale = scale; |
2101 | 2150 | ||
2102 | ScheduleFullUpdate(); | 2151 | ScheduleFullUpdate(); |
@@ -2522,5 +2571,15 @@ namespace OpenSim.Region.Environment.Scenes | |||
2522 | info.AddValue("PayPrice", PayPrice); | 2571 | info.AddValue("PayPrice", PayPrice); |
2523 | } | 2572 | } |
2524 | 2573 | ||
2574 | |||
2575 | public void Undo() | ||
2576 | { | ||
2577 | if (m_undo.Count > 0) | ||
2578 | { | ||
2579 | UndoState goback = m_undo.Pop(); | ||
2580 | if (goback != null) | ||
2581 | goback.PlaybackState(this); | ||
2582 | } | ||
2583 | } | ||
2525 | } | 2584 | } |
2526 | } | 2585 | } |
diff --git a/OpenSim/Region/Environment/Scenes/UndoState.cs b/OpenSim/Region/Environment/Scenes/UndoState.cs new file mode 100644 index 0000000..65c8669 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/UndoState.cs | |||
@@ -0,0 +1,118 @@ | |||
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 OpenSim 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.Collections.Generic; | ||
30 | using libsecondlife; | ||
31 | |||
32 | namespace OpenSim.Region.Environment.Scenes | ||
33 | { | ||
34 | public class UndoState | ||
35 | { | ||
36 | public LLVector3 Position = LLVector3.Zero; | ||
37 | public LLVector3 Scale = LLVector3.Zero; | ||
38 | public LLQuaternion Rotation = LLQuaternion.Identity; | ||
39 | |||
40 | public UndoState(LLVector3 pos, LLQuaternion rot, LLVector3 scale) | ||
41 | { | ||
42 | Position = pos; | ||
43 | Rotation = rot; | ||
44 | Scale = scale; | ||
45 | } | ||
46 | |||
47 | public UndoState(SceneObjectPart part) | ||
48 | { | ||
49 | if (part != null) | ||
50 | { | ||
51 | if (part.ParentID == 0) | ||
52 | { | ||
53 | Position = part.AbsolutePosition; | ||
54 | Rotation = part.RotationOffset; | ||
55 | |||
56 | } | ||
57 | else | ||
58 | { | ||
59 | Position = part.GroupPosition; | ||
60 | Rotation = part.RotationOffset; | ||
61 | Scale = part.Shape.Scale; | ||
62 | |||
63 | } | ||
64 | } | ||
65 | } | ||
66 | |||
67 | public bool Compare(SceneObjectPart part) | ||
68 | { | ||
69 | if (part != null) | ||
70 | { | ||
71 | if (part.ParentID == 0) | ||
72 | { | ||
73 | if (Position == part.AbsolutePosition && Rotation == part.RotationOffset) | ||
74 | return true; | ||
75 | else | ||
76 | return false; | ||
77 | } | ||
78 | else | ||
79 | { | ||
80 | if (Position == part.GroupPosition && Rotation == part.RotationOffset && Scale == part.Shape.Scale) | ||
81 | return true; | ||
82 | else | ||
83 | return false; | ||
84 | |||
85 | } | ||
86 | } | ||
87 | return false; | ||
88 | } | ||
89 | |||
90 | public void PlaybackState(SceneObjectPart part) | ||
91 | { | ||
92 | if (part != null) | ||
93 | { | ||
94 | part.m_undoing = true; | ||
95 | |||
96 | if (part.ParentID == 0) | ||
97 | { | ||
98 | part.ParentGroup.AbsolutePosition = Position; | ||
99 | part.UpdateRotation(Rotation); | ||
100 | part.ParentGroup.ScheduleGroupForTerseUpdate(); | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | part.OffsetPosition = Position; | ||
105 | part.UpdateRotation(Rotation); | ||
106 | part.Resize(Scale); | ||
107 | part.ScheduleTerseUpdate(); | ||
108 | } | ||
109 | part.m_undoing = false; | ||
110 | |||
111 | } | ||
112 | } | ||
113 | |||
114 | public UndoState() | ||
115 | { | ||
116 | } | ||
117 | } | ||
118 | } | ||
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 9e57da5..59a2fd8 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | |||
@@ -171,6 +171,7 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
171 | 171 | ||
172 | public event ScriptAnswer OnScriptAnswer; | 172 | public event ScriptAnswer OnScriptAnswer; |
173 | public event RequestPayPrice OnRequestPayPrice; | 173 | public event RequestPayPrice OnRequestPayPrice; |
174 | public event AgentSit OnUndo; | ||
174 | 175 | ||
175 | 176 | ||
176 | #pragma warning restore 67 | 177 | #pragma warning restore 67 |