From 644b8ff0a43405b9193a24b62a4a7bd1aa6f87f8 Mon Sep 17 00:00:00 2001 From: David Capello Date: Mon, 7 Nov 2016 17:47:53 -0300 Subject: [PATCH] Add Ctrl+Shift+R on debug mode to recover the active document from active backup session In this way we can test on each moment how the information is being saved and will be recovered. We can find bugs with missing or invalid doc::Object::incrementVersion() calls. --- src/README.md | 9 ++++++--- src/app/app.cpp | 6 ++++++ src/app/app.h | 5 +++++ src/app/crash/data_recovery.h | 4 +++- src/app/crash/session.cpp | 12 ++++++++++++ src/app/crash/session.h | 2 ++ src/app/modules/gui.cpp | 26 +++++++++++++++++++++++--- 7 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/README.md b/src/README.md index 51c9e6046..b27434d8e 100644 --- a/src/README.md +++ b/src/README.md @@ -59,6 +59,9 @@ because they don't depend on any other component. # Debugging Tricks -On Windows, you can use F5 to show the amount of used memory. Also -`Ctrl+Shift+Q` crashes the application in case that you want to test -the anticrash feature or your need a memory dump file. +* On Windows, you can use F5 to show the amount of used memory. +* On debug mode (when `_DEBUG` is defined), `Ctrl+Alt+Shift+Q` crashes + the application in case that you want to test the anticrash feature + or your need a memory dump file. +* On debug mode, you can use `Ctrl+Alt+Shift+R` to recover the active + document from the data recovery store. diff --git a/src/app/app.cpp b/src/app/app.cpp index 1abb084bb..b2c7167a6 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -129,6 +129,7 @@ public: void deleteDataRecovery() { #ifdef ENABLE_DATA_RECOVERY delete m_recovery; + m_recovery = nullptr; #endif } @@ -845,6 +846,11 @@ Preferences& App::preferences() const return m_coreModules->m_preferences; } +crash::DataRecovery* App::dataRecovery() const +{ + return m_modules->recovery(); +} + void App::showNotification(INotificationDelegate* del) { m_mainWindow->showNotification(del); diff --git a/src/app/app.h b/src/app/app.h index ebd520e39..6d4acb874 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -42,6 +42,10 @@ namespace app { class Timeline; class Workspace; + namespace crash { + class DataRecovery; + } + namespace tools { class ActiveToolManager; class Tool; @@ -78,6 +82,7 @@ namespace app { ContextBar* contextBar() const; Timeline* timeline() const; Preferences& preferences() const; + crash::DataRecovery* dataRecovery() const; AppBrushes& brushes() { ASSERT(m_brushes.get()); diff --git a/src/app/crash/data_recovery.h b/src/app/crash/data_recovery.h index b2b4dfa34..51a2924e3 100644 --- a/src/app/crash/data_recovery.h +++ b/src/app/crash/data_recovery.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2001-2015 David Capello +// Copyright (C) 2001-2016 David Capello // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -28,6 +28,8 @@ namespace crash { DataRecovery(doc::Context* context); ~DataRecovery(); + Session* activeSession() { return m_inProgress.get(); } + // Returns the list of sessions that can be recovered. const Sessions& sessions() { return m_sessions; } diff --git a/src/app/crash/session.cpp b/src/app/crash/session.cpp index fd076d784..6925c0c58 100644 --- a/src/app/crash/session.cpp +++ b/src/app/crash/session.cpp @@ -25,6 +25,7 @@ #include "base/process.h" #include "base/split_string.h" #include "base/string.h" +#include "base/unique_ptr.h" namespace app { namespace crash { @@ -173,6 +174,17 @@ void Session::restoreBackup(Backup* backup) } } +void Session::restoreBackupById(const ObjectId id) +{ + std::string docDir = base::join_path(m_path, base::convert_to(int(id))); + if (!base::is_directory(docDir)) + return; + + base::UniquePtr backup(new Backup(docDir)); + if (backup) + restoreBackup(backup.get()); +} + void Session::restoreRawImages(Backup* backup, RawImagesAs as) { Console console; diff --git a/src/app/crash/session.h b/src/app/crash/session.h index 354ecc7c5..ac9b9b667 100644 --- a/src/app/crash/session.h +++ b/src/app/crash/session.h @@ -12,6 +12,7 @@ #include "base/disable_copying.h" #include "base/process.h" #include "base/shared_ptr.h" +#include "doc/object_id.h" #include #include @@ -52,6 +53,7 @@ namespace crash { void removeDocument(app::Document* doc); void restoreBackup(Backup* backup); + void restoreBackupById(const doc::ObjectId id); void restoreRawImages(Backup* backup, RawImagesAs as); void deleteBackup(Backup* backup); diff --git a/src/app/modules/gui.cpp b/src/app/modules/gui.cpp index 5ab764a04..615856a27 100644 --- a/src/app/modules/gui.cpp +++ b/src/app/modules/gui.cpp @@ -15,7 +15,6 @@ #include "app/console.h" #include "app/document.h" #include "app/ini_file.h" -#include "app/modules/editors.h" #include "app/modules/gfx.h" #include "app/modules/gui.h" #include "app/modules/palettes.h" @@ -47,6 +46,11 @@ #include #include +#if defined(_DEBUG) && defined(ENABLE_DATA_RECOVERY) +#include "app/crash/data_recovery.h" +#include "app/modules/editors.h" +#endif + namespace app { using namespace gfx; @@ -372,14 +376,30 @@ bool CustomizedGuiManager::onProcessMessage(Message* msg) case kKeyDownMessage: { #ifdef _DEBUG - // Left Shift+Ctrl+Q generates a crash (useful to test the anticrash feature) + // Ctrl+Shift+Q generates a crash (useful to test the anticrash feature) if (msg->ctrlPressed() && msg->shiftPressed() && static_cast(msg)->scancode() == kKeyQ) { int* p = nullptr; *p = 0; } -#endif + +#ifdef ENABLE_DATA_RECOVERY + // Ctrl+Shift+R recover active sprite from the backup store + if (msg->ctrlPressed() && + msg->shiftPressed() && + static_cast(msg)->scancode() == kKeyR && + App::instance()->dataRecovery() && + App::instance()->dataRecovery()->activeSession() && + current_editor && + current_editor->document()) { + App::instance() + ->dataRecovery() + ->activeSession() + ->restoreBackupById(current_editor->document()->id()); + } +#endif // ENABLE_DATA_RECOVERY +#endif // _DEBUG // Call base impl to check if there is a foreground window as // top level that needs keys. (In this way we just do not