Skip to content

Commit

Permalink
refactor: Make Args less of a singleton (Chatterino#5041)
Browse files Browse the repository at this point in the history
This means it's no longer a singleton, and its lifetime is bound to our application.
This felt like a good small experiment to see how its changes would look
if we did this.
As a shortcut, `getApp` that is already a mega singleton keeps a
reference to Args, this means places that are a bit more difficult to
inject into call `getApp()->getArgs()` just like other things are
accessed.
  • Loading branch information
pajlada authored Dec 29, 2023
1 parent c65ebd2 commit d085ab5
Show file tree
Hide file tree
Showing 20 changed files with 78 additions and 69 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
- Dev: BREAKING: Replace custom `import()` with normal Lua `require()`. (#5014)
- Dev: Fixed most compiler warnings. (#5028)
- Dev: Added the ability to show `ChannelView`s without a `Split`. (#4747)
- Dev: Refactor Args to be less of a singleton. (#5041)
- Dev: Channels without any animated elements on screen will skip updates from the GIF timer. (#5042, #5043, #5045)

## 2.4.6
Expand Down
9 changes: 9 additions & 0 deletions mocks/include/mocks/EmptyApplication.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "Application.hpp"
#include "common/Args.hpp"

namespace chatterino::mock {

Expand All @@ -9,6 +10,11 @@ class EmptyApplication : public IApplication
public:
virtual ~EmptyApplication() = default;

const Args &getArgs() override
{
return this->args_;
}

Theme *getThemes() override
{
return nullptr;
Expand Down Expand Up @@ -110,6 +116,9 @@ class EmptyApplication : public IApplication
{
return nullptr;
}

private:
Args args_;
};

} // namespace chatterino::mock
15 changes: 8 additions & 7 deletions src/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,9 @@ IApplication::IApplication()
// It will create the instances of the major classes, and connect their signals
// to each other

Application::Application(Settings &_settings, Paths &_paths)
: themes(&this->emplace<Theme>())
Application::Application(Settings &_settings, Paths &_paths, const Args &_args)
: args_(_args)
, themes(&this->emplace<Theme>())
, fonts(&this->emplace<Fonts>())
, emotes(&this->emplace<Emotes>())
, accounts(&this->emplace<AccountController>())
Expand Down Expand Up @@ -146,7 +147,7 @@ void Application::initialize(Settings &settings, Paths &paths)
isAppInitialized = true;

// Show changelog
if (!getArgs().isFramelessEmbed &&
if (!this->args_.isFramelessEmbed &&
getSettings()->currentVersion.getValue() != "" &&
getSettings()->currentVersion.getValue() != CHATTERINO_VERSION)
{
Expand All @@ -161,7 +162,7 @@ void Application::initialize(Settings &settings, Paths &paths)
}
}

if (!getArgs().isFramelessEmbed)
if (!this->args_.isFramelessEmbed)
{
getSettings()->currentVersion.setValue(CHATTERINO_VERSION);

Expand All @@ -179,7 +180,7 @@ void Application::initialize(Settings &settings, Paths &paths)
// Show crash message.
// On Windows, the crash message was already shown.
#ifndef Q_OS_WIN
if (!getArgs().isFramelessEmbed && getArgs().crashRecovery)
if (!this->args_.isFramelessEmbed && this->args_.crashRecovery)
{
if (auto selected =
this->windows->getMainWindow().getNotebook().getSelectedPage())
Expand All @@ -203,7 +204,7 @@ void Application::initialize(Settings &settings, Paths &paths)

this->windows->updateWordTypeMask();

if (!getArgs().isFramelessEmbed)
if (!this->args_.isFramelessEmbed)
{
this->initNm(paths);
}
Expand All @@ -219,7 +220,7 @@ int Application::run(QApplication &qtApp)

this->twitch->connect();

if (!getArgs().isFramelessEmbed)
if (!this->args_.isFramelessEmbed)
{
this->windows->getMainWindow().show();
}
Expand Down
9 changes: 8 additions & 1 deletion src/Application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace chatterino {

class Args;
class TwitchIrcServer;
class ITwitchIrcServer;
class PubSub;
Expand Down Expand Up @@ -54,6 +55,7 @@ class IApplication

static IApplication *instance;

virtual const Args &getArgs() = 0;
virtual Theme *getThemes() = 0;
virtual Fonts *getFonts() = 0;
virtual IEmotes *getEmotes() = 0;
Expand All @@ -78,14 +80,15 @@ class IApplication

class Application : public IApplication
{
const Args &args_;
std::vector<std::unique_ptr<Singleton>> singletons_;
int argc_{};
char **argv_{};

public:
static Application *instance;

Application(Settings &settings, Paths &paths);
Application(Settings &_settings, Paths &_paths, const Args &_args);

void initialize(Settings &settings, Paths &paths);
void load();
Expand Down Expand Up @@ -126,6 +129,10 @@ class Application : public IApplication

/*[[deprecated]]*/ Logging *const logging{};

const Args &getArgs() override
{
return this->args_;
}
Theme *getThemes() override
{
return this->themes;
Expand Down
14 changes: 7 additions & 7 deletions src/RunGui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ namespace {
installCustomPalette();
}

void showLastCrashDialog()
void showLastCrashDialog(const Args &args)
{
auto *dialog = new LastRunCrashDialog;
auto *dialog = new LastRunCrashDialog(args);
// Use exec() over open() to block the app from being loaded
// and to be able to set the safe mode.
dialog->exec();
Expand Down Expand Up @@ -223,16 +223,16 @@ namespace {
}
} // namespace

void runGui(QApplication &a, Paths &paths, Settings &settings)
void runGui(QApplication &a, Paths &paths, Settings &settings, const Args &args)
{
initQt();
initResources();
initSignalHandler();

#ifdef Q_OS_WIN
if (getArgs().crashRecovery)
if (args.crashRecovery)
{
showLastCrashDialog();
showLastCrashDialog(args);
}
#endif

Expand Down Expand Up @@ -271,12 +271,12 @@ void runGui(QApplication &a, Paths &paths, Settings &settings)
chatterino::NetworkManager::init();
chatterino::Updates::instance().checkForUpdates();

Application app(settings, paths);
Application app(settings, paths, args);
app.initialize(settings, paths);
app.run(a);
app.save();

if (!getArgs().dontSaveSettings)
if (!args.dontSaveSettings)
{
pajlada::Settings::SettingManager::gSave();
}
Expand Down
6 changes: 5 additions & 1 deletion src/RunGui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
class QApplication;

namespace chatterino {

class Args;
class Paths;
class Settings;

void runGui(QApplication &a, Paths &paths, Settings &settings);
void runGui(QApplication &a, Paths &paths, Settings &settings,
const Args &args);

} // namespace chatterino
16 changes: 1 addition & 15 deletions src/common/Args.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "Args.hpp"
#include "common/Args.hpp"

#include "common/QLogging.hpp"
#include "debug/AssertInGuiThread.hpp"
Expand Down Expand Up @@ -248,18 +248,4 @@ void Args::applyCustomChannelLayout(const QString &argValue)
}
}

static Args *instance = nullptr;

void initArgs(const QApplication &app)
{
instance = new Args(app);
}

const Args &getArgs()
{
assert(instance);

return *instance;
}

} // namespace chatterino
4 changes: 1 addition & 3 deletions src/common/Args.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace chatterino {
class Args
{
public:
Args() = default;
Args(const QApplication &app);

bool printVersion{};
Expand Down Expand Up @@ -60,7 +61,4 @@ class Args
QStringList currentArguments_;
};

void initArgs(const QApplication &app);
const Args &getArgs();

} // namespace chatterino
2 changes: 1 addition & 1 deletion src/controllers/plugins/PluginController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ void PluginController::load(const QFileInfo &index, const QDir &pluginDir,
auto *temp = plugin.get();
this->plugins_.insert({pluginName, std::move(plugin)});

if (getArgs().safeMode)
if (getApp()->getArgs().safeMode)
{
// This isn't done earlier to ensure the user can disable a misbehaving plugin
qCWarning(chatterinoLua) << "Skipping loading plugin " << meta.name
Expand Down
12 changes: 6 additions & 6 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,18 @@ int main(int argc, char **argv)
return 1;
}

initArgs(a);
const Args args(a);

#ifdef CHATTERINO_WITH_CRASHPAD
const auto crashpadHandler = installCrashHandler();
const auto crashpadHandler = installCrashHandler(args);
#endif

// run in gui mode or browser extension host mode
if (getArgs().shouldRunBrowserExtensionHost)
if (args.shouldRunBrowserExtensionHost)
{
runBrowserExtensionHost();
}
else if (getArgs().printVersion)
else if (args.printVersion)
{
attachToConsole();

Expand All @@ -87,7 +87,7 @@ int main(int argc, char **argv)
}
else
{
if (getArgs().verbose)
if (args.verbose)
{
attachToConsole();
}
Expand All @@ -99,7 +99,7 @@ int main(int argc, char **argv)

Settings settings(paths->settingsDirectory);

runGui(a, *paths, settings);
runGui(a, *paths, settings, args);
}
return 0;
}
13 changes: 6 additions & 7 deletions src/singletons/CrashHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,9 @@ std::optional<bool> readRecoverySettings(const Paths &paths)
return shouldRecover.toBool();
}

bool canRestart(const Paths &paths)
bool canRestart(const Paths &paths, const Args &args)
{
#ifdef NDEBUG
const auto &args = chatterino::getArgs();
if (args.isFramelessEmbed || args.shouldRunBrowserExtensionHost)
{
return false;
Expand All @@ -109,10 +108,10 @@ bool canRestart(const Paths &paths)
/// additional plus ('++' -> '+').
///
/// The decoding happens in crash-handler/src/CommandLine.cpp
std::string encodeArguments()
std::string encodeArguments(const Args &appArgs)
{
std::string args;
for (auto arg : getArgs().currentArguments())
for (auto arg : appArgs.currentArguments())
{
if (!args.empty())
{
Expand Down Expand Up @@ -161,7 +160,7 @@ void CrashHandler::saveShouldRecover(bool value)
}

#ifdef CHATTERINO_WITH_CRASHPAD
std::unique_ptr<crashpad::CrashpadClient> installCrashHandler()
std::unique_ptr<crashpad::CrashpadClient> installCrashHandler(const Args &args)
{
// Currently, the following directory layout is assumed:
// [applicationDirPath]
Expand Down Expand Up @@ -197,7 +196,7 @@ std::unique_ptr<crashpad::CrashpadClient> installCrashHandler()
std::map<std::string, std::string> annotations{
{
"canRestart"s,
canRestart(*getPaths()) ? "true"s : "false"s,
canRestart(*getPaths(), args) ? "true"s : "false"s,
},
{
"exePath"s,
Expand All @@ -209,7 +208,7 @@ std::unique_ptr<crashpad::CrashpadClient> installCrashHandler()
},
{
"exeArguments"s,
encodeArguments(),
encodeArguments(args),
},
};

Expand Down
4 changes: 3 additions & 1 deletion src/singletons/CrashHandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

namespace chatterino {

class Args;

class CrashHandler : public Singleton
{
public:
Expand All @@ -30,7 +32,7 @@ class CrashHandler : public Singleton
};

#ifdef CHATTERINO_WITH_CRASHPAD
std::unique_ptr<crashpad::CrashpadClient> installCrashHandler();
std::unique_ptr<crashpad::CrashpadClient> installCrashHandler(const Args &args);
#endif

} // namespace chatterino
Loading

0 comments on commit d085ab5

Please sign in to comment.