mirror of
https://github.com/cookiengineer/audacity
synced 2025-04-29 23:29:41 +02:00
Define CallAfter and Yield in BasicUI...
...so direct uses of wx/app.h may later be removed. That header is one of the files that is in wxBase, but is not acceptable in "toolkit neutral" code, which should not directly use any version of an event loop. Original commit: 50e8139716388f55b11abecb1fc46cbfcd38e247 Signed-off-by: Panagiotis Vasilopoulos <hello@alwayslivid.com>
This commit is contained in:
parent
2d0394796e
commit
e5cffb7620
@ -9,6 +9,9 @@ Paul Licameli
|
||||
**********************************************************************/
|
||||
#include "BasicUI.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace BasicUI {
|
||||
Services::~Services() = default;
|
||||
|
||||
@ -22,4 +25,40 @@ Services *Install(Services *pInstance)
|
||||
theInstance = pInstance;
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::recursive_mutex sActionsMutex;
|
||||
static std::vector<Action> sActions;
|
||||
|
||||
void CallAfter(Action action)
|
||||
{
|
||||
if (auto p = Get())
|
||||
p->DoCallAfter(action);
|
||||
else {
|
||||
// No services yet -- but don't lose the action. Put it in a queue
|
||||
auto guard = std::lock_guard{ sActionsMutex };
|
||||
sActions.emplace_back(std::move(action));
|
||||
}
|
||||
}
|
||||
|
||||
void Yield()
|
||||
{
|
||||
do {
|
||||
// Dispatch anything in the queue, added while there were no Services
|
||||
{
|
||||
auto guard = std::lock_guard{ sActionsMutex };
|
||||
std::vector<Action> actions;
|
||||
actions.swap(sActions);
|
||||
for (auto &action : actions)
|
||||
action();
|
||||
}
|
||||
|
||||
// Dispatch according to Services, if present
|
||||
if (auto p = Get())
|
||||
p->DoYield();
|
||||
}
|
||||
// Re-test for more actions that might have been enqueued by actions just
|
||||
// dispatched
|
||||
while ( !sActions.empty() );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,14 +8,18 @@ Audacity: A Digital Audio Editor
|
||||
Paul Licameli
|
||||
|
||||
**********************************************************************/
|
||||
#ifndef __AUDACITY_BASIC_UI__
|
||||
#define __AUDACITY_BASIC_UI__
|
||||
#ifndef __TENACITY_BASIC_UI__
|
||||
#define __TENACITY_BASIC_UI__
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace BasicUI {
|
||||
|
||||
//! @name Types used in the Services interface
|
||||
//! @{
|
||||
|
||||
using Action = std::function<void()>;
|
||||
|
||||
//! @}
|
||||
|
||||
//! Abstract class defines a few user interface services, not mentioning particular toolkits
|
||||
@ -25,6 +29,8 @@ namespace BasicUI {
|
||||
class BASIC_UI_API Services {
|
||||
public:
|
||||
virtual ~Services();
|
||||
virtual void DoCallAfter(const Action &action) = 0;
|
||||
virtual void DoYield() = 0;
|
||||
};
|
||||
|
||||
//! Fetch the global instance, or nullptr if none is yet installed
|
||||
@ -40,6 +46,21 @@ BASIC_UI_API Services *Install(Services *pInstance);
|
||||
*/
|
||||
//! @{
|
||||
|
||||
//! Schedule an action to be done later, and in the main thread
|
||||
/*! This function may be called in other threads than the main. If no Services
|
||||
are yet installed, the action is not lost, but may be dispatched by Yield().
|
||||
The action may itself invoke CallAfter to enqueue other actions.
|
||||
*/
|
||||
void CallAfter(Action action);
|
||||
|
||||
//! Dispatch waiting events, including actions enqueued by CallAfter
|
||||
/*! This function must be called by the main thread. Actions enqueued by
|
||||
CallAfter before Services were installed will be dispatched in the sequence
|
||||
they were enqueued, unless an exception thrown by one of them stops the
|
||||
dispatching.
|
||||
*/
|
||||
void Yield();
|
||||
|
||||
//! @}
|
||||
}
|
||||
|
||||
|
@ -8,5 +8,18 @@ Paul Licameli
|
||||
|
||||
**********************************************************************/
|
||||
#include "wxWidgetsBasicUI.h"
|
||||
#include <wx/app.h>
|
||||
|
||||
using namespace BasicUI;
|
||||
|
||||
wxWidgetsBasicUI::~wxWidgetsBasicUI() = default;
|
||||
|
||||
void wxWidgetsBasicUI::DoCallAfter(const Action &action)
|
||||
{
|
||||
wxTheApp->CallAfter(action);
|
||||
}
|
||||
|
||||
void wxWidgetsBasicUI::DoYield()
|
||||
{
|
||||
wxTheApp->Yield();
|
||||
}
|
||||
|
@ -18,6 +18,9 @@ Paul Licameli
|
||||
class wxWidgetsBasicUI final : public BasicUI::Services {
|
||||
public:
|
||||
~wxWidgetsBasicUI() override;
|
||||
|
||||
void DoCallAfter(const BasicUI::Action &action) override;
|
||||
void DoYield() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user