Loading...
Searching...
No Matches
MinimalApplication.hpp
1#pragma once
2
3#include <core/application/ApplicationInterface.hpp>
4#include <core/application/ApplicationSettings.hpp>
5#include <core/presenter/Presenter.hpp>
6#include <core/settings/Settings.hpp>
7#include <core/view/Window.hpp>
8
9#include <QApplication>
10
11#include <clocale>
12#include <memory>
13
14#if defined(SCORE_STATIC_PLUGINS)
15#include <score_static_plugins.hpp>
16#endif
17
18namespace score
19{
21 : public QObject
23{
24public:
26 {
27 int argc = 1;
28 const char* argv[2] = {"score", nullptr};
29 };
30
33 {
34 }
35
36 explicit MinimalApplication(DefaultArgs& args)
37 : MinimalApplication{args.argc, (char**)args.argv}
38 {
39 }
40
41 MinimalApplication(int& argc, char** argv)
42 : QObject{nullptr}
43 , m_app{new QApplication{argc, argv}}
44 {
45#if defined(SCORE_STATIC_PLUGINS)
46 score_init_static_plugins();
47#endif
48
49 m_instance = this;
50 this->setParent(m_app.get());
51
52 m_presenter
53 = new score::Presenter{m_applicationSettings, m_settings, m_pset, nullptr, this};
54
55 GUIApplicationInterface::loadPluginData(m_settings, *m_presenter);
56 }
57
58 ~MinimalApplication() override
59 {
60 this->setParent(nullptr);
61 // Drain the event queue BEFORE deleting the presenter: deferred slots
62 // queued during plugin load (e.g. Scenario::SearchWidget's deferred init
63 // → findDeviceExplorerWidgetInstance) read the presenter-owned application
64 // context, so dispatching them after delete m_presenter is a use-after-free.
65 QApplication::processEvents();
66 delete m_presenter;
67
68 // The settings models are QObjects owned by value members of this class;
69 // members destruct after this body, i.e. after the QApplication is gone,
70 // which Qt >= 6.11 does not survive. Take them down while the app lives.
71 m_settings.teardownModels();
72 m_app.reset();
73 }
74
75 const score::GUIApplicationContext& context() const override
76 {
77 return m_presenter->applicationContext();
78 }
79
80 const score::ApplicationComponents& components() const override
81 {
82 return context().components;
83 }
84
85 score::ApplicationComponentsData& componentsData()
86 {
87 return m_presenter->components();
88 }
89
90 int exec() { return m_app->exec(); }
91
92 // Declared first so it is destroyed last (after the settings members, whose
93 // models are parented to it).
94 std::unique_ptr<QApplication> m_app;
95 score::Settings m_settings;
97 score::Presenter* m_presenter{};
98 score::ApplicationSettings m_applicationSettings;
99};
100
102 : public QObject
104{
105public:
106 MinimalGUIApplication(int& argc, char** argv, bool show = true)
107 : QObject{nullptr}
108 , m_app{new QApplication{argc, argv}}
109 {
110 m_show = show;
111#if defined(SCORE_STATIC_PLUGINS)
112 score_init_static_plugins();
113#endif
114
115 m_instance = this;
116 this->setParent(m_app.get());
117
118 m_view = new score::View{nullptr};
119 m_presenter
120 = new score::Presenter{m_applicationSettings, m_settings, m_pset, m_view, this};
121
122 GUIApplicationInterface::loadPluginData(m_settings, *m_presenter);
123
124 if(m_show)
125 m_view->show();
126 }
127
128 ~MinimalGUIApplication() override
129 {
130 this->setParent(nullptr);
131 // Drain queued slots while m_presenter is still alive (see
132 // ~MinimalApplication): deferred plugin-load slots read the presenter-owned
133 // context — dispatching them after delete m_presenter is a use-after-free.
134 QApplication::processEvents();
135 delete m_presenter;
136
137 // See ~MinimalApplication: QObject settings models must not outlive the
138 // QApplication.
139 m_settings.teardownModels();
140 m_app.reset();
141 }
142
143 const score::GUIApplicationContext& context() const override
144 {
145 return m_presenter->applicationContext();
146 }
147
148 const score::ApplicationComponents& components() const override
149 {
150 return context().components;
151 }
152
153 score::ApplicationComponentsData& componentsData()
154 {
155 return m_presenter->components();
156 }
157
158 score::View& view() const { return *m_view; }
159
160 int exec() { return m_app->exec(); }
161
162 // Whether to show() the main window. Tests that only need a valid document
163 // presenter (not actual painting) can leave it hidden.
164 bool m_show{true};
165
166 // Declared first so it is destroyed last (after the settings members, whose
167 // models are parented to it).
168 std::unique_ptr<QApplication> m_app;
169 score::Settings m_settings;
171 score::View* m_view{};
172 score::Presenter* m_presenter{};
173 score::ApplicationSettings m_applicationSettings;
174};
175}
Definition ApplicationComponents.hpp:68
Definition ApplicationInterface.hpp:39
void loadPluginData(score::Settings &settings, score::Presenter &presenter)
loadPluginData Utility method to load the minimal required data for plug-ins.
Definition ApplicationInterface.cpp:86
Definition MinimalApplication.hpp:23
Definition MinimalApplication.hpp:104
The Presenter class.
Definition lib/core/presenter/Presenter.hpp:36
Definition lib/core/settings/Settings.hpp:77
Application-wide user settings registering and handling.
Definition lib/core/settings/Settings.hpp:42
void teardownModels() noexcept
Definition lib/core/settings/Settings.cpp:26
The main display of the application.
Definition lib/core/view/Window.hpp:41
Base toolkit upon which the software is built.
Definition Application.cpp:113
Definition ApplicationComponents.hpp:46
Load-time settings.
Definition ApplicationSettings.hpp:17
Specializes ApplicationContext with the QMainWindow.
Definition GUIApplicationContext.hpp:15
Definition MinimalApplication.hpp:26