diff --git a/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp b/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp index d95a0c51f9b..bf1d30bf23c 100644 --- a/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp +++ b/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp @@ -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 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("addEventListener", m_name, suspendResume->jsEventHandlerAt(m_eventHandlerIndex)); +} + +QWasmEventHandler::~QWasmEventHandler() +{ + QWasmSuspendResumeControl *suspendResume = QWasmSuspendResumeControl::get(); + Q_ASSERT(suspendResume); + m_element.call("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 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(timeout.count()); + ArgType timerId = val::global("window").call("setTimeout", jsHandler, timoutValue); + m_timerId = static_cast(std::round(timerId)); +} + +bool QWasmTimer::hasTimeout() +{ + return m_timerId > 0; +} + +void QWasmTimer::clearTimeout() +{ + val::global("window").call("clearTimeout", double(m_timerId)); + m_timerId = 0; +} diff --git a/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h b/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h index b8204ff1293..c500c40791a 100644 --- a/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h +++ b/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h @@ -8,6 +8,7 @@ #include #include #include +#include // // W A R N I N G @@ -46,4 +47,37 @@ private: std::map> 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 fn); + +private: + emscripten::val m_element; + emscripten::val m_name; + uint32_t m_eventHandlerIndex = 0; +}; + +class QWasmTimer +{ +public: + QWasmTimer(QWasmSuspendResumeControl* suspendResume, std::function 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