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.

212 lines
4.4KB

  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. ModuleAdd::~ModuleAdd() {
  28. json_decref(moduleJ);
  29. }
  30. void ModuleAdd::setModule(app::ModuleWidget *mw) {
  31. model = mw->model;
  32. assert(mw->module);
  33. moduleId = mw->module->id;
  34. pos = mw->box.pos;
  35. // ModuleAdd doesn't *really* need the state to be serialized, although ModuleRemove certainly does.
  36. // However, creating a module may give it a nondeterministic initial state for whatever reason, so serialize anyway.
  37. moduleJ = mw->toJson();
  38. }
  39. void ModuleAdd::undo() {
  40. app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId);
  41. assert(mw);
  42. APP->scene->rackWidget->removeModule(mw);
  43. delete mw;
  44. }
  45. void ModuleAdd::redo() {
  46. app::ModuleWidget *mw = model->createModuleWidget();
  47. assert(mw);
  48. assert(mw->module);
  49. mw->module->id = moduleId;
  50. mw->box.pos = pos;
  51. mw->fromJson(moduleJ);
  52. APP->scene->rackWidget->addModule(mw);
  53. }
  54. void ModuleMove::undo() {
  55. app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId);
  56. assert(mw);
  57. mw->box.pos = oldPos;
  58. }
  59. void ModuleMove::redo() {
  60. app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId);
  61. assert(mw);
  62. mw->box.pos = newPos;
  63. }
  64. void ModuleBypass::undo() {
  65. app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId);
  66. assert(mw);
  67. APP->engine->bypassModule(mw->module, !bypass);
  68. }
  69. void ModuleBypass::redo() {
  70. app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId);
  71. assert(mw);
  72. APP->engine->bypassModule(mw->module, bypass);
  73. }
  74. ModuleChange::~ModuleChange() {
  75. json_decref(oldModuleJ);
  76. json_decref(newModuleJ);
  77. }
  78. void ModuleChange::undo() {
  79. app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId);
  80. assert(mw);
  81. mw->fromJson(oldModuleJ);
  82. }
  83. void ModuleChange::redo() {
  84. app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId);
  85. assert(mw);
  86. mw->fromJson(newModuleJ);
  87. }
  88. void ParamChange::undo() {
  89. app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId);
  90. assert(mw);
  91. mw->module->params[paramId].value = oldValue;
  92. }
  93. void ParamChange::redo() {
  94. app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId);
  95. assert(mw);
  96. mw->module->params[paramId].value = newValue;
  97. }
  98. void CableAdd::setCable(app::CableWidget *cw) {
  99. assert(cw->cable);
  100. assert(cw->cable->id > 0);
  101. cableId = cw->cable->id;
  102. assert(cw->cable->outputModule);
  103. outputModuleId = cw->cable->outputModule->id;
  104. outputId = cw->cable->outputId;
  105. assert(cw->cable->inputModule);
  106. inputModuleId = cw->cable->inputModule->id;
  107. inputId = cw->cable->inputId;
  108. color = cw->color;
  109. }
  110. void CableAdd::undo() {
  111. app::CableWidget *cw = APP->scene->rackWidget->getCable(cableId);
  112. APP->scene->rackWidget->removeCable(cw);
  113. delete cw;
  114. }
  115. void CableAdd::redo() {
  116. app::CableWidget *cw = new app::CableWidget;
  117. cw->cable->id = cableId;
  118. app::ModuleWidget *outputModule = APP->scene->rackWidget->getModule(outputModuleId);
  119. assert(outputModule);
  120. app::PortWidget *outputPort = outputModule->getOutput(outputId);
  121. assert(outputPort);
  122. cw->setOutput(outputPort);
  123. app::ModuleWidget *inputModule = APP->scene->rackWidget->getModule(inputModuleId);
  124. assert(inputModule);
  125. app::PortWidget *inputPort = inputModule->getInput(inputId);
  126. assert(inputPort);
  127. cw->setInput(inputPort);
  128. cw->color = color;
  129. APP->scene->rackWidget->addCable(cw);
  130. }
  131. State::~State() {
  132. clear();
  133. }
  134. void State::clear() {
  135. for (Action *action : actions) {
  136. delete action;
  137. }
  138. actions.clear();
  139. actionIndex = 0;
  140. }
  141. void State::push(Action *action) {
  142. for (int i = actionIndex; i < (int) actions.size(); i++) {
  143. delete actions[i];
  144. }
  145. actions.resize(actionIndex);
  146. actions.push_back(action);
  147. actionIndex++;
  148. }
  149. void State::undo() {
  150. if (canUndo()) {
  151. actionIndex--;
  152. actions[actionIndex]->undo();
  153. }
  154. }
  155. void State::redo() {
  156. if (canRedo()) {
  157. actions[actionIndex]->redo();
  158. actionIndex++;
  159. }
  160. }
  161. bool State::canUndo() {
  162. return actionIndex > 0;
  163. }
  164. bool State::canRedo() {
  165. return actionIndex < (int) actions.size();
  166. }
  167. } // namespace history
  168. } // namespace rack