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.
This commit is contained in:
David Capello 2016-11-07 17:47:53 -03:00
parent 1b2b98ec38
commit 644b8ff0a4
7 changed files with 57 additions and 7 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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());

View File

@ -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; }

View File

@ -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<std::string>(int(id)));
if (!base::is_directory(docDir))
return;
base::UniquePtr<Backup> backup(new Backup(docDir));
if (backup)
restoreBackup(backup.get());
}
void Session::restoreRawImages(Backup* backup, RawImagesAs as)
{
Console console;

View File

@ -12,6 +12,7 @@
#include "base/disable_copying.h"
#include "base/process.h"
#include "base/shared_ptr.h"
#include "doc/object_id.h"
#include <fstream>
#include <string>
@ -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);

View File

@ -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 <list>
#include <vector>
#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<KeyMessage*>(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<KeyMessage*>(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