PageRenderTime 37ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llui/llundo.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 174 lines | 94 code | 29 blank | 51 comment | 15 complexity | d2647941bd8bd979b3ccc22f8b5d2580 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llundo.cpp
  3. *
  4. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  5. * Second Life Viewer Source Code
  6. * Copyright (C) 2010, Linden Research, Inc.
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation;
  11. * version 2.1 of the License only.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  23. * $/LicenseInfo$
  24. */
  25. #include "linden_common.h"
  26. #include "llundo.h"
  27. // TODO:
  28. // implement doubly linked circular list for ring buffer
  29. // this will allow us to easily change the size of an undo buffer on the fly
  30. //-----------------------------------------------------------------------------
  31. // LLUndoBuffer()
  32. //-----------------------------------------------------------------------------
  33. LLUndoBuffer::LLUndoBuffer( LLUndoAction (*create_func()), S32 initial_count )
  34. {
  35. mNextAction = 0;
  36. mLastAction = 0;
  37. mFirstAction = 0;
  38. mOperationID = 0;
  39. mNumActions = initial_count;
  40. mActions = new LLUndoAction *[initial_count];
  41. //initialize buffer with actions
  42. for (S32 i = 0; i < initial_count; i++)
  43. {
  44. mActions[i] = create_func();
  45. if (!mActions[i])
  46. {
  47. llerrs << "Unable to create action for undo buffer" << llendl;
  48. }
  49. }
  50. }
  51. //-----------------------------------------------------------------------------
  52. // ~LLUndoBuffer()
  53. //-----------------------------------------------------------------------------
  54. LLUndoBuffer::~LLUndoBuffer()
  55. {
  56. for (S32 i = 0; i < mNumActions; i++)
  57. {
  58. delete mActions[i];
  59. }
  60. delete [] mActions;
  61. }
  62. //-----------------------------------------------------------------------------
  63. // getNextAction()
  64. //-----------------------------------------------------------------------------
  65. LLUndoBuffer::LLUndoAction* LLUndoBuffer::getNextAction(BOOL setClusterBegin)
  66. {
  67. LLUndoAction *nextAction = mActions[mNextAction];
  68. if (setClusterBegin)
  69. {
  70. mOperationID++;
  71. }
  72. mActions[mNextAction]->mClusterID = mOperationID;
  73. mNextAction = (mNextAction + 1) % mNumActions;
  74. mLastAction = mNextAction;
  75. if (mNextAction == mFirstAction)
  76. {
  77. mActions[mFirstAction]->cleanup();
  78. mFirstAction = (mFirstAction + 1) % mNumActions;
  79. }
  80. return nextAction;
  81. }
  82. //-----------------------------------------------------------------------------
  83. // undoAction()
  84. //-----------------------------------------------------------------------------
  85. BOOL LLUndoBuffer::undoAction()
  86. {
  87. if (!canUndo())
  88. {
  89. return FALSE;
  90. }
  91. S32 prevAction = (mNextAction + mNumActions - 1) % mNumActions;
  92. while(mActions[prevAction]->mClusterID == mOperationID)
  93. {
  94. // go ahead and decrement action index
  95. mNextAction = prevAction;
  96. // undo this action
  97. mActions[mNextAction]->undo();
  98. // we're at the first action, so we don't know if we've actually undid everything
  99. if (mNextAction == mFirstAction)
  100. {
  101. mOperationID--;
  102. return FALSE;
  103. }
  104. // do wrap-around of index, but avoid negative numbers for modulo operator
  105. prevAction = (mNextAction + mNumActions - 1) % mNumActions;
  106. }
  107. mOperationID--;
  108. return TRUE;
  109. }
  110. //-----------------------------------------------------------------------------
  111. // redoAction()
  112. //-----------------------------------------------------------------------------
  113. BOOL LLUndoBuffer::redoAction()
  114. {
  115. if (!canRedo())
  116. {
  117. return FALSE;
  118. }
  119. mOperationID++;
  120. while(mActions[mNextAction]->mClusterID == mOperationID)
  121. {
  122. if (mNextAction == mLastAction)
  123. {
  124. return FALSE;
  125. }
  126. mActions[mNextAction]->redo();
  127. // do wrap-around of index
  128. mNextAction = (mNextAction + 1) % mNumActions;
  129. }
  130. return TRUE;
  131. }
  132. //-----------------------------------------------------------------------------
  133. // flushActions()
  134. //-----------------------------------------------------------------------------
  135. void LLUndoBuffer::flushActions()
  136. {
  137. for (S32 i = 0; i < mNumActions; i++)
  138. {
  139. mActions[i]->cleanup();
  140. }
  141. mNextAction = 0;
  142. mLastAction = 0;
  143. mFirstAction = 0;
  144. mOperationID = 0;
  145. }