aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/UndoState.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/UndoState.cs283
1 files changed, 282 insertions, 1 deletions
diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs
index 38474de..668b53b 100644
--- a/OpenSim/Region/Framework/Scenes/UndoState.cs
+++ b/OpenSim/Region/Framework/Scenes/UndoState.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections.Generic;
30using log4net; 31using log4net;
31using OpenMetaverse; 32using OpenMetaverse;
32using OpenSim.Region.Framework.Interfaces; 33using OpenSim.Region.Framework.Interfaces;
@@ -34,6 +35,8 @@ using System;
34 35
35namespace OpenSim.Region.Framework.Scenes 36namespace OpenSim.Region.Framework.Scenes
36{ 37{
38
39/*
37 [Flags] 40 [Flags]
38 public enum UndoType 41 public enum UndoType
39 { 42 {
@@ -48,6 +51,7 @@ namespace OpenSim.Region.Framework.Scenes
48 STATE_ALL = 63 51 STATE_ALL = 63
49 } 52 }
50 53
54
51 public class UndoState 55 public class UndoState
52 { 56 {
53 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 57 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -121,9 +125,16 @@ namespace OpenSim.Region.Framework.Scenes
121 public void PlayState(SceneObjectPart part) 125 public void PlayState(SceneObjectPart part)
122 { 126 {
123 part.Undoing = true; 127 part.Undoing = true;
124 128 bool physbuilding = false;
129
125 if (part.ParentID == 0) 130 if (part.ParentID == 0)
126 { 131 {
132 if (!ForGroup && part.PhysActor != null)
133 {
134 part.PhysActor.Building = true;
135 physbuilding = true;
136 }
137
127 if (Position != Vector3.Zero) 138 if (Position != Vector3.Zero)
128 { 139 {
129 if (ForGroup) 140 if (ForGroup)
@@ -139,17 +150,34 @@ namespace OpenSim.Region.Framework.Scenes
139 150
140 if (Scale != Vector3.Zero) 151 if (Scale != Vector3.Zero)
141 { 152 {
153 if (!physbuilding && part.PhysActor != null)
154 {
155 part.PhysActor.Building = true;
156 physbuilding = true;
157 }
158
142 if (ForGroup) 159 if (ForGroup)
143 part.ParentGroup.GroupResize(Scale); 160 part.ParentGroup.GroupResize(Scale);
144 else 161 else
145 part.Resize(Scale); 162 part.Resize(Scale);
146 } 163 }
164
165 if (physbuilding)
166 part.PhysActor.Building = false;
167
147 part.ParentGroup.ScheduleGroupForTerseUpdate(); 168 part.ParentGroup.ScheduleGroupForTerseUpdate();
148 } 169 }
149 else 170 else
150 { 171 {
151 if (ForGroup) // trap for group since seems parts can't do it 172 if (ForGroup) // trap for group since seems parts can't do it
152 return; 173 return;
174
175 // changing a part invalidates entire object physical rep
176 if (part.ParentGroup != null && part.ParentGroup.RootPart != null && part.ParentGroup.RootPart.PhysActor != null)
177 {
178 part.ParentGroup.RootPart.PhysActor.Building = true;
179 physbuilding = true;
180 }
153 181
154 // Note: Updating these properties on sop automatically schedules an update if needed 182 // Note: Updating these properties on sop automatically schedules an update if needed
155 part.OffsetPosition = Position; 183 part.OffsetPosition = Position;
@@ -158,11 +186,264 @@ namespace OpenSim.Region.Framework.Scenes
158 { 186 {
159 part.Resize(Scale); 187 part.Resize(Scale);
160 } 188 }
189
190 if (physbuilding)
191 part.ParentGroup.RootPart.PhysActor.Building = false;
161 } 192 }
162 193
163 part.Undoing = false; 194 part.Undoing = false;
164 } 195 }
165 } 196 }
197*/
198 public class UndoState
199 {
200 const int UNDOEXPIRESECONDS = 300; // undo expire time (nice to have it came from a ini later)
201
202 public ObjectChangeData data;
203 public DateTime creationtime;
204 /// <summary>
205 /// Constructor.
206 /// </summary>
207 /// <param name="part"></param>
208 /// <param name="forGroup">True if the undo is for an entire group</param>
209 /// only for root parts ????
210 public UndoState(SceneObjectPart part, ObjectChangeWhat what)
211 {
212 data = new ObjectChangeData();
213 data.what = what;
214 creationtime = DateTime.UtcNow;
215
216 if (part.ParentGroup.RootPart == part)
217 {
218 if ((what & ObjectChangeWhat.Position) != 0)
219 data.position = part.ParentGroup.AbsolutePosition;
220 if ((what & ObjectChangeWhat.Rotation) != 0)
221 data.rotation = part.RotationOffset;
222 if ((what & ObjectChangeWhat.Scale) != 0)
223 data.scale = part.Shape.Scale;
224 }
225 else
226 {
227 if ((what & ObjectChangeWhat.Position) != 0)
228 data.position = part.OffsetPosition;
229 if ((what & ObjectChangeWhat.Rotation) != 0)
230 data.rotation = part.RotationOffset;
231 if ((what & ObjectChangeWhat.Scale) != 0)
232 data.scale = part.Shape.Scale;
233 }
234 }
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
249 /// <summary>
250 /// Compare the relevant state in the given part to this state.
251 /// </summary>
252 /// <param name="part"></param>
253 /// <returns>true if both the part's position, rotation and scale match those in this undo state. False otherwise.</returns>
254 public bool Compare(SceneObjectPart part, ObjectChangeWhat what)
255 {
256 if (data.what != what) // if diferent targets, then they are diferent
257 return false;
258
259 if (part != null)
260 {
261 if (part.ParentID == 0)
262 {
263 if ((what & ObjectChangeWhat.Position) != 0 && data.position != part.ParentGroup.AbsolutePosition)
264 return false;
265 }
266 else
267 {
268 if ((what & ObjectChangeWhat.Position) != 0 && data.position != part.OffsetPosition)
269 return false;
270 }
271
272 if ((what & ObjectChangeWhat.Rotation) != 0 && data.rotation != part.RotationOffset)
273 return false;
274 if ((what & ObjectChangeWhat.Rotation) != 0 && data.scale == part.Shape.Scale)
275 return false;
276 return true;
277
278 }
279 return false;
280 }
281
282 public void PlayState(SceneObjectPart part)
283 {
284 part.Undoing = true;
285
286 SceneObjectGroup grp = part.ParentGroup;
287
288 if (grp != null)
289 {
290 grp.doChangeObject(part, data);
291 }
292 part.Undoing = false;
293 }
294 }
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 }
166 447
167 public class LandUndoState 448 public class LandUndoState
168 { 449 {