Use std::unique_ptr/optional in more App objects

This commit is contained in:
David Capello 2022-06-09 17:13:51 -03:00
parent 99c0d5b743
commit b2d46bf10b
6 changed files with 74 additions and 48 deletions

View File

@ -87,6 +87,9 @@
#include "steam/steam.h" #include "steam/steam.h"
#endif #endif
#include <memory>
#include <optional>
namespace app { namespace app {
using namespace ui; using namespace ui;
@ -147,10 +150,12 @@ public:
InputChain m_inputChain; InputChain m_inputChain;
clipboard::ClipboardManager m_clipboardManager; clipboard::ClipboardManager m_clipboardManager;
#endif #endif
#ifdef ENABLE_DATA_RECOVERY
// This is a raw pointer because we want to delete it explicitly. // This is a raw pointer because we want to delete it explicitly.
// (e.g. if an exception occurs, the ~Modules() doesn't have to // (e.g. if an exception occurs, the ~Modules() doesn't have to
// delete m_recovery) // delete m_recovery)
app::crash::DataRecovery* m_recovery; std::unique_ptr<app::crash::DataRecovery> m_recovery;
#endif
Modules(const bool createLogInDesktop, Modules(const bool createLogInDesktop,
Preferences& pref) Preferences& pref)
@ -160,21 +165,30 @@ public:
#ifdef ENABLE_UI #ifdef ENABLE_UI
, m_recent_files(pref.general.recentItems()) , m_recent_files(pref.general.recentItems())
#endif #endif
, m_recovery(nullptr) { #ifdef ENABLE_DATA_RECOVERY
, m_recovery(nullptr)
#endif
{
} }
~Modules() { ~Modules() {
#ifdef ENABLE_DATA_RECOVERY
ASSERT(m_recovery == nullptr || ASSERT(m_recovery == nullptr ||
ui::get_app_state() == ui::AppState::kClosingWithException); ui::get_app_state() == ui::AppState::kClosingWithException);
#endif
} }
app::crash::DataRecovery* recovery() { app::crash::DataRecovery* recovery() {
return m_recovery; #ifdef ENABLE_DATA_RECOVERY
return m_recovery.get();
#else
return nullptr;
#endif
} }
void createDataRecovery(Context* ctx) { void createDataRecovery(Context* ctx) {
#ifdef ENABLE_DATA_RECOVERY #ifdef ENABLE_DATA_RECOVERY
m_recovery = new app::crash::DataRecovery(ctx); m_recovery = std::make_unique<app::crash::DataRecovery>(ctx);
m_recovery->SessionsListIsReady.connect( m_recovery->SessionsListIsReady.connect(
[] { [] {
ui::assert_ui_thread(); ui::assert_ui_thread();
@ -197,10 +211,7 @@ public:
void deleteDataRecovery() { void deleteDataRecovery() {
#ifdef ENABLE_DATA_RECOVERY #ifdef ENABLE_DATA_RECOVERY
if (m_recovery) { m_recovery.reset();
delete m_recovery;
m_recovery = nullptr;
}
#endif #endif
} }
@ -222,7 +233,7 @@ App::App(AppMod* mod)
, m_engine(new script::Engine) , m_engine(new script::Engine)
#endif #endif
{ {
ASSERT(m_instance == NULL); ASSERT(m_instance == nullptr);
m_instance = this; m_instance = this;
} }
@ -236,7 +247,7 @@ int App::initialize(const AppOptions& options)
m_isGui = false; m_isGui = false;
#endif #endif
m_isShell = options.startShell(); m_isShell = options.startShell();
m_coreModules = new CoreModules; m_coreModules = std::make_unique<CoreModules>();
#if LAF_WINDOWS #if LAF_WINDOWS
@ -289,10 +300,10 @@ int App::initialize(const AppOptions& options)
initialize_color_spaces(preferences()); initialize_color_spaces(preferences());
// Load modules // Load modules
m_modules = new Modules(createLogInDesktop, preferences()); m_modules = std::make_unique<Modules>(createLogInDesktop, preferences());
m_legacy = new LegacyModules(isGui() ? REQUIRE_INTERFACE: 0); m_legacy = std::make_unique<LegacyModules>(isGui() ? REQUIRE_INTERFACE: 0);
#ifdef ENABLE_UI #ifdef ENABLE_UI
m_brushes.reset(new AppBrushes); m_brushes = std::make_unique<AppBrushes>();
#endif #endif
// Data recovery is enabled only in GUI mode // Data recovery is enabled only in GUI mode
@ -572,17 +583,14 @@ App::~App()
// Finalize modules, configuration and core. // Finalize modules, configuration and core.
Editor::destroyEditorSharedInternals(); Editor::destroyEditorSharedInternals();
if (m_backupIndicator) { m_backupIndicator.reset();
delete m_backupIndicator;
m_backupIndicator = nullptr;
}
// Save brushes // Save brushes
m_brushes.reset(nullptr); m_brushes.reset();
#endif #endif
delete m_legacy; m_legacy.reset();
delete m_modules; m_modules.reset();
// Save preferences only if we are running in GUI mode. when we // Save preferences only if we are running in GUI mode. when we
// run in batch mode we might want to reset some preferences so // run in batch mode we might want to reset some preferences so
@ -591,15 +599,13 @@ App::~App()
if (isGui()) if (isGui())
preferences().save(); preferences().save();
delete m_coreModules; m_coreModules.reset();
#ifdef ENABLE_UI #ifdef ENABLE_UI
// Destroy the loaded gui.xml data. // Destroy the loaded gui.xml data.
delete KeyboardShortcuts::instance(); KeyboardShortcuts::destroyInstance();
delete GuiXml::instance(); GuiXml::destroyInstance();
#endif #endif
m_instance = NULL;
} }
catch (const std::exception& e) { catch (const std::exception& e) {
LOG(ERROR, "APP: Error: %s\n", e.what()); LOG(ERROR, "APP: Error: %s\n", e.what());
@ -612,6 +618,8 @@ App::~App()
// no re-throw // no re-throw
} }
m_instance = nullptr;
} }
Context* App::context() Context* App::context()
@ -621,15 +629,14 @@ Context* App::context()
bool App::isPortable() bool App::isPortable()
{ {
static bool* is_portable = NULL; static std::optional<bool> is_portable;
if (!is_portable) { if (!is_portable) {
is_portable = is_portable =
new bool(
base::is_file(base::join_path( base::is_file(base::join_path(
base::get_file_path(base::get_app_path()), base::get_file_path(base::get_app_path()),
"aseprite.ini"))); "aseprite.ini"));
} }
return *is_portable; return is_portable.value();
} }
tools::ToolBox* App::toolBox() const tools::ToolBox* App::toolBox() const
@ -709,7 +716,7 @@ void App::showBackupNotification(bool state)
assert_ui_thread(); assert_ui_thread();
if (state) { if (state) {
if (!m_backupIndicator) if (!m_backupIndicator)
m_backupIndicator = new BackupIndicator; m_backupIndicator = std::make_unique<BackupIndicator>();
m_backupIndicator->start(); m_backupIndicator->start();
} }
else { else {

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018-2020 Igara Studio S.A. // Copyright (C) 2018-2022 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -135,16 +135,16 @@ namespace app {
AppMod* m_mod; AppMod* m_mod;
std::unique_ptr<ui::UISystem> m_uiSystem; std::unique_ptr<ui::UISystem> m_uiSystem;
CoreModules* m_coreModules; std::unique_ptr<CoreModules> m_coreModules;
Modules* m_modules; std::unique_ptr<Modules> m_modules;
LegacyModules* m_legacy; std::unique_ptr<LegacyModules> m_legacy;
bool m_isGui; bool m_isGui;
bool m_isShell; bool m_isShell;
std::unique_ptr<MainWindow> m_mainWindow; std::unique_ptr<MainWindow> m_mainWindow;
base::paths m_files; base::paths m_files;
#ifdef ENABLE_UI #ifdef ENABLE_UI
std::unique_ptr<AppBrushes> m_brushes; std::unique_ptr<AppBrushes> m_brushes;
BackupIndicator* m_backupIndicator; std::unique_ptr<BackupIndicator> m_backupIndicator;
#endif // ENABLE_UI #endif // ENABLE_UI
#ifdef ENABLE_SCRIPTING #ifdef ENABLE_SCRIPTING
std::unique_ptr<script::Engine> m_engine; std::unique_ptr<script::Engine> m_engine;

View File

@ -18,13 +18,20 @@
namespace app { namespace app {
static std::unique_ptr<GuiXml> g_singleton;
// static // static
GuiXml* GuiXml::instance() GuiXml* GuiXml::instance()
{ {
static GuiXml* singleton = 0; if (!g_singleton)
if (!singleton) g_singleton = std::make_unique<GuiXml>();
singleton = new GuiXml(); return g_singleton.get();
return singleton; }
// static
void GuiXml::destroyInstance()
{
g_singleton.reset();
} }
GuiXml::GuiXml() GuiXml::GuiXml()

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2020 Igara Studio S.A. // Copyright (C) 2020-2022 Igara Studio S.A.
// Copyright (C) 2001-2015 David Capello // Copyright (C) 2001-2015 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -11,6 +11,7 @@
#include "app/xml_document.h" #include "app/xml_document.h"
#include <memory>
#include <string> #include <string>
namespace app { namespace app {
@ -22,6 +23,9 @@ namespace app {
// gui.xml file will be loaded by the first time, which could // gui.xml file will be loaded by the first time, which could
// generated an exception if there are errors in the XML file. // generated an exception if there are errors in the XML file.
static GuiXml* instance(); static GuiXml* instance();
static void destroyInstance();
GuiXml();
// Returns the tinyxml document instance. // Returns the tinyxml document instance.
XmlDocumentRef doc() { XmlDocumentRef doc() {
@ -34,9 +38,8 @@ namespace app {
} }
private: private:
GuiXml();
XmlDocumentRef m_doc; XmlDocumentRef m_doc;
friend class std::unique_ptr<GuiXml>;
}; };
} // namespace app } // namespace app

View File

@ -465,12 +465,20 @@ std::string Key::triggerString() const
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// KeyboardShortcuts // KeyboardShortcuts
static std::unique_ptr<KeyboardShortcuts> g_singleton;
// static
KeyboardShortcuts* KeyboardShortcuts::instance() KeyboardShortcuts* KeyboardShortcuts::instance()
{ {
static KeyboardShortcuts* singleton = NULL; if (!g_singleton)
if (!singleton) g_singleton = std::make_unique<KeyboardShortcuts>();
singleton = new KeyboardShortcuts(); return g_singleton.get();
return singleton; }
// static
void KeyboardShortcuts::destroyInstance()
{
g_singleton.reset();
} }
KeyboardShortcuts::KeyboardShortcuts() KeyboardShortcuts::KeyboardShortcuts()

View File

@ -22,6 +22,7 @@ namespace app {
typedef Keys::const_iterator const_iterator; typedef Keys::const_iterator const_iterator;
static KeyboardShortcuts* instance(); static KeyboardShortcuts* instance();
static void destroyInstance();
KeyboardShortcuts(); KeyboardShortcuts();
KeyboardShortcuts(const KeyboardShortcuts&) = delete; KeyboardShortcuts(const KeyboardShortcuts&) = delete;