@@ -27,10 +27,27 @@ using namespace KDFoundation;
2727
2828CoreApplication *CoreApplication::ms_application = nullptr ;
2929
30- CoreApplication::CoreApplication (std::unique_ptr<AbstractPlatformIntegration> &&platformIntegration)
30+ namespace {
31+ std::unique_ptr<AbstractPlatformIntegration> createPlatformIntegration ()
32+ {
33+ // Create a platform integration
34+ #if defined(PLATFORM_LINUX)
35+ return std::make_unique<LinuxPlatformIntegration>();
36+ #elif defined(PLATFORM_WIN32)
37+ return std::make_unique<Win32PlatformIntegration>();
38+ #elif defined(PLATFORM_MACOS)
39+ return std::make_unique<MacOSPlatformIntegration>();
40+ #else
41+ static_assert (false , " No valid platform integration could be found." );
42+ #endif
43+ }
44+ } // namespace
45+
46+ CoreApplication::CoreApplication (std::unique_ptr<AbstractPlatformIntegration> &&platformIntegration, std::unique_ptr<KDFoundation::AbstractPlatformEventLoop> &&platformEventLoop)
3147 : m_defaultLogger{ KDUtils::Logger::logger (" default_log" , spdlog::level::info) }
32- , m_platformIntegration{ std::move (platformIntegration) }
48+ , m_platformIntegration{ platformIntegration ? std::move (platformIntegration) : createPlatformIntegration ( ) }
3349 , m_logger{ KDUtils::Logger::logger (" core_application" ) }
50+ , m_eventLoop{ platformEventLoop ? std::move (platformEventLoop) : m_platformIntegration->createPlatformEventLoop () }
3451{
3552 assert (ms_application == nullptr );
3653 ms_application = this ;
@@ -41,25 +58,7 @@ CoreApplication::CoreApplication(std::unique_ptr<AbstractPlatformIntegration> &&
4158 if (const char *display = std::getenv (" DISPLAY" )) // NOLINT(concurrency-mt-unsafe)
4259 SPDLOG_LOGGER_INFO (m_logger, " DISPLAY={}" , display);
4360
44- // Create a default postman object
45- m_postman = std::make_unique<Postman>();
46-
47- // Create a platform integration
48- if (!m_platformIntegration) {
49- #if defined(PLATFORM_LINUX)
50- m_platformIntegration = std::make_unique<LinuxPlatformIntegration>();
51- #elif defined(PLATFORM_WIN32)
52- m_platformIntegration = std::make_unique<Win32PlatformIntegration>();
53- #elif defined(PLATFORM_MACOS)
54- m_platformIntegration = std::make_unique<MacOSPlatformIntegration>();
55- #endif
56- }
57-
58- // Ask the platform integration to create us a suitable event loop
59- assert (m_platformIntegration);
60- m_platformEventLoop = m_platformIntegration->createPlatformEventLoop ();
6161 m_platformIntegration->init ();
62- m_platformEventLoop->setPostman (m_postman.get ());
6362}
6463
6564CoreApplication::~CoreApplication ()
@@ -68,60 +67,34 @@ CoreApplication::~CoreApplication()
6867 // and immediately return after processing events (timeout = 0).
6968 processEvents (0 );
7069
71- // Destroy the event loop and platform integration before removing the app instance
72- m_platformEventLoop = std::unique_ptr<AbstractPlatformEventLoop>();
73- m_platformIntegration = std::unique_ptr<AbstractPlatformIntegration>();
70+ // Destroy the platform integration before removing the app instance
71+ m_platformIntegration.reset ();
7472 ms_application = nullptr ;
7573}
7674
7775std::shared_ptr<KDBindings::ConnectionEvaluator> CoreApplication::connectionEvaluator ()
7876{
79- return eventLoop ()-> connectionEvaluator ();
77+ return m_eventLoop. connectionEvaluator ();
8078}
8179
8280void CoreApplication::postEvent (EventReceiver *target, std::unique_ptr<Event> &&event)
8381{
84- assert (target != nullptr );
85- assert (event->type () != Event::Type::Invalid);
86- m_eventQueue.push (target, std::forward<std::unique_ptr<Event>>(event));
87- m_platformEventLoop->wakeUp ();
82+ m_eventLoop.postEvent (target, std::forward<std::unique_ptr<Event>>(event));
8883}
8984
9085void CoreApplication::sendEvent (EventReceiver *target, Event *event)
9186{
92- SPDLOG_LOGGER_TRACE (m_logger, " {}()" , __FUNCTION__);
93- m_postman->deliverEvent (target, event);
87+ m_eventLoop.sendEvent (target, event);
9488}
9589
9690void CoreApplication::processEvents (int timeout)
9791{
98- // Deliver any events that have already been posted
99- for (size_t eventIndex = 0 , eventCount = m_eventQueue.size (); eventIndex < eventCount; ++eventIndex) {
100- auto postedEvent = m_eventQueue.tryPop ();
101- if (!postedEvent)
102- break ;
103- const auto target = postedEvent->target ();
104- const auto ev = postedEvent->wrappedEvent ();
105-
106- m_postman->deliverEvent (target, ev);
107- }
108-
109- // Poll/wait for new events
110- if (!m_platformEventLoop)
111- return ;
112- m_platformEventLoop->waitForEvents (timeout);
92+ m_eventLoop.processEvents (timeout);
11393}
11494
11595int CoreApplication::exec ()
11696{
117- if (!m_platformEventLoop)
118- return 1 ;
119-
120- while (!m_quitRequested)
121- processEvents (-1 );
122- m_quitRequested = false ;
123-
124- return 0 ;
97+ return m_eventLoop.exec ();
12598}
12699
127100void CoreApplication::quit ()
@@ -137,12 +110,7 @@ AbstractPlatformIntegration *CoreApplication::platformIntegration()
137110void CoreApplication::event (EventReceiver *target, Event *event)
138111{
139112 if (event->type () == Event::Type::Quit) {
140- // After setting the quit flag to true, we must wake up the event loop once more,
141- // because processEvents() goes back into waitForEvents() after processing the
142- // queued events. Without the wakeUp() call it would wait until some other event
143- // woke it up again. Let's kick it ourselves.
144- m_quitRequested = true ;
145- m_platformEventLoop->wakeUp ();
113+ m_eventLoop.quit ();
146114 event->setAccepted (true );
147115 }
148116
0 commit comments