llundo.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:5k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llundo.cpp
  3.  *
  4.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  5.  * 
  6.  * Copyright (c) 2001-2010, Linden Research, Inc.
  7.  * 
  8.  * Second Life Viewer Source Code
  9.  * The source code in this file ("Source Code") is provided by Linden Lab
  10.  * to you under the terms of the GNU General Public License, version 2.0
  11.  * ("GPL"), unless you have obtained a separate licensing agreement
  12.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  13.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  14.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  15.  * 
  16.  * There are special exceptions to the terms and conditions of the GPL as
  17.  * it is applied to this Source Code. View the full text of the exception
  18.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  19.  * online at
  20.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  21.  * 
  22.  * By copying, modifying or distributing this software, you acknowledge
  23.  * that you have read and understood your obligations described above,
  24.  * and agree to abide by those obligations.
  25.  * 
  26.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  27.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  28.  * COMPLETENESS OR PERFORMANCE.
  29.  * $/LicenseInfo$
  30.  */
  31. #include "linden_common.h"
  32. #include "llundo.h"
  33. // TODO:
  34. // implement doubly linked circular list for ring buffer
  35. // this will allow us to easily change the size of an undo buffer on the fly
  36. //-----------------------------------------------------------------------------
  37. // LLUndoBuffer()
  38. //-----------------------------------------------------------------------------
  39. LLUndoBuffer::LLUndoBuffer( LLUndoAction (*create_func()), S32 initial_count )
  40. {
  41. mNextAction = 0;
  42. mLastAction = 0;
  43. mFirstAction = 0;
  44. mOperationID = 0;
  45. mNumActions = initial_count;
  46. mActions = new LLUndoAction *[initial_count];
  47. //initialize buffer with actions
  48. for (S32 i = 0; i < initial_count; i++)
  49. {
  50. mActions[i] = create_func();
  51. if (!mActions[i])
  52. {
  53. llerrs << "Unable to create action for undo buffer" << llendl;
  54. }
  55. }
  56. }
  57. //-----------------------------------------------------------------------------
  58. // ~LLUndoBuffer()
  59. //-----------------------------------------------------------------------------
  60. LLUndoBuffer::~LLUndoBuffer()
  61. {
  62. for (S32 i = 0; i < mNumActions; i++)
  63. {
  64. delete mActions[i];
  65. }
  66. delete [] mActions;
  67. }
  68. //-----------------------------------------------------------------------------
  69. // getNextAction()
  70. //-----------------------------------------------------------------------------
  71. LLUndoBuffer::LLUndoAction* LLUndoBuffer::getNextAction(BOOL setClusterBegin)
  72. {
  73. LLUndoAction *nextAction = mActions[mNextAction];
  74. if (setClusterBegin)
  75. {
  76. mOperationID++;
  77. }
  78. mActions[mNextAction]->mClusterID = mOperationID;
  79. mNextAction = (mNextAction + 1) % mNumActions;
  80. mLastAction = mNextAction;
  81. if (mNextAction == mFirstAction)
  82. {
  83. mActions[mFirstAction]->cleanup();
  84. mFirstAction = (mFirstAction + 1) % mNumActions;
  85. }
  86. return nextAction;
  87. }
  88. //-----------------------------------------------------------------------------
  89. // undoAction()
  90. //-----------------------------------------------------------------------------
  91. BOOL LLUndoBuffer::undoAction()
  92. {
  93. if (!canUndo())
  94. {
  95. return FALSE;
  96. }
  97. S32 prevAction = (mNextAction + mNumActions - 1) % mNumActions;
  98. while(mActions[prevAction]->mClusterID == mOperationID)
  99. {
  100. // go ahead and decrement action index
  101. mNextAction = prevAction;
  102. // undo this action
  103. mActions[mNextAction]->undo();
  104. // we're at the first action, so we don't know if we've actually undid everything
  105. if (mNextAction == mFirstAction)
  106. {
  107. mOperationID--;
  108. return FALSE;
  109. }
  110. // do wrap-around of index, but avoid negative numbers for modulo operator
  111. prevAction = (mNextAction + mNumActions - 1) % mNumActions;
  112. }
  113. mOperationID--;
  114. return TRUE;
  115. }
  116. //-----------------------------------------------------------------------------
  117. // redoAction()
  118. //-----------------------------------------------------------------------------
  119. BOOL LLUndoBuffer::redoAction()
  120. {
  121. if (!canRedo())
  122. {
  123. return FALSE;
  124. }
  125. mOperationID++;
  126. while(mActions[mNextAction]->mClusterID == mOperationID)
  127. {
  128. if (mNextAction == mLastAction)
  129. {
  130. return FALSE;
  131. }
  132. mActions[mNextAction]->redo();
  133. // do wrap-around of index
  134. mNextAction = (mNextAction + 1) % mNumActions;
  135. }
  136. return TRUE;
  137. }
  138. //-----------------------------------------------------------------------------
  139. // flushActions()
  140. //-----------------------------------------------------------------------------
  141. void LLUndoBuffer::flushActions()
  142. {
  143. for (S32 i = 0; i < mNumActions; i++)
  144. {
  145. mActions[i]->cleanup();
  146. }
  147. mNextAction = 0;
  148. mLastAction = 0;
  149. mFirstAction = 0;
  150. mOperationID = 0;
  151. }