wasm: add native event and timer helpers
These build on QWasmSuspendResumeControl and provide support for registering C++ event handlers and native timer callbacks. Change-Id: I8370f91e42b3992ff7864e847efb9c225010e718 Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io>
This commit is contained in:
parent
3c72f99770
commit
de2a29a1fe
@ -164,3 +164,71 @@ void qtSendPendingEvents()
|
||||
EMSCRIPTEN_BINDINGS(qtSuspendResumeControl) {
|
||||
emscripten::function("qtSendPendingEvents", qtSendPendingEvents QT_WASM_EMSCRIPTEN_ASYNC);
|
||||
}
|
||||
|
||||
//
|
||||
// The EventCallback class registers a callback function for an event on an html element.
|
||||
//
|
||||
QWasmEventHandler::QWasmEventHandler(emscripten::val element, const std::string &name, std::function<void(emscripten::val)> handler)
|
||||
:m_element(element)
|
||||
,m_name(name)
|
||||
{
|
||||
QWasmSuspendResumeControl *suspendResume = QWasmSuspendResumeControl::get();
|
||||
Q_ASSERT(suspendResume); // must construct the event dispatcher or platform integration first
|
||||
m_eventHandlerIndex = suspendResume->registerEventHandler(std::move(handler));
|
||||
m_element.call<void>("addEventListener", m_name, suspendResume->jsEventHandlerAt(m_eventHandlerIndex));
|
||||
}
|
||||
|
||||
QWasmEventHandler::~QWasmEventHandler()
|
||||
{
|
||||
QWasmSuspendResumeControl *suspendResume = QWasmSuspendResumeControl::get();
|
||||
Q_ASSERT(suspendResume);
|
||||
m_element.call<void>("removeEventListener", m_name, suspendResume->jsEventHandlerAt(m_eventHandlerIndex));
|
||||
suspendResume->removeEventHandler(m_eventHandlerIndex);
|
||||
}
|
||||
|
||||
//
|
||||
// The QWasmTimer class creates a native single-shot timer. The event handler is provided in the
|
||||
// constructor and can be reused: each call setTimeout() sets a new timeout, though with the
|
||||
// limitiation that there can be only one timeout at a time. (Setting a new timer clears the
|
||||
// previous one).
|
||||
//
|
||||
QWasmTimer::QWasmTimer(QWasmSuspendResumeControl *suspendResume, std::function<void()> handler)
|
||||
:m_suspendResume(suspendResume)
|
||||
{
|
||||
auto wrapper = [handler = std::move(handler), this](val argument) {
|
||||
Q_UNUSED(argument); // no argument for timers
|
||||
Q_ASSERT(m_timerId);
|
||||
m_timerId = 0;
|
||||
handler();
|
||||
};
|
||||
|
||||
m_handlerIndex = m_suspendResume->registerEventHandler(std::move(wrapper));
|
||||
}
|
||||
|
||||
QWasmTimer::~QWasmTimer()
|
||||
{
|
||||
clearTimeout();
|
||||
m_suspendResume->removeEventHandler(m_handlerIndex);
|
||||
}
|
||||
|
||||
void QWasmTimer::setTimeout(std::chrono::milliseconds timeout)
|
||||
{
|
||||
if (hasTimeout())
|
||||
clearTimeout();
|
||||
val jsHandler = QWasmSuspendResumeControl::get()->jsEventHandlerAt(m_handlerIndex);
|
||||
using ArgType = double; // emscripten::val::call() does not support int64_t
|
||||
ArgType timoutValue = static_cast<ArgType>(timeout.count());
|
||||
ArgType timerId = val::global("window").call<ArgType>("setTimeout", jsHandler, timoutValue);
|
||||
m_timerId = static_cast<int64_t>(std::round(timerId));
|
||||
}
|
||||
|
||||
bool QWasmTimer::hasTimeout()
|
||||
{
|
||||
return m_timerId > 0;
|
||||
}
|
||||
|
||||
void QWasmTimer::clearTimeout()
|
||||
{
|
||||
val::global("window").call<void>("clearTimeout", double(m_timerId));
|
||||
m_timerId = 0;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <emscripten/val.h>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <chrono>
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
@ -46,4 +47,37 @@ private:
|
||||
std::map<int, std::function<void(emscripten::val)>> m_eventHandlers;
|
||||
};
|
||||
|
||||
class Q_CORE_EXPORT QWasmEventHandler
|
||||
{
|
||||
public:
|
||||
QWasmEventHandler() = default;
|
||||
~QWasmEventHandler();
|
||||
QWasmEventHandler(QWasmEventHandler const&) = delete;
|
||||
QWasmEventHandler& operator=(QWasmEventHandler const&) = delete;
|
||||
QWasmEventHandler(emscripten::val element, const std::string &name,
|
||||
std::function<void(emscripten::val)> fn);
|
||||
|
||||
private:
|
||||
emscripten::val m_element;
|
||||
emscripten::val m_name;
|
||||
uint32_t m_eventHandlerIndex = 0;
|
||||
};
|
||||
|
||||
class QWasmTimer
|
||||
{
|
||||
public:
|
||||
QWasmTimer(QWasmSuspendResumeControl* suspendResume, std::function<void()> handler);
|
||||
~QWasmTimer();
|
||||
QWasmTimer(QWasmTimer const&) = delete;
|
||||
QWasmTimer& operator=(QWasmTimer const&) = delete;
|
||||
void setTimeout(std::chrono::milliseconds timeout);
|
||||
bool hasTimeout();
|
||||
void clearTimeout();
|
||||
|
||||
private:
|
||||
QWasmSuspendResumeControl *m_suspendResume;
|
||||
uint32_t m_handlerIndex;
|
||||
uint64_t m_timerId = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user