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_BINDINGS(qtSuspendResumeControl) {
|
||||||
emscripten::function("qtSendPendingEvents", qtSendPendingEvents QT_WASM_EMSCRIPTEN_ASYNC);
|
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 <emscripten/val.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
//
|
//
|
||||||
// W A R N I N G
|
// W A R N I N G
|
||||||
@ -46,4 +47,37 @@ private:
|
|||||||
std::map<int, std::function<void(emscripten::val)>> m_eventHandlers;
|
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
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user