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.

279 lines
5.6KB

  1. #include <history.hpp>
  2. #include <context.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. assert(mw);
  35. model = mw->getModel();
  36. assert(mw->getModule());
  37. moduleId = mw->getModule()->id;
  38. pos = mw->box.pos;
  39. // ModuleAdd doesn't *really* need the state to be serialized, although ModuleRemove certainly does.
  40. // However, creating a module may give it a nondeterministic initial state for whatever reason, so serialize anyway.
  41. moduleJ = APP->engine->moduleToJson(mw->getModule());
  42. }
  43. void ModuleAdd::undo() {
  44. app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId);
  45. if (!mw)
  46. return;
  47. APP->scene->rack->removeModule(mw);
  48. delete mw;
  49. }
  50. void ModuleAdd::redo() {
  51. engine::Module* module = model->createModule();
  52. module->id = moduleId;
  53. try {
  54. module->fromJson(moduleJ);
  55. }
  56. catch (Exception& e) {
  57. WARN("%s", e.what());
  58. }
  59. APP->engine->addModule(module);
  60. app::ModuleWidget* mw = model->createModuleWidget(module);
  61. mw->box.pos = pos;
  62. APP->scene->rack->addModule(mw);
  63. }
  64. void ModuleMove::undo() {
  65. app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId);
  66. if (!mw)
  67. return;
  68. APP->scene->rack->requestModulePos(mw, oldPos);
  69. }
  70. void ModuleMove::redo() {
  71. app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId);
  72. if (!mw)
  73. return;
  74. APP->scene->rack->requestModulePos(mw, newPos);
  75. }
  76. void ModuleBypass::undo() {
  77. engine::Module* module = APP->engine->getModule(moduleId);
  78. if (!module)
  79. return;
  80. APP->engine->bypassModule(module, !bypassed);
  81. }
  82. void ModuleBypass::redo() {
  83. engine::Module* module = APP->engine->getModule(moduleId);
  84. if (!module)
  85. return;
  86. APP->engine->bypassModule(module, bypassed);
  87. }
  88. ModuleChange::~ModuleChange() {
  89. json_decref(oldModuleJ);
  90. json_decref(newModuleJ);
  91. }
  92. void ModuleChange::undo() {
  93. engine::Module* module = APP->engine->getModule(moduleId);
  94. if (!module)
  95. return;
  96. APP->engine->moduleFromJson(module, oldModuleJ);
  97. }
  98. void ModuleChange::redo() {
  99. engine::Module* module = APP->engine->getModule(moduleId);
  100. if (!module)
  101. return;
  102. APP->engine->moduleFromJson(module, newModuleJ);
  103. }
  104. void ParamChange::undo() {
  105. engine::Module* module = APP->engine->getModule(moduleId);
  106. if (!module)
  107. return;
  108. APP->engine->setParamValue(module, paramId, oldValue);
  109. }
  110. void ParamChange::redo() {
  111. engine::Module* module = APP->engine->getModule(moduleId);
  112. if (!module)
  113. return;
  114. APP->engine->setParamValue(module, paramId, newValue);
  115. }
  116. void CableAdd::setCable(app::CableWidget* cw) {
  117. assert(cw);
  118. assert(cw->cable);
  119. assert(cw->cable->id >= 0);
  120. cableId = cw->cable->id;
  121. assert(cw->cable->outputModule);
  122. outputModuleId = cw->cable->outputModule->id;
  123. outputId = cw->cable->outputId;
  124. assert(cw->cable->inputModule);
  125. inputModuleId = cw->cable->inputModule->id;
  126. inputId = cw->cable->inputId;
  127. color = cw->color;
  128. }
  129. void CableAdd::undo() {
  130. app::CableWidget* cw = APP->scene->rack->getCable(cableId);
  131. if (!cw)
  132. return;
  133. APP->scene->rack->removeCable(cw);
  134. delete cw;
  135. }
  136. void CableAdd::redo() {
  137. engine::Cable* cable = new engine::Cable;
  138. cable->id = cableId;
  139. cable->inputModule = APP->engine->getModule(inputModuleId);
  140. if (!cable->inputModule) {
  141. delete cable;
  142. return;
  143. }
  144. cable->inputId = inputId;
  145. cable->outputModule = APP->engine->getModule(outputModuleId);
  146. if (!cable->outputModule) {
  147. delete cable;
  148. return;
  149. }
  150. cable->outputId = outputId;
  151. APP->engine->addCable(cable);
  152. app::CableWidget* cw = new app::CableWidget;
  153. cw->setCable(cable);
  154. cw->color = color;
  155. APP->scene->rack->addCable(cw);
  156. }
  157. State::State() {
  158. clear();
  159. }
  160. State::~State() {
  161. clear();
  162. }
  163. void State::clear() {
  164. for (Action* action : actions) {
  165. delete action;
  166. }
  167. actions.clear();
  168. actionIndex = 0;
  169. savedIndex = -1;
  170. }
  171. void State::push(Action* action) {
  172. // Delete all future actions (if we have undone some actions)
  173. for (int i = actionIndex; i < (int) actions.size(); i++) {
  174. delete actions[i];
  175. }
  176. actions.resize(actionIndex);
  177. // Delete actions from beginning if limit is reached
  178. static const int limit = 500;
  179. int n = (int) actions.size() - limit + 1;
  180. if (n > 0) {
  181. for (int i = 0; i < n; i++) {
  182. delete actions[i];
  183. }
  184. actions.erase(actions.begin(), actions.begin() + n);
  185. actionIndex -= n;
  186. savedIndex -= n;
  187. }
  188. // Push action
  189. actions.push_back(action);
  190. actionIndex++;
  191. // Unset the savedIndex if we just permanently overwrote the saved state
  192. if (actionIndex == savedIndex) {
  193. savedIndex = -1;
  194. }
  195. }
  196. void State::undo() {
  197. if (canUndo()) {
  198. actionIndex--;
  199. actions[actionIndex]->undo();
  200. }
  201. }
  202. void State::redo() {
  203. if (canRedo()) {
  204. actions[actionIndex]->redo();
  205. actionIndex++;
  206. }
  207. }
  208. bool State::canUndo() {
  209. return actionIndex > 0;
  210. }
  211. bool State::canRedo() {
  212. return actionIndex < (int) actions.size();
  213. }
  214. std::string State::getUndoName() {
  215. if (!canUndo())
  216. return "";
  217. return actions[actionIndex - 1]->name;
  218. }
  219. std::string State::getRedoName() {
  220. if (!canRedo())
  221. return "";
  222. return actions[actionIndex]->name;
  223. }
  224. void State::setSaved() {
  225. savedIndex = actionIndex;
  226. }
  227. bool State::isSaved() {
  228. return actionIndex == savedIndex;
  229. }
  230. } // namespace history
  231. } // namespace rack