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.

305 lines
6.1KB

  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. INFO("Creating module %s", model->getFullName().c_str());
  52. engine::Module* module = model->createModule();
  53. module->id = moduleId;
  54. try {
  55. module->fromJson(moduleJ);
  56. }
  57. catch (Exception& e) {
  58. WARN("%s", e.what());
  59. }
  60. APP->engine->addModule(module);
  61. INFO("Creating module widget %s", model->getFullName().c_str());
  62. app::ModuleWidget* mw = model->createModuleWidget(module);
  63. mw->box.pos = pos;
  64. APP->scene->rack->addModule(mw);
  65. }
  66. void ModuleMove::undo() {
  67. app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId);
  68. if (!mw)
  69. return;
  70. mw->box.pos = oldPos;
  71. APP->scene->rack->updateExpanders();
  72. }
  73. void ModuleMove::redo() {
  74. app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId);
  75. if (!mw)
  76. return;
  77. mw->box.pos = newPos;
  78. APP->scene->rack->updateExpanders();
  79. }
  80. void ModuleBypass::undo() {
  81. engine::Module* module = APP->engine->getModule(moduleId);
  82. if (!module)
  83. return;
  84. APP->engine->bypassModule(module, !bypassed);
  85. }
  86. void ModuleBypass::redo() {
  87. engine::Module* module = APP->engine->getModule(moduleId);
  88. if (!module)
  89. return;
  90. APP->engine->bypassModule(module, bypassed);
  91. }
  92. ModuleChange::~ModuleChange() {
  93. json_decref(oldModuleJ);
  94. json_decref(newModuleJ);
  95. }
  96. void ModuleChange::undo() {
  97. engine::Module* module = APP->engine->getModule(moduleId);
  98. if (!module)
  99. return;
  100. APP->engine->moduleFromJson(module, oldModuleJ);
  101. }
  102. void ModuleChange::redo() {
  103. engine::Module* module = APP->engine->getModule(moduleId);
  104. if (!module)
  105. return;
  106. APP->engine->moduleFromJson(module, newModuleJ);
  107. }
  108. void ParamChange::undo() {
  109. engine::Module* module = APP->engine->getModule(moduleId);
  110. if (!module)
  111. return;
  112. APP->engine->setParamValue(module, paramId, oldValue);
  113. }
  114. void ParamChange::redo() {
  115. engine::Module* module = APP->engine->getModule(moduleId);
  116. if (!module)
  117. return;
  118. APP->engine->setParamValue(module, paramId, newValue);
  119. }
  120. void CableAdd::setCable(app::CableWidget* cw) {
  121. assert(cw);
  122. assert(cw->cable);
  123. assert(cw->cable->id >= 0);
  124. cableId = cw->cable->id;
  125. assert(cw->cable->outputModule);
  126. outputModuleId = cw->cable->outputModule->id;
  127. outputId = cw->cable->outputId;
  128. assert(cw->cable->inputModule);
  129. inputModuleId = cw->cable->inputModule->id;
  130. inputId = cw->cable->inputId;
  131. color = cw->color;
  132. }
  133. void CableAdd::undo() {
  134. app::CableWidget* cw = APP->scene->rack->getCable(cableId);
  135. if (!cw)
  136. return;
  137. APP->scene->rack->removeCable(cw);
  138. delete cw;
  139. }
  140. void CableAdd::redo() {
  141. engine::Cable* cable = new engine::Cable;
  142. cable->id = cableId;
  143. cable->inputModule = APP->engine->getModule(inputModuleId);
  144. if (!cable->inputModule) {
  145. delete cable;
  146. return;
  147. }
  148. cable->inputId = inputId;
  149. cable->outputModule = APP->engine->getModule(outputModuleId);
  150. if (!cable->outputModule) {
  151. delete cable;
  152. return;
  153. }
  154. cable->outputId = outputId;
  155. APP->engine->addCable(cable);
  156. app::CableWidget* cw = new app::CableWidget;
  157. cw->setCable(cable);
  158. cw->color = color;
  159. APP->scene->rack->addCable(cw);
  160. }
  161. void CableColorChange::setCable(app::CableWidget* cw) {
  162. assert(cw);
  163. assert(cw->cable);
  164. assert(cw->cable->id >= 0);
  165. cableId = cw->cable->id;
  166. }
  167. void CableColorChange::undo() {
  168. app::CableWidget* cw = APP->scene->rack->getCable(cableId);
  169. if (!cw)
  170. return;
  171. cw->color = oldColor;
  172. }
  173. void CableColorChange::redo() {
  174. app::CableWidget* cw = APP->scene->rack->getCable(cableId);
  175. if (!cw)
  176. return;
  177. cw->color = newColor;
  178. }
  179. State::State() {
  180. clear();
  181. }
  182. State::~State() {
  183. clear();
  184. }
  185. void State::clear() {
  186. for (Action* action : actions) {
  187. delete action;
  188. }
  189. actions.clear();
  190. actionIndex = 0;
  191. savedIndex = -1;
  192. }
  193. void State::push(Action* action) {
  194. // Delete all future actions (if we have undone some actions)
  195. for (int i = actionIndex; i < (int) actions.size(); i++) {
  196. delete actions[i];
  197. }
  198. actions.resize(actionIndex);
  199. // Delete actions from beginning if limit is reached
  200. static const int limit = 500;
  201. int n = (int) actions.size() - limit + 1;
  202. if (n > 0) {
  203. for (int i = 0; i < n; i++) {
  204. delete actions[i];
  205. }
  206. actions.erase(actions.begin(), actions.begin() + n);
  207. actionIndex -= n;
  208. savedIndex -= n;
  209. }
  210. // Push action
  211. actions.push_back(action);
  212. actionIndex++;
  213. // Unset the savedIndex if we just permanently overwrote the saved state
  214. if (actionIndex == savedIndex) {
  215. savedIndex = -1;
  216. }
  217. }
  218. void State::undo() {
  219. if (canUndo()) {
  220. actionIndex--;
  221. actions[actionIndex]->undo();
  222. }
  223. }
  224. void State::redo() {
  225. if (canRedo()) {
  226. actions[actionIndex]->redo();
  227. actionIndex++;
  228. }
  229. }
  230. bool State::canUndo() {
  231. return actionIndex > 0;
  232. }
  233. bool State::canRedo() {
  234. return actionIndex < (int) actions.size();
  235. }
  236. std::string State::getUndoName() {
  237. if (!canUndo())
  238. return "";
  239. return actions[actionIndex - 1]->name;
  240. }
  241. std::string State::getRedoName() {
  242. if (!canRedo())
  243. return "";
  244. return actions[actionIndex]->name;
  245. }
  246. void State::setSaved() {
  247. savedIndex = actionIndex;
  248. }
  249. bool State::isSaved() {
  250. return actionIndex == savedIndex;
  251. }
  252. } // namespace history
  253. } // namespace rack