diff options
author | UbitUmarov | 2012-03-11 00:36:34 +0000 |
---|---|---|
committer | UbitUmarov | 2012-03-11 00:36:34 +0000 |
commit | ab235abc46e3d902a7aaf61e589b81f826a2d7a5 (patch) | |
tree | b64df1477b670b49849ae28d236757f44ed3f901 | |
parent | BIG MESS. changed Iclient interface so only one event is used to inform scene... (diff) | |
download | opensim-SC_OLD-ab235abc46e3d902a7aaf61e589b81f826a2d7a5.zip opensim-SC_OLD-ab235abc46e3d902a7aaf61e589b81f826a2d7a5.tar.gz opensim-SC_OLD-ab235abc46e3d902a7aaf61e589b81f826a2d7a5.tar.bz2 opensim-SC_OLD-ab235abc46e3d902a7aaf61e589b81f826a2d7a5.tar.xz |
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***
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 155 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/UndoState.cs | 176 |
2 files changed, 195 insertions, 136 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index c806fda..f70b259 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -263,8 +263,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
263 | private bool m_occupied; // KF if any av is sitting on this prim | 263 | private bool m_occupied; // KF if any av is sitting on this prim |
264 | private string m_text = String.Empty; | 264 | private string m_text = String.Empty; |
265 | private string m_touchName = String.Empty; | 265 | private string m_touchName = String.Empty; |
266 | private Stack<UndoState> m_undo = new Stack<UndoState>(5); | 266 | private UndoRedoState m_UndoRedo = new UndoRedoState(5); |
267 | private Stack<UndoState> m_redo = new Stack<UndoState>(5); | ||
268 | 267 | ||
269 | private bool m_passTouches; | 268 | private bool m_passTouches; |
270 | 269 | ||
@@ -1709,8 +1708,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1709 | dupe.Category = Category; | 1708 | dupe.Category = Category; |
1710 | dupe.m_rezzed = m_rezzed; | 1709 | dupe.m_rezzed = m_rezzed; |
1711 | 1710 | ||
1712 | dupe.m_undo = new Stack<UndoState>(5); | 1711 | dupe.m_UndoRedo = new UndoRedoState(5); |
1713 | dupe.m_redo = new Stack<UndoState>(5); | 1712 | |
1714 | dupe.IgnoreUndoUpdate = false; | 1713 | dupe.IgnoreUndoUpdate = false; |
1715 | dupe.Undoing = false; | 1714 | dupe.Undoing = false; |
1716 | 1715 | ||
@@ -3657,82 +3656,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
3657 | ParentGroup.ScheduleGroupForTerseUpdate(); | 3656 | ParentGroup.ScheduleGroupForTerseUpdate(); |
3658 | //ParentGroup.ScheduleGroupForFullUpdate(); | 3657 | //ParentGroup.ScheduleGroupForFullUpdate(); |
3659 | } | 3658 | } |
3660 | /* | ||
3661 | public void StoreUndoState() | ||
3662 | { | ||
3663 | StoreUndoState(false); | ||
3664 | } | ||
3665 | |||
3666 | public void StoreUndoState(bool forGroup) | ||
3667 | { | ||
3668 | if (!Undoing && !IgnoreUndoUpdate) // just to read better - undo is in progress, or suspended | ||
3669 | { | ||
3670 | if (ParentGroup != null) | ||
3671 | { | ||
3672 | lock (m_undo) | ||
3673 | { | ||
3674 | if (m_undo.Count > 0) | ||
3675 | { | ||
3676 | // see if we had a change | ||
3677 | |||
3678 | UndoState last = m_undo.Peek(); | ||
3679 | if (last != null) | ||
3680 | { | ||
3681 | if (last.Compare(this, forGroup)) | ||
3682 | { | ||
3683 | return; | ||
3684 | } | ||
3685 | } | ||
3686 | } | ||
3687 | |||
3688 | if (ParentGroup.GetSceneMaxUndo() > 0) | ||
3689 | { | ||
3690 | UndoState nUndo = new UndoState(this, forGroup); | ||
3691 | |||
3692 | m_undo.Push(nUndo); | ||
3693 | |||
3694 | if (m_redo.Count > 0) | ||
3695 | m_redo.Clear(); | ||
3696 | } | ||
3697 | } | ||
3698 | } | ||
3699 | } | ||
3700 | } | ||
3701 | */ | ||
3702 | |||
3703 | 3659 | ||
3704 | public void StoreUndoState(ObjectChangeWhat what) | 3660 | public void StoreUndoState(ObjectChangeWhat what) |
3705 | { | 3661 | { |
3706 | if (!Undoing && !IgnoreUndoUpdate) // just to read better - undo is in progress, or suspended | 3662 | lock (m_UndoRedo) |
3707 | { | 3663 | { |
3708 | if (ParentGroup != null) | 3664 | if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended |
3709 | { | 3665 | { |
3710 | lock (m_undo) | 3666 | m_UndoRedo.StoreUndo(this, what); |
3711 | { | ||
3712 | if (m_undo.Count > 0) | ||
3713 | { | ||
3714 | // see if we had a change | ||
3715 | |||
3716 | UndoState last = m_undo.Peek(); | ||
3717 | if (last != null) | ||
3718 | { | ||
3719 | if (last.Compare(this, what)) | ||
3720 | { | ||
3721 | return; | ||
3722 | } | ||
3723 | } | ||
3724 | } | ||
3725 | |||
3726 | if (ParentGroup.GetSceneMaxUndo() > 0) | ||
3727 | { | ||
3728 | UndoState nUndo = new UndoState(this, what); | ||
3729 | |||
3730 | m_undo.Push(nUndo); | ||
3731 | |||
3732 | if (m_redo.Count > 0) | ||
3733 | m_redo.Clear(); | ||
3734 | } | ||
3735 | } | ||
3736 | } | 3667 | } |
3737 | } | 3668 | } |
3738 | } | 3669 | } |
@@ -3744,84 +3675,42 @@ namespace OpenSim.Region.Framework.Scenes | |||
3744 | { | 3675 | { |
3745 | get | 3676 | get |
3746 | { | 3677 | { |
3747 | lock (m_undo) | 3678 | lock (m_UndoRedo) |
3748 | return m_undo.Count; | 3679 | return m_UndoRedo.Count; |
3749 | } | 3680 | } |
3750 | } | 3681 | } |
3751 | 3682 | ||
3752 | public void Undo() | 3683 | public void Undo() |
3753 | { | 3684 | { |
3754 | lock (m_undo) | 3685 | lock (m_UndoRedo) |
3755 | { | 3686 | { |
3756 | // m_log.DebugFormat( | 3687 | if (Undoing || ParentGroup == null) |
3757 | // "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}", | 3688 | return; |
3758 | // Name, LocalId, m_undo.Count); | ||
3759 | |||
3760 | if (m_undo.Count > 0) | ||
3761 | { | ||
3762 | UndoState goback = m_undo.Pop(); | ||
3763 | |||
3764 | if (goback != null) | ||
3765 | { | ||
3766 | UndoState nUndo = null; | ||
3767 | |||
3768 | if (ParentGroup.GetSceneMaxUndo() > 0) | ||
3769 | { | ||
3770 | nUndo = new UndoState(this, goback.data.what); | ||
3771 | } | ||
3772 | |||
3773 | goback.PlayState(this); | ||
3774 | |||
3775 | if (nUndo != null) | ||
3776 | m_redo.Push(nUndo); | ||
3777 | } | ||
3778 | } | ||
3779 | 3689 | ||
3780 | // m_log.DebugFormat( | 3690 | Undoing = true; |
3781 | // "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", | 3691 | m_UndoRedo.Undo(this); |
3782 | // Name, LocalId, m_undo.Count); | 3692 | Undoing = false; |
3783 | } | 3693 | } |
3784 | } | 3694 | } |
3785 | 3695 | ||
3786 | public void Redo() | 3696 | public void Redo() |
3787 | { | 3697 | { |
3788 | lock (m_undo) | 3698 | lock (m_UndoRedo) |
3789 | { | 3699 | { |
3790 | // m_log.DebugFormat( | 3700 | if (Undoing || ParentGroup == null) |
3791 | // "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}", | 3701 | return; |
3792 | // Name, LocalId, m_redo.Count); | ||
3793 | |||
3794 | if (m_redo.Count > 0) | ||
3795 | { | ||
3796 | UndoState gofwd = m_redo.Pop(); | ||
3797 | |||
3798 | if (gofwd != null) | ||
3799 | { | ||
3800 | if (ParentGroup.GetSceneMaxUndo() > 0) | ||
3801 | { | ||
3802 | UndoState nUndo = new UndoState(this, gofwd.data.what); | ||
3803 | |||
3804 | m_undo.Push(nUndo); | ||
3805 | } | ||
3806 | |||
3807 | gofwd.PlayState(this); | ||
3808 | } | ||
3809 | 3702 | ||
3810 | // m_log.DebugFormat( | 3703 | Undoing = true; |
3811 | // "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", | 3704 | m_UndoRedo.Redo(this); |
3812 | // Name, LocalId, m_redo.Count); | 3705 | Undoing = false; |
3813 | } | ||
3814 | } | 3706 | } |
3815 | } | 3707 | } |
3816 | 3708 | ||
3817 | public void ClearUndoState() | 3709 | public void ClearUndoState() |
3818 | { | 3710 | { |
3819 | // m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); | 3711 | lock (m_UndoRedo) |
3820 | |||
3821 | lock (m_undo) | ||
3822 | { | 3712 | { |
3823 | m_undo.Clear(); | 3713 | m_UndoRedo.Clear(); |
3824 | m_redo.Clear(); | ||
3825 | } | 3714 | } |
3826 | } | 3715 | } |
3827 | 3716 | ||
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 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Reflection; | 29 | using System.Reflection; |
30 | using System.Collections.Generic; | ||
30 | using log4net; | 31 | using log4net; |
31 | using OpenMetaverse; | 32 | using OpenMetaverse; |
32 | using OpenSim.Region.Framework.Interfaces; | 33 | using OpenSim.Region.Framework.Interfaces; |
@@ -34,6 +35,8 @@ using System; | |||
34 | 35 | ||
35 | namespace OpenSim.Region.Framework.Scenes | 36 | namespace OpenSim.Region.Framework.Scenes |
36 | { | 37 | { |
38 | |||
39 | /* | ||
37 | [Flags] | 40 | [Flags] |
38 | public enum UndoType | 41 | public enum UndoType |
39 | { | 42 | { |
@@ -48,7 +51,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
48 | STATE_ALL = 63 | 51 | STATE_ALL = 63 |
49 | } | 52 | } |
50 | 53 | ||
51 | /* | 54 | |
52 | public class UndoState | 55 | public class UndoState |
53 | { | 56 | { |
54 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 57 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -194,7 +197,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
194 | */ | 197 | */ |
195 | public class UndoState | 198 | public class UndoState |
196 | { | 199 | { |
200 | const int UNDOEXPIRESECONDS = 300; // undo expire time (nice to have it came from a ini later) | ||
201 | |||
197 | public ObjectChangeData data; | 202 | public ObjectChangeData data; |
203 | public DateTime creationtime; | ||
198 | /// <summary> | 204 | /// <summary> |
199 | /// Constructor. | 205 | /// Constructor. |
200 | /// </summary> | 206 | /// </summary> |
@@ -204,8 +210,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
204 | public UndoState(SceneObjectPart part, ObjectChangeWhat what) | 210 | public UndoState(SceneObjectPart part, ObjectChangeWhat what) |
205 | { | 211 | { |
206 | data = new ObjectChangeData(); | 212 | data = new ObjectChangeData(); |
207 | |||
208 | data.what = what; | 213 | data.what = what; |
214 | creationtime = DateTime.UtcNow; | ||
209 | 215 | ||
210 | if (part.ParentGroup.RootPart == part) | 216 | if (part.ParentGroup.RootPart == part) |
211 | { | 217 | { |
@@ -227,12 +233,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
227 | } | 233 | } |
228 | } | 234 | } |
229 | 235 | ||
236 | public bool checkExpire() | ||
237 | { | ||
238 | TimeSpan t = DateTime.UtcNow - creationtime; | ||
239 | if (t.Seconds > UNDOEXPIRESECONDS) | ||
240 | return true; | ||
241 | return false; | ||
242 | } | ||
243 | |||
244 | public void updateExpire() | ||
245 | { | ||
246 | creationtime = DateTime.UtcNow; | ||
247 | } | ||
248 | |||
230 | /// <summary> | 249 | /// <summary> |
231 | /// Compare the relevant state in the given part to this state. | 250 | /// Compare the relevant state in the given part to this state. |
232 | /// </summary> | 251 | /// </summary> |
233 | /// <param name="part"></param> | 252 | /// <param name="part"></param> |
234 | /// <returns>true if both the part's position, rotation and scale match those in this undo state. False otherwise.</returns> | 253 | /// <returns>true if both the part's position, rotation and scale match those in this undo state. False otherwise.</returns> |
235 | public bool Compare(SceneObjectPart part, ObjectChangeWhat what) | 254 | public bool Compare(SceneObjectPart part, ObjectChangeWhat what) |
236 | { | 255 | { |
237 | if (data.what != what) // if diferent targets, then they are diferent | 256 | if (data.what != what) // if diferent targets, then they are diferent |
238 | return false; | 257 | return false; |
@@ -274,6 +293,157 @@ namespace OpenSim.Region.Framework.Scenes | |||
274 | } | 293 | } |
275 | } | 294 | } |
276 | 295 | ||
296 | public class UndoRedoState | ||
297 | { | ||
298 | int size; | ||
299 | public LinkedList<UndoState> m_redo = new LinkedList<UndoState>(); | ||
300 | public LinkedList<UndoState> m_undo = new LinkedList<UndoState>(); | ||
301 | |||
302 | public UndoRedoState() | ||
303 | { | ||
304 | size = 5; | ||
305 | } | ||
306 | |||
307 | public UndoRedoState(int _size) | ||
308 | { | ||
309 | if (_size < 3) | ||
310 | size = 3; | ||
311 | else | ||
312 | size = _size; | ||
313 | } | ||
314 | |||
315 | public int Count | ||
316 | { | ||
317 | get { return m_undo.Count; } | ||
318 | } | ||
319 | |||
320 | public void Clear() | ||
321 | { | ||
322 | m_undo.Clear(); | ||
323 | m_redo.Clear(); | ||
324 | } | ||
325 | |||
326 | public void StoreUndo(SceneObjectPart part, ObjectChangeWhat what) | ||
327 | { | ||
328 | lock (m_undo) | ||
329 | { | ||
330 | UndoState last; | ||
331 | |||
332 | if (m_redo.Count > 0) // last code seems to clear redo on every new undo | ||
333 | { | ||
334 | m_redo.Clear(); | ||
335 | } | ||
336 | |||
337 | if (m_undo.Count > 0) | ||
338 | { | ||
339 | // check expired entry | ||
340 | last = m_undo.First.Value; | ||
341 | if (last != null && last.checkExpire()) | ||
342 | m_undo.Clear(); | ||
343 | else | ||
344 | { | ||
345 | // see if we actually have a change | ||
346 | if (last != null) | ||
347 | { | ||
348 | if (last.Compare(part, what)) | ||
349 | return; | ||
350 | } | ||
351 | } | ||
352 | } | ||
353 | |||
354 | // limite size | ||
355 | while (m_undo.Count >= size) | ||
356 | m_undo.RemoveLast(); | ||
357 | |||
358 | UndoState nUndo = new UndoState(part, what); | ||
359 | m_undo.AddFirst(nUndo); | ||
360 | } | ||
361 | } | ||
362 | |||
363 | public void Undo(SceneObjectPart part) | ||
364 | { | ||
365 | lock (m_undo) | ||
366 | { | ||
367 | UndoState nUndo; | ||
368 | |||
369 | // expire redo | ||
370 | if (m_redo.Count > 0) | ||
371 | { | ||
372 | nUndo = m_redo.First.Value; | ||
373 | if (nUndo != null && nUndo.checkExpire()) | ||
374 | m_redo.Clear(); | ||
375 | } | ||
376 | |||
377 | if (m_undo.Count > 0) | ||
378 | { | ||
379 | UndoState goback = m_undo.First.Value; | ||
380 | // check expired | ||
381 | if (goback != null && goback.checkExpire()) | ||
382 | { | ||
383 | m_undo.Clear(); | ||
384 | return; | ||
385 | } | ||
386 | |||
387 | if (goback != null) | ||
388 | { | ||
389 | m_undo.RemoveFirst(); | ||
390 | |||
391 | // redo limite size | ||
392 | while (m_redo.Count >= size) | ||
393 | m_redo.RemoveLast(); | ||
394 | |||
395 | nUndo = new UndoState(part, goback.data.what); // new value in part should it be full goback copy? | ||
396 | m_redo.AddFirst(nUndo); | ||
397 | |||
398 | goback.PlayState(part); | ||
399 | } | ||
400 | } | ||
401 | } | ||
402 | } | ||
403 | |||
404 | public void Redo(SceneObjectPart part) | ||
405 | { | ||
406 | lock (m_undo) | ||
407 | { | ||
408 | UndoState nUndo; | ||
409 | |||
410 | // expire undo | ||
411 | if (m_undo.Count > 0) | ||
412 | { | ||
413 | nUndo = m_undo.First.Value; | ||
414 | if (nUndo != null && nUndo.checkExpire()) | ||
415 | m_undo.Clear(); | ||
416 | } | ||
417 | |||
418 | if (m_redo.Count > 0) | ||
419 | { | ||
420 | UndoState gofwd = m_redo.First.Value; | ||
421 | // check expired | ||
422 | if (gofwd != null && gofwd.checkExpire()) | ||
423 | { | ||
424 | m_redo.Clear(); | ||
425 | return; | ||
426 | } | ||
427 | |||
428 | if (gofwd != null) | ||
429 | { | ||
430 | m_redo.RemoveFirst(); | ||
431 | |||
432 | // limite undo size | ||
433 | while (m_undo.Count >= size) | ||
434 | m_undo.RemoveLast(); | ||
435 | |||
436 | nUndo = new UndoState(part, gofwd.data.what); // new value in part should it be full gofwd copy? | ||
437 | m_undo.AddFirst(nUndo); | ||
438 | |||
439 | gofwd.PlayState(part); | ||
440 | } | ||
441 | } | ||
442 | } | ||
443 | } | ||
444 | |||
445 | |||
446 | } | ||
277 | 447 | ||
278 | public class LandUndoState | 448 | public class LandUndoState |
279 | { | 449 | { |