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***
parent
908abb1c3d
commit
ab235abc46
|
@ -263,8 +263,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
private bool m_occupied; // KF if any av is sitting on this prim
|
private bool m_occupied; // KF if any av is sitting on this prim
|
||||||
private string m_text = String.Empty;
|
private string m_text = String.Empty;
|
||||||
private string m_touchName = String.Empty;
|
private string m_touchName = String.Empty;
|
||||||
private Stack<UndoState> m_undo = new Stack<UndoState>(5);
|
private UndoRedoState m_UndoRedo = new UndoRedoState(5);
|
||||||
private Stack<UndoState> m_redo = new Stack<UndoState>(5);
|
|
||||||
|
|
||||||
private bool m_passTouches;
|
private bool m_passTouches;
|
||||||
|
|
||||||
|
@ -1709,8 +1708,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
dupe.Category = Category;
|
dupe.Category = Category;
|
||||||
dupe.m_rezzed = m_rezzed;
|
dupe.m_rezzed = m_rezzed;
|
||||||
|
|
||||||
dupe.m_undo = new Stack<UndoState>(5);
|
dupe.m_UndoRedo = new UndoRedoState(5);
|
||||||
dupe.m_redo = new Stack<UndoState>(5);
|
|
||||||
dupe.IgnoreUndoUpdate = false;
|
dupe.IgnoreUndoUpdate = false;
|
||||||
dupe.Undoing = false;
|
dupe.Undoing = false;
|
||||||
|
|
||||||
|
@ -3657,82 +3656,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ParentGroup.ScheduleGroupForTerseUpdate();
|
ParentGroup.ScheduleGroupForTerseUpdate();
|
||||||
//ParentGroup.ScheduleGroupForFullUpdate();
|
//ParentGroup.ScheduleGroupForFullUpdate();
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
public void StoreUndoState()
|
|
||||||
{
|
|
||||||
StoreUndoState(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StoreUndoState(bool forGroup)
|
|
||||||
{
|
|
||||||
if (!Undoing && !IgnoreUndoUpdate) // just to read better - undo is in progress, or suspended
|
|
||||||
{
|
|
||||||
if (ParentGroup != null)
|
|
||||||
{
|
|
||||||
lock (m_undo)
|
|
||||||
{
|
|
||||||
if (m_undo.Count > 0)
|
|
||||||
{
|
|
||||||
// see if we had a change
|
|
||||||
|
|
||||||
UndoState last = m_undo.Peek();
|
|
||||||
if (last != null)
|
|
||||||
{
|
|
||||||
if (last.Compare(this, forGroup))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ParentGroup.GetSceneMaxUndo() > 0)
|
|
||||||
{
|
|
||||||
UndoState nUndo = new UndoState(this, forGroup);
|
|
||||||
|
|
||||||
m_undo.Push(nUndo);
|
|
||||||
|
|
||||||
if (m_redo.Count > 0)
|
|
||||||
m_redo.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
public void StoreUndoState(ObjectChangeWhat what)
|
public void StoreUndoState(ObjectChangeWhat what)
|
||||||
{
|
{
|
||||||
if (!Undoing && !IgnoreUndoUpdate) // just to read better - undo is in progress, or suspended
|
lock (m_UndoRedo)
|
||||||
{
|
{
|
||||||
if (ParentGroup != null)
|
if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
|
||||||
{
|
{
|
||||||
lock (m_undo)
|
m_UndoRedo.StoreUndo(this, what);
|
||||||
{
|
|
||||||
if (m_undo.Count > 0)
|
|
||||||
{
|
|
||||||
// see if we had a change
|
|
||||||
|
|
||||||
UndoState last = m_undo.Peek();
|
|
||||||
if (last != null)
|
|
||||||
{
|
|
||||||
if (last.Compare(this, what))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ParentGroup.GetSceneMaxUndo() > 0)
|
|
||||||
{
|
|
||||||
UndoState nUndo = new UndoState(this, what);
|
|
||||||
|
|
||||||
m_undo.Push(nUndo);
|
|
||||||
|
|
||||||
if (m_redo.Count > 0)
|
|
||||||
m_redo.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3744,84 +3675,42 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
lock (m_undo)
|
lock (m_UndoRedo)
|
||||||
return m_undo.Count;
|
return m_UndoRedo.Count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Undo()
|
public void Undo()
|
||||||
{
|
{
|
||||||
lock (m_undo)
|
lock (m_UndoRedo)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
if (Undoing || ParentGroup == null)
|
||||||
// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
|
return;
|
||||||
// Name, LocalId, m_undo.Count);
|
|
||||||
|
|
||||||
if (m_undo.Count > 0)
|
Undoing = true;
|
||||||
{
|
m_UndoRedo.Undo(this);
|
||||||
UndoState goback = m_undo.Pop();
|
Undoing = false;
|
||||||
|
|
||||||
if (goback != null)
|
|
||||||
{
|
|
||||||
UndoState nUndo = null;
|
|
||||||
|
|
||||||
if (ParentGroup.GetSceneMaxUndo() > 0)
|
|
||||||
{
|
|
||||||
nUndo = new UndoState(this, goback.data.what);
|
|
||||||
}
|
|
||||||
|
|
||||||
goback.PlayState(this);
|
|
||||||
|
|
||||||
if (nUndo != null)
|
|
||||||
m_redo.Push(nUndo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}",
|
|
||||||
// Name, LocalId, m_undo.Count);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Redo()
|
public void Redo()
|
||||||
{
|
{
|
||||||
lock (m_undo)
|
lock (m_UndoRedo)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
if (Undoing || ParentGroup == null)
|
||||||
// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
|
return;
|
||||||
// Name, LocalId, m_redo.Count);
|
|
||||||
|
|
||||||
if (m_redo.Count > 0)
|
Undoing = true;
|
||||||
{
|
m_UndoRedo.Redo(this);
|
||||||
UndoState gofwd = m_redo.Pop();
|
Undoing = false;
|
||||||
|
|
||||||
if (gofwd != null)
|
|
||||||
{
|
|
||||||
if (ParentGroup.GetSceneMaxUndo() > 0)
|
|
||||||
{
|
|
||||||
UndoState nUndo = new UndoState(this, gofwd.data.what);
|
|
||||||
|
|
||||||
m_undo.Push(nUndo);
|
|
||||||
}
|
|
||||||
|
|
||||||
gofwd.PlayState(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}",
|
|
||||||
// Name, LocalId, m_redo.Count);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearUndoState()
|
public void ClearUndoState()
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId);
|
lock (m_UndoRedo)
|
||||||
|
|
||||||
lock (m_undo)
|
|
||||||
{
|
{
|
||||||
m_undo.Clear();
|
m_UndoRedo.Clear();
|
||||||
m_redo.Clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
@ -34,6 +35,8 @@ using System;
|
||||||
|
|
||||||
namespace OpenSim.Region.Framework.Scenes
|
namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum UndoType
|
public enum UndoType
|
||||||
{
|
{
|
||||||
|
@ -48,7 +51,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
STATE_ALL = 63
|
STATE_ALL = 63
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
public class UndoState
|
public class UndoState
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
@ -194,7 +197,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
*/
|
*/
|
||||||
public class UndoState
|
public class UndoState
|
||||||
{
|
{
|
||||||
|
const int UNDOEXPIRESECONDS = 300; // undo expire time (nice to have it came from a ini later)
|
||||||
|
|
||||||
public ObjectChangeData data;
|
public ObjectChangeData data;
|
||||||
|
public DateTime creationtime;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -204,8 +210,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public UndoState(SceneObjectPart part, ObjectChangeWhat what)
|
public UndoState(SceneObjectPart part, ObjectChangeWhat what)
|
||||||
{
|
{
|
||||||
data = new ObjectChangeData();
|
data = new ObjectChangeData();
|
||||||
|
|
||||||
data.what = what;
|
data.what = what;
|
||||||
|
creationtime = DateTime.UtcNow;
|
||||||
|
|
||||||
if (part.ParentGroup.RootPart == part)
|
if (part.ParentGroup.RootPart == part)
|
||||||
{
|
{
|
||||||
|
@ -227,6 +233,19 @@ 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;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Compare the relevant state in the given part to this state.
|
/// Compare the relevant state in the given part to this state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -274,6 +293,157 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class UndoRedoState
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
public LinkedList<UndoState> m_redo = new LinkedList<UndoState>();
|
||||||
|
public LinkedList<UndoState> m_undo = new LinkedList<UndoState>();
|
||||||
|
|
||||||
|
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
|
public class LandUndoState
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue