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