diff --git a/src/app/app.cpp b/src/app/app.cpp index 2c02593a2..5d09d32ae 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -87,6 +87,9 @@ #include "steam/steam.h" #endif +#include +#include + namespace app { using namespace ui; @@ -147,10 +150,12 @@ public: InputChain m_inputChain; clipboard::ClipboardManager m_clipboardManager; #endif +#ifdef ENABLE_DATA_RECOVERY // This is a raw pointer because we want to delete it explicitly. // (e.g. if an exception occurs, the ~Modules() doesn't have to // delete m_recovery) - app::crash::DataRecovery* m_recovery; + std::unique_ptr m_recovery; +#endif Modules(const bool createLogInDesktop, Preferences& pref) @@ -160,21 +165,30 @@ public: #ifdef ENABLE_UI , m_recent_files(pref.general.recentItems()) #endif - , m_recovery(nullptr) { +#ifdef ENABLE_DATA_RECOVERY + , m_recovery(nullptr) +#endif + { } ~Modules() { +#ifdef ENABLE_DATA_RECOVERY ASSERT(m_recovery == nullptr || ui::get_app_state() == ui::AppState::kClosingWithException); +#endif } app::crash::DataRecovery* recovery() { - return m_recovery; +#ifdef ENABLE_DATA_RECOVERY + return m_recovery.get(); +#else + return nullptr; +#endif } void createDataRecovery(Context* ctx) { #ifdef ENABLE_DATA_RECOVERY - m_recovery = new app::crash::DataRecovery(ctx); + m_recovery = std::make_unique(ctx); m_recovery->SessionsListIsReady.connect( [] { ui::assert_ui_thread(); @@ -197,10 +211,7 @@ public: void deleteDataRecovery() { #ifdef ENABLE_DATA_RECOVERY - if (m_recovery) { - delete m_recovery; - m_recovery = nullptr; - } + m_recovery.reset(); #endif } @@ -222,7 +233,7 @@ App::App(AppMod* mod) , m_engine(new script::Engine) #endif { - ASSERT(m_instance == NULL); + ASSERT(m_instance == nullptr); m_instance = this; } @@ -236,7 +247,7 @@ int App::initialize(const AppOptions& options) m_isGui = false; #endif m_isShell = options.startShell(); - m_coreModules = new CoreModules; + m_coreModules = std::make_unique(); #if LAF_WINDOWS @@ -289,10 +300,10 @@ int App::initialize(const AppOptions& options) initialize_color_spaces(preferences()); // Load modules - m_modules = new Modules(createLogInDesktop, preferences()); - m_legacy = new LegacyModules(isGui() ? REQUIRE_INTERFACE: 0); + m_modules = std::make_unique(createLogInDesktop, preferences()); + m_legacy = std::make_unique(isGui() ? REQUIRE_INTERFACE: 0); #ifdef ENABLE_UI - m_brushes.reset(new AppBrushes); + m_brushes = std::make_unique(); #endif // Data recovery is enabled only in GUI mode @@ -572,17 +583,14 @@ App::~App() // Finalize modules, configuration and core. Editor::destroyEditorSharedInternals(); - if (m_backupIndicator) { - delete m_backupIndicator; - m_backupIndicator = nullptr; - } + m_backupIndicator.reset(); // Save brushes - m_brushes.reset(nullptr); + m_brushes.reset(); #endif - delete m_legacy; - delete m_modules; + m_legacy.reset(); + m_modules.reset(); // Save preferences only if we are running in GUI mode. when we // run in batch mode we might want to reset some preferences so @@ -591,15 +599,13 @@ App::~App() if (isGui()) preferences().save(); - delete m_coreModules; + m_coreModules.reset(); #ifdef ENABLE_UI // Destroy the loaded gui.xml data. - delete KeyboardShortcuts::instance(); - delete GuiXml::instance(); + KeyboardShortcuts::destroyInstance(); + GuiXml::destroyInstance(); #endif - - m_instance = NULL; } catch (const std::exception& e) { LOG(ERROR, "APP: Error: %s\n", e.what()); @@ -612,6 +618,8 @@ App::~App() // no re-throw } + + m_instance = nullptr; } Context* App::context() @@ -621,15 +629,14 @@ Context* App::context() bool App::isPortable() { - static bool* is_portable = NULL; + static std::optional is_portable; if (!is_portable) { is_portable = - new bool( - base::is_file(base::join_path( - base::get_file_path(base::get_app_path()), - "aseprite.ini"))); + base::is_file(base::join_path( + base::get_file_path(base::get_app_path()), + "aseprite.ini")); } - return *is_portable; + return is_portable.value(); } tools::ToolBox* App::toolBox() const @@ -709,7 +716,7 @@ void App::showBackupNotification(bool state) assert_ui_thread(); if (state) { if (!m_backupIndicator) - m_backupIndicator = new BackupIndicator; + m_backupIndicator = std::make_unique(); m_backupIndicator->start(); } else { diff --git a/src/app/app.h b/src/app/app.h index e178ee519..020882446 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2018-2020 Igara Studio S.A. +// Copyright (C) 2018-2022 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -135,16 +135,16 @@ namespace app { AppMod* m_mod; std::unique_ptr m_uiSystem; - CoreModules* m_coreModules; - Modules* m_modules; - LegacyModules* m_legacy; + std::unique_ptr m_coreModules; + std::unique_ptr m_modules; + std::unique_ptr m_legacy; bool m_isGui; bool m_isShell; std::unique_ptr m_mainWindow; base::paths m_files; #ifdef ENABLE_UI std::unique_ptr m_brushes; - BackupIndicator* m_backupIndicator; + std::unique_ptr m_backupIndicator; #endif // ENABLE_UI #ifdef ENABLE_SCRIPTING std::unique_ptr m_engine; diff --git a/src/app/gui_xml.cpp b/src/app/gui_xml.cpp index 0e17d49b5..bf8f4cab4 100644 --- a/src/app/gui_xml.cpp +++ b/src/app/gui_xml.cpp @@ -18,13 +18,20 @@ namespace app { +static std::unique_ptr g_singleton; + // static GuiXml* GuiXml::instance() { - static GuiXml* singleton = 0; - if (!singleton) - singleton = new GuiXml(); - return singleton; + if (!g_singleton) + g_singleton = std::make_unique(); + return g_singleton.get(); +} + +// static +void GuiXml::destroyInstance() +{ + g_singleton.reset(); } GuiXml::GuiXml() diff --git a/src/app/gui_xml.h b/src/app/gui_xml.h index dde09790e..cbad619f9 100644 --- a/src/app/gui_xml.h +++ b/src/app/gui_xml.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2020 Igara Studio S.A. +// Copyright (C) 2020-2022 Igara Studio S.A. // Copyright (C) 2001-2015 David Capello // // This program is distributed under the terms of @@ -11,6 +11,7 @@ #include "app/xml_document.h" +#include #include namespace app { @@ -22,6 +23,9 @@ namespace app { // gui.xml file will be loaded by the first time, which could // generated an exception if there are errors in the XML file. static GuiXml* instance(); + static void destroyInstance(); + + GuiXml(); // Returns the tinyxml document instance. XmlDocumentRef doc() { @@ -34,9 +38,8 @@ namespace app { } private: - GuiXml(); - XmlDocumentRef m_doc; + friend class std::unique_ptr; }; } // namespace app diff --git a/src/app/ui/keyboard_shortcuts.cpp b/src/app/ui/keyboard_shortcuts.cpp index e0d728857..a19e59871 100644 --- a/src/app/ui/keyboard_shortcuts.cpp +++ b/src/app/ui/keyboard_shortcuts.cpp @@ -465,12 +465,20 @@ std::string Key::triggerString() const ////////////////////////////////////////////////////////////////////// // KeyboardShortcuts +static std::unique_ptr g_singleton; + +// static KeyboardShortcuts* KeyboardShortcuts::instance() { - static KeyboardShortcuts* singleton = NULL; - if (!singleton) - singleton = new KeyboardShortcuts(); - return singleton; + if (!g_singleton) + g_singleton = std::make_unique(); + return g_singleton.get(); +} + +// static +void KeyboardShortcuts::destroyInstance() +{ + g_singleton.reset(); } KeyboardShortcuts::KeyboardShortcuts() diff --git a/src/app/ui/keyboard_shortcuts.h b/src/app/ui/keyboard_shortcuts.h index 934fe62c2..b53c58e7f 100644 --- a/src/app/ui/keyboard_shortcuts.h +++ b/src/app/ui/keyboard_shortcuts.h @@ -22,6 +22,7 @@ namespace app { typedef Keys::const_iterator const_iterator; static KeyboardShortcuts* instance(); + static void destroyInstance(); KeyboardShortcuts(); KeyboardShortcuts(const KeyboardShortcuts&) = delete;