You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

245 lines
4.9KB

  1. #include <history.hpp>
  2. #include <app.hpp>
  3. #include <app/Scene.hpp>
  4. #include <engine/Cable.hpp>
  5. #include <engine/Engine.hpp>
  6. namespace rack {
  7. namespace history {
  8. ComplexAction::~ComplexAction() {
  9. for (Action* action : actions) {
  10. delete action;
  11. }
  12. }
  13. void ComplexAction::undo() {
  14. for (auto it = actions.rbegin(); it != actions.rend(); it++) {
  15. Action* action = *it;
  16. action->undo();
  17. }
  18. }
  19. void ComplexAction::redo() {
  20. for (Action* action : actions) {
  21. action->redo();
  22. }
  23. }
  24. void ComplexAction::push(Action* action) {
  25. actions.push_back(action);
  26. }
  27. bool ComplexAction::isEmpty() {
  28. return actions.empty();
  29. }
  30. ModuleAdd::~ModuleAdd() {
  31. json_decref(moduleJ);
  32. }
  33. void ModuleAdd::setModule(app::ModuleWidget* mw) {
  34. model = mw->model;
  35. assert(mw->module);
  36. moduleId = mw->module->id;
  37. pos = mw->box.pos;
  38. // ModuleAdd doesn't *really* need the state to be serialized, although ModuleRemove certainly does.
  39. // However, creating a module may give it a nondeterministic initial state for whatever reason, so serialize anyway.
  40. moduleJ = mw->toJson();
  41. }
  42. void ModuleAdd::undo() {
  43. app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId);
  44. assert(mw);
  45. APP->scene->rack->removeModule(mw);
  46. delete mw;
  47. }
  48. void ModuleAdd::redo() {
  49. app::ModuleWidget* mw = model->createModuleWidget();
  50. assert(mw);
  51. assert(mw->module);
  52. mw->module->id = moduleId;
  53. mw->box.pos = pos;
  54. mw->fromJson(moduleJ);
  55. APP->scene->rack->addModule(mw);
  56. }
  57. void ModuleMove::undo() {
  58. app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId);
  59. assert(mw);
  60. mw->box.pos = oldPos;
  61. }
  62. void ModuleMove::redo() {
  63. app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId);
  64. assert(mw);
  65. mw->box.pos = newPos;
  66. }
  67. void ModuleBypass::undo() {
  68. app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId);
  69. assert(mw);
  70. APP->engine->bypassModule(mw->module, !bypass);
  71. }
  72. void ModuleBypass::redo() {
  73. app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId);
  74. assert(mw);
  75. APP->engine->bypassModule(mw->module, bypass);
  76. }
  77. ModuleChange::~ModuleChange() {
  78. json_decref(oldModuleJ);
  79. json_decref(newModuleJ);
  80. }
  81. void ModuleChange::undo() {
  82. app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId);
  83. assert(mw);
  84. mw->fromJson(oldModuleJ);
  85. }
  86. void ModuleChange::redo() {
  87. app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId);
  88. assert(mw);
  89. mw->fromJson(newModuleJ);
  90. }
  91. void ParamChange::undo() {
  92. app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId);
  93. assert(mw);
  94. mw->module->params[paramId].value = oldValue;
  95. }
  96. void ParamChange::redo() {
  97. app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId);
  98. assert(mw);
  99. mw->module->params[paramId].value = newValue;
  100. }
  101. void CableAdd::setCable(app::CableWidget* cw) {
  102. assert(cw->cable);
  103. assert(cw->cable->id >= 0);
  104. cableId = cw->cable->id;
  105. assert(cw->cable->outputModule);
  106. outputModuleId = cw->cable->outputModule->id;
  107. outputId = cw->cable->outputId;
  108. assert(cw->cable->inputModule);
  109. inputModuleId = cw->cable->inputModule->id;
  110. inputId = cw->cable->inputId;
  111. color = cw->color;
  112. }
  113. void CableAdd::undo() {
  114. app::CableWidget* cw = APP->scene->rack->getCable(cableId);
  115. APP->scene->rack->removeCable(cw);
  116. delete cw;
  117. }
  118. void CableAdd::redo() {
  119. app::CableWidget* cw = new app::CableWidget;
  120. cw->cable->id = cableId;
  121. app::ModuleWidget* outputModule = APP->scene->rack->getModule(outputModuleId);
  122. assert(outputModule);
  123. app::PortWidget* outputPort = outputModule->getOutput(outputId);
  124. assert(outputPort);
  125. cw->setOutput(outputPort);
  126. app::ModuleWidget* inputModule = APP->scene->rack->getModule(inputModuleId);
  127. assert(inputModule);
  128. app::PortWidget* inputPort = inputModule->getInput(inputId);
  129. assert(inputPort);
  130. cw->setInput(inputPort);
  131. cw->color = color;
  132. APP->scene->rack->addCable(cw);
  133. }
  134. State::State() {
  135. clear();
  136. }
  137. State::~State() {
  138. clear();
  139. }
  140. void State::clear() {
  141. for (Action* action : actions) {
  142. delete action;
  143. }
  144. actions.clear();
  145. actionIndex = 0;
  146. savedIndex = -1;
  147. }
  148. void State::push(Action* action) {
  149. for (int i = actionIndex; i < (int) actions.size(); i++) {
  150. delete actions[i];
  151. }
  152. actions.resize(actionIndex);
  153. actions.push_back(action);
  154. actionIndex++;
  155. // Unset the savedIndex if we just permanently overwrote the saved state
  156. if (actionIndex == savedIndex) {
  157. savedIndex = -1;
  158. }
  159. }
  160. void State::undo() {
  161. if (canUndo()) {
  162. actionIndex--;
  163. actions[actionIndex]->undo();
  164. }
  165. }
  166. void State::redo() {
  167. if (canRedo()) {
  168. actions[actionIndex]->redo();
  169. actionIndex++;
  170. }
  171. }
  172. bool State::canUndo() {
  173. return actionIndex > 0;
  174. }
  175. bool State::canRedo() {
  176. return actionIndex < (int) actions.size();
  177. }
  178. std::string State::getUndoName() {
  179. if (!canUndo())
  180. return "";
  181. return actions[actionIndex - 1]->name;
  182. }
  183. std::string State::getRedoName() {
  184. if (!canRedo())
  185. return "";
  186. return actions[actionIndex]->name;
  187. }
  188. void State::setSaved() {
  189. savedIndex = actionIndex;
  190. }
  191. bool State::isSaved() {
  192. return actionIndex == savedIndex;
  193. }
  194. } // namespace history
  195. } // namespace rack