Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions application_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,9 @@ void ApplicationManager::exec()
app->exit(status);
});

QTimer* main_timer = new QTimer(m_engine);
main_timer->setInterval(0);
QObject::connect(main_timer, &QTimer::timeout, [this]
{
GCGuard gc_guard;
m_event_hook();
});
main_timer->start();
m_event_loop_updater = new EventLoopUpdater(m_engine, jl_get_function(m_qml_mod, "process_eventloop_updates"));

ForeignThreadManager::instance(); // Make sure the main thread is put in GC safe mode
const int status = app->exec();
if (status != 0)
{
Expand All @@ -119,7 +113,13 @@ void ApplicationManager::add_import_path(std::string path)
m_import_paths.push_back(path);
}

ApplicationManager::ApplicationManager() : m_event_hook(jl_get_function(m_qml_mod, "process_eventloop_updates"))
void ApplicationManager::queue_process_eventloop_updates()
{
assert(m_event_loop_updater != nullptr);
QMetaObject::invokeMethod(m_event_loop_updater, [this]{ m_event_loop_updater->process_eventloop_updates(); }, Qt::QueuedConnection);
}

ApplicationManager::ApplicationManager()
{
if(QProcessEnvironment::systemEnvironment().contains("QSG_RENDER_LOOP"))
{
Expand Down Expand Up @@ -147,6 +147,7 @@ void ApplicationManager::cleanup()
delete JuliaSingleton::s_singletonInstance;
JuliaSingleton::s_singletonInstance = nullptr;
ForeignThreadManager::instance().cleanup();
m_event_loop_updater = nullptr;
}

void ApplicationManager::check_no_engine()
Expand Down Expand Up @@ -177,4 +178,14 @@ void ApplicationManager::process_events()

jl_module_t* ApplicationManager::m_qml_mod = nullptr;

EventLoopUpdater::EventLoopUpdater(QObject *parent, jl_value_t *f) : QObject(parent), m_process_eventloop_updates(f)
{
}

void EventLoopUpdater::process_eventloop_updates()
{
GCGuard gc_guard;
m_process_eventloop_updates();
}

}
16 changes: 15 additions & 1 deletion application_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@
namespace qmlwrap
{

/// Helper to invoke a Julia function inside the main event loop
class EventLoopUpdater : public QObject
{
Q_OBJECT
public:
EventLoopUpdater(QObject* parent, jl_value_t* f);
void process_eventloop_updates();

private:
jlcxx::JuliaFunction m_process_eventloop_updates;
};

/// Manage creation and destruction of the application and the QML engine,
class ApplicationManager
{
Expand All @@ -45,6 +57,8 @@ class ApplicationManager

void add_import_path(std::string path);

void queue_process_eventloop_updates();

static void process_events();

static jl_module_t* m_qml_mod;
Expand All @@ -60,7 +74,7 @@ class ApplicationManager
QQmlEngine* m_engine = nullptr;
QQmlContext* m_root_ctx = nullptr;
std::vector<std::string> m_import_paths;
jlcxx::JuliaFunction m_event_hook;
EventLoopUpdater* m_event_loop_updater = nullptr;
};

}
Expand Down
6 changes: 6 additions & 0 deletions foreign_thread_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ void ForeignThreadManager::end_julia()
}
}

void ForeignThreadManager::yield()
{
end_julia();
begin_julia();
}

void ForeignThreadManager::cleanup()
{
if(!QThread::isMainThread())
Expand Down
2 changes: 2 additions & 0 deletions foreign_thread_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class ForeignThreadManager
void begin_julia();
void end_julia();

void yield();

// Remove the current instance, to be called after exec finishes.
void cleanup();

Expand Down
1 change: 1 addition & 0 deletions makie_viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ void MakieViewport::setup_buffer(QOpenGLFramebufferObject* fbo)

connect(window(), &QQuickWindow::sceneGraphInvalidated, [this] ()
{
GCGuard gc_guard;
MakieSupport::instance().on_context_destroy(m_screen);
});
}
Expand Down
16 changes: 14 additions & 2 deletions wrap_qml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,7 @@ JLCXX_MODULE define_julia_module(jlcxx::Module& qml_module)
});

qml_module.add_type<QSize>("QSize")
.constructor<int,int>()
.method("width", &QSize::width)
.method("height", &QSize::height);

Expand Down Expand Up @@ -780,10 +781,20 @@ JLCXX_MODULE define_julia_module(jlcxx::Module& qml_module)
qml_module.method("app_exec", []() { qmlwrap::ApplicationManager::instance().exec(); });
qml_module.method("process_events", qmlwrap::ApplicationManager::process_events);
qml_module.method("add_import_path", [](std::string path) { qmlwrap::ApplicationManager::instance().add_import_path(path); });
qml_module.method("queue_process_eventloop_updates", []() { qmlwrap::ApplicationManager::instance().queue_process_eventloop_updates(); });

qml_module.method("yield", []() { qmlwrap::ForeignThreadManager::instance().yield(); });

qml_module.add_type<QTimer>("QTimer", julia_base_type<QObject>())
.constructor<QObject*>()
.method("setInterval", static_cast<void(QTimer::*)(int)>(&QTimer::setInterval))
.method("start", [] (QTimer& t) { t.start(); } )
.method("stop", &QTimer::stop);
.method("stop", &QTimer::stop)
.method("callOnTimeout", [] (QTimer& t, jl_value_t* julia_function)
{
JuliaFunction f(julia_function);
t.callOnTimeout([f] () { f(); });
});

// Emit signals helper
qml_module.method("emit", [](const char *signal_name, const QVariantList& args) {
Expand Down Expand Up @@ -999,7 +1010,8 @@ JLCXX_MODULE define_julia_module(jlcxx::Module& qml_module)
.method("copy", static_cast<QImage (QImage::*) (int,int,int,int) const>(&QImage::copy))
.method("copy", [] (const QImage& i) { return i.copy(); } )
.method("height", &QImage::height)
.method("width", &QImage::width);
.method("width", &QImage::width)
.method("fill", static_cast<void (QImage::*) (const QColor&)>(&QImage::fill));

qml_module.add_type<QPixmap>("QPixmap", julia_base_type<QPaintDevice>())
.constructor<const char *const[] >()
Expand Down
Loading