From ab235abc46e3d902a7aaf61e589b81f826a2d7a5 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 11 Mar 2012 00:36:34 +0000 Subject: Changed undo redo internals. moved exec code to UndoState.cs from sop that now only sees a unified UndoRedoStore class, added size limit on buffers so only last 5 undo/redo are kept. (5 is hardcode like it was ) ***UNTESTED*** --- OpenSim/Region/Framework/Scenes/UndoState.cs | 176 ++++++++++++++++++++++++++- 1 file changed, 173 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/UndoState.cs') diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index eb76ca5..668b53b 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -27,6 +27,7 @@ using System; using System.Reflection; +using System.Collections.Generic; using log4net; using OpenMetaverse; using OpenSim.Region.Framework.Interfaces; @@ -34,6 +35,8 @@ using System; namespace OpenSim.Region.Framework.Scenes { + +/* [Flags] public enum UndoType { @@ -48,7 +51,7 @@ namespace OpenSim.Region.Framework.Scenes STATE_ALL = 63 } -/* + public class UndoState { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -194,7 +197,10 @@ namespace OpenSim.Region.Framework.Scenes */ public class UndoState { + const int UNDOEXPIRESECONDS = 300; // undo expire time (nice to have it came from a ini later) + public ObjectChangeData data; + public DateTime creationtime; /// /// Constructor. /// @@ -204,8 +210,8 @@ namespace OpenSim.Region.Framework.Scenes public UndoState(SceneObjectPart part, ObjectChangeWhat what) { data = new ObjectChangeData(); - data.what = what; + creationtime = DateTime.UtcNow; if (part.ParentGroup.RootPart == part) { @@ -227,12 +233,25 @@ namespace OpenSim.Region.Framework.Scenes } } + public bool checkExpire() + { + TimeSpan t = DateTime.UtcNow - creationtime; + if (t.Seconds > UNDOEXPIRESECONDS) + return true; + return false; + } + + public void updateExpire() + { + creationtime = DateTime.UtcNow; + } + /// /// Compare the relevant state in the given part to this state. /// /// /// true if both the part's position, rotation and scale match those in this undo state. False otherwise. - public bool Compare(SceneObjectPart part, ObjectChangeWhat what) + public bool Compare(SceneObjectPart part, ObjectChangeWhat what) { if (data.what != what) // if diferent targets, then they are diferent return false; @@ -274,6 +293,157 @@ namespace OpenSim.Region.Framework.Scenes } } + public class UndoRedoState + { + int size; + public LinkedList m_redo = new LinkedList(); + public LinkedList m_undo = new LinkedList(); + + public UndoRedoState() + { + size = 5; + } + + public UndoRedoState(int _size) + { + if (_size < 3) + size = 3; + else + size = _size; + } + + public int Count + { + get { return m_undo.Count; } + } + + public void Clear() + { + m_undo.Clear(); + m_redo.Clear(); + } + + public void StoreUndo(SceneObjectPart part, ObjectChangeWhat what) + { + lock (m_undo) + { + UndoState last; + + if (m_redo.Count > 0) // last code seems to clear redo on every new undo + { + m_redo.Clear(); + } + + if (m_undo.Count > 0) + { + // check expired entry + last = m_undo.First.Value; + if (last != null && last.checkExpire()) + m_undo.Clear(); + else + { + // see if we actually have a change + if (last != null) + { + if (last.Compare(part, what)) + return; + } + } + } + + // limite size + while (m_undo.Count >= size) + m_undo.RemoveLast(); + + UndoState nUndo = new UndoState(part, what); + m_undo.AddFirst(nUndo); + } + } + + public void Undo(SceneObjectPart part) + { + lock (m_undo) + { + UndoState nUndo; + + // expire redo + if (m_redo.Count > 0) + { + nUndo = m_redo.First.Value; + if (nUndo != null && nUndo.checkExpire()) + m_redo.Clear(); + } + + if (m_undo.Count > 0) + { + UndoState goback = m_undo.First.Value; + // check expired + if (goback != null && goback.checkExpire()) + { + m_undo.Clear(); + return; + } + + if (goback != null) + { + m_undo.RemoveFirst(); + + // redo limite size + while (m_redo.Count >= size) + m_redo.RemoveLast(); + + nUndo = new UndoState(part, goback.data.what); // new value in part should it be full goback copy? + m_redo.AddFirst(nUndo); + + goback.PlayState(part); + } + } + } + } + + public void Redo(SceneObjectPart part) + { + lock (m_undo) + { + UndoState nUndo; + + // expire undo + if (m_undo.Count > 0) + { + nUndo = m_undo.First.Value; + if (nUndo != null && nUndo.checkExpire()) + m_undo.Clear(); + } + + if (m_redo.Count > 0) + { + UndoState gofwd = m_redo.First.Value; + // check expired + if (gofwd != null && gofwd.checkExpire()) + { + m_redo.Clear(); + return; + } + + if (gofwd != null) + { + m_redo.RemoveFirst(); + + // limite undo size + while (m_undo.Count >= size) + m_undo.RemoveLast(); + + nUndo = new UndoState(part, gofwd.data.what); // new value in part should it be full gofwd copy? + m_undo.AddFirst(nUndo); + + gofwd.PlayState(part); + } + } + } + } + + + } public class LandUndoState { -- cgit v1.1