Move Preferences instance to app::Context

With this change we fix some tests when !ENABLE_UI and we start using
less Preferences::instance() (maybe in the future we could exclusively
access the preferences from the new Context::preferences() function).
This commit is contained in:
David Capello 2019-12-11 12:27:56 -03:00
parent e553777d24
commit 8139b8a1d4
10 changed files with 54 additions and 41 deletions

View File

@ -103,8 +103,14 @@ private:
class App::CoreModules {
public:
#ifdef ENABLE_UI
typedef app::UIContext ContextT;
#else
typedef app::Context ContextT;
#endif
ConfigModule m_configModule;
Preferences m_preferences;
ContextT m_context;
};
class App::LoadLanguage {
@ -117,12 +123,6 @@ public:
class App::Modules {
public:
#ifdef ENABLE_UI
typedef app::UIContext ContextT;
#else
typedef app::Context ContextT;
#endif
LoggerModule m_loggerModule;
FileSystemModule m_file_system_module;
Extensions m_extensions;
@ -131,7 +131,6 @@ public:
tools::ToolBox m_toolbox;
tools::ActiveToolManager m_activeToolManager;
Commands m_commands;
ContextT m_context;
#ifdef ENABLE_UI
RecentFiles m_recent_files;
InputChain m_inputChain;
@ -161,9 +160,9 @@ public:
return m_recovery;
}
void createDataRecovery() {
void createDataRecovery(Context* ctx) {
#ifdef ENABLE_DATA_RECOVERY
m_recovery = new app::crash::DataRecovery(&m_context);
m_recovery = new app::crash::DataRecovery(ctx);
m_recovery->SessionsListIsReady.connect(
[] {
ui::assert_ui_thread();
@ -252,7 +251,7 @@ int App::initialize(const AppOptions& options)
break;
}
initialize_color_spaces();
initialize_color_spaces(preferences());
// Load modules
m_modules = new Modules(createLogInDesktop, preferences());
@ -263,7 +262,7 @@ int App::initialize(const AppOptions& options)
// Data recovery is enabled only in GUI mode
if (isGui() && preferences().general.dataRecovery())
m_modules->createDataRecovery();
m_modules->createDataRecovery(context());
if (isPortable())
LOG("APP: Running in portable mode\n");
@ -319,7 +318,7 @@ int App::initialize(const AppOptions& options)
delegate.reset(new DefaultCliDelegate);
CliProcessor cli(delegate.get(), options);
int code = cli.process(&m_modules->m_context);
int code = cli.process(context());
if (code != 0)
return code;
}
@ -337,7 +336,7 @@ void App::run()
// How to interpret one finger on Windows tablets.
ui::Manager::getDefault()->getDisplay()
->setInterpretOneFingerGestureAsMouseMovement(
Preferences::instance().experimental.oneFingerAsMouseMovement());
preferences().experimental.oneFingerAsMouseMovement());
#endif
#if !defined(_WIN32) && !defined(__APPLE__)
@ -417,7 +416,7 @@ void App::run()
#ifdef ENABLE_UI
if (isGui()) {
// Select no document
m_modules->m_context.setActiveView(nullptr);
static_cast<UIContext*>(context())->setActiveView(nullptr);
// Delete backups (this is a normal shutdown, we are not handling
// exceptions, and we are not in a destructor).
@ -428,10 +427,10 @@ void App::run()
// Destroy all documents from the UIContext.
std::vector<Doc*> docs;
#ifdef ENABLE_UI
for (Doc* doc : m_modules->m_context.getAndRemoveAllClosedDocs())
for (Doc* doc : static_cast<UIContext*>(context())->getAndRemoveAllClosedDocs())
docs.push_back(doc);
#endif
for (Doc* doc : m_modules->m_context.documents())
for (Doc* doc : context()->documents())
docs.push_back(doc);
for (Doc* doc : docs) {
// First we close the document. In this way we receive recent
@ -496,7 +495,7 @@ App::~App()
// the scripts have a reproducible behavior. Those reset
// preferences must not be saved.
if (isGui())
m_coreModules->m_preferences.save();
preferences().save();
delete m_coreModules;
@ -523,7 +522,7 @@ App::~App()
Context* App::context()
{
return &m_modules->m_context;
return &m_coreModules->m_context;
}
bool App::isPortable()
@ -591,7 +590,7 @@ Timeline* App::timeline() const
Preferences& App::preferences() const
{
return m_coreModules->m_preferences;
return m_coreModules->m_context.preferences();
}
Extensions& App::extensions() const

View File

@ -19,12 +19,11 @@
namespace app {
ClosedDocs::ClosedDocs()
ClosedDocs::ClosedDocs(const Preferences& pref)
: m_done(false)
{
CLOSEDOC_TRACE("CLOSEDOC: Init");
const auto& pref = Preferences::instance();
if (pref.general.dataRecovery())
m_dataRecoveryPeriodMSecs = int(1000.0*60.0*pref.general.dataRecoveryPeriod());
else

View File

@ -18,6 +18,7 @@
namespace app {
class Doc;
class Preferences;
// Handle the list of closed docs:
// * When a document is closed, we keep it for some time so the user
@ -29,7 +30,7 @@ namespace app {
// the document was restore, we remove it from the m_docs.
class ClosedDocs {
public:
ClosedDocs();
ClosedDocs(const Preferences& pref);
~ClosedDocs();
bool hasClosedDocs();

View File

@ -24,10 +24,10 @@ namespace app {
// spaces must be done.
static bool g_manage = false;
void initialize_color_spaces()
void initialize_color_spaces(Preferences& pref)
{
g_manage = Preferences::instance().color.manage();
Preferences::instance().color.manage.AfterChange.connect(
g_manage = pref.color.manage();
pref.color.manage.AfterChange.connect(
[](bool manage){
g_manage = manage;
});

View File

@ -19,8 +19,9 @@ namespace doc {
}
namespace app {
class Preferences;
void initialize_color_spaces();
void initialize_color_spaces(Preferences& pref);
os::ColorSpacePtr get_screen_color_space();

View File

@ -31,17 +31,28 @@ namespace app {
Context::Context()
: m_docs(this)
, m_lastSelectedDoc(nullptr)
, m_preferences(nullptr)
{
m_docs.add_observer(this);
m_docs.add_observer(&Preferences::instance());
}
Context::~Context()
{
m_docs.remove_observer(&Preferences::instance());
if (m_preferences)
m_docs.remove_observer(m_preferences.get());
m_docs.remove_observer(this);
}
Preferences& Context::preferences() const
{
if (!m_preferences) {
m_preferences.reset(new Preferences);
m_docs.add_observer(m_preferences.get());
}
return *m_preferences;
}
void Context::sendDocumentToTop(Doc* document)
{
ASSERT(document != NULL);

View File

@ -33,6 +33,7 @@ namespace app {
class Command;
class Doc;
class DocView;
class Preferences;
class CommandPreconditionException : public base::Exception {
public:
@ -69,6 +70,8 @@ namespace app {
const Docs& documents() const { return m_docs; }
Docs& documents() { return m_docs; }
Preferences& preferences() const;
virtual bool isUIAvailable() const { return false; }
virtual bool isRecordingMacro() const { return false; }
virtual bool isExecutingMacro() const { return false; }
@ -116,10 +119,11 @@ namespace app {
private:
ActiveSiteHandler* activeSiteHandler() const;
Docs m_docs;
mutable Docs m_docs;
ContextFlags m_flags; // Last updated flags.
Doc* m_lastSelectedDoc;
mutable std::unique_ptr<ActiveSiteHandler> m_activeSiteHandler;
mutable std::unique_ptr<Preferences> m_preferences;
DISABLE_COPYING(Context);
};

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2018-2019 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -12,8 +12,6 @@
#include "app/doc.h"
#include "app/file/file.h"
#include "app/file/file_formats_manager.h"
#include "app/ini_file.h"
#include "app/pref/preferences.h"
#include "doc/doc.h"
#include <cstdio>
@ -24,11 +22,6 @@ using namespace app;
TEST(File, SeveralSizes)
{
// Now we need a preferences instance to load/save files (for color
// profiles management).
push_config_state();
Preferences preferences;
// Register all possible image formats.
std::vector<char> fn(256);
app::Context ctx;

View File

@ -44,9 +44,13 @@ Preferences::Preferences()
ASSERT(!singleton);
singleton = this;
// Main configuration file
const std::string fn = main_config_filename();
ASSERT(!fn.empty());
// The first time we execute the program, the configuration file
// doesn't exist.
const bool firstTime = (!base::is_file(main_config_filename()));
const bool firstTime = (!base::is_file(fn));
load();

View File

@ -37,15 +37,16 @@ UIContext* UIContext::m_instance = nullptr;
UIContext::UIContext()
: m_lastSelectedView(nullptr)
, m_closedDocs(preferences())
{
ASSERT(m_instance == NULL);
ASSERT(m_instance == nullptr);
m_instance = this;
}
UIContext::~UIContext()
{
ASSERT(m_instance == this);
m_instance = NULL;
m_instance = nullptr;
// The context must be empty at this point. (It's to check if the UI
// is working correctly, i.e. closing all files when the user can