diff options
author | Morten Johan Sørvig <morten.sorvig@qt.io> | 2021-11-25 12:55:10 +0100 |
---|---|---|
committer | Morten Johan Sørvig <morten.sorvig@qt.io> | 2022-02-11 18:15:26 +0100 |
commit | 5958c28d9fbfa4432887e83e97defb76b0dda14d (patch) | |
tree | 9faa26b3110d60f819a19c8ec22895b9280cdbf4 /src | |
parent | 7c54988b1b3b9eb4d2f3650c1ba5ffe97673ca92 (diff) |
wasm: improve qstdweb::EventCallback
We are storing a copy of the this pointer in the constructor,
and later deference it to access EventCallback object
memebers. This makes the class noncopyable: delete
the copy constructor to make sure it isn’t.
Also change the callback API to propagate the event
to the event callback.
Change-Id: Ida4bb192b3e905b260ebeec30293aad71b7d8c49
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/platform/wasm/qstdweb.cpp | 26 | ||||
-rw-r--r-- | src/corelib/platform/wasm/qstdweb_p.h | 17 | ||||
-rw-r--r-- | src/gui/platform/wasm/qwasmlocalfileaccess.cpp | 2 |
3 files changed, 30 insertions, 15 deletions
diff --git a/src/corelib/platform/wasm/qstdweb.cpp b/src/corelib/platform/wasm/qstdweb.cpp index 2bbf57953b..e58447db1a 100644 --- a/src/corelib/platform/wasm/qstdweb.cpp +++ b/src/corelib/platform/wasm/qstdweb.cpp @@ -151,7 +151,7 @@ void File::stream(uint32_t offset, uint32_t length, char *buffer, const std::fun return; } char *nextChunkBuffer = chunkBuffer + result.byteLength(); - fileReader->onLoad([=]() { (*chunkCompleted)(nextChunkBegin, nextChunkBuffer); }); + fileReader->onLoad([=](emscripten::val) { (*chunkCompleted)(nextChunkBegin, nextChunkBuffer); }); qstdweb::Blob blob = fileHandle.slice(nextChunkBegin, nextChunkEnd); fileReader->readAsArrayBuffer(blob); }; @@ -203,17 +203,17 @@ void FileReader::readAsArrayBuffer(const Blob &blob) const m_fileReader.call<void>("readAsArrayBuffer", blob.m_blob); } -void FileReader::onLoad(const std::function<void ()> &onLoad) +void FileReader::onLoad(const std::function<void(emscripten::val)> &onLoad) { m_onLoad.reset(new EventCallback(m_fileReader, "load", onLoad)); } -void FileReader::onError(const std::function<void ()> &onError) +void FileReader::onError(const std::function<void(emscripten::val)> &onError) { m_onError.reset(new EventCallback(m_fileReader, "error", onError)); } -void FileReader::onAbort(const std::function<void ()> &onAbort) +void FileReader::onAbort(const std::function<void(emscripten::val)> &onAbort) { m_onAbort.reset(new EventCallback(m_fileReader, "abort", onAbort)); } @@ -305,11 +305,19 @@ emscripten::val Uint8Array::constructor_() // Registers a callback function for a named event on the given element. The event // name must be the name as returned by the Event.type property: e.g. "load", "error". -EventCallback::EventCallback(emscripten::val element, const std::string &name, const std::function<void ()> &fn) -:m_fn(fn) +EventCallback::~EventCallback() { - element.set(contextPropertyName(name).c_str(), emscripten::val(intptr_t(this))); - element.set((std::string("on") + name).c_str(), emscripten::val::module_property("qtStdWebEventCallbackActivate")); + m_element.set(contextPropertyName(m_eventName).c_str(), emscripten::val::undefined()); + m_element.set((std::string("on") + m_eventName).c_str(), emscripten::val::undefined()); +} + +EventCallback::EventCallback(emscripten::val element, const std::string &name, const std::function<void(emscripten::val)> &fn) + :m_element(element) + ,m_eventName(name) + ,m_fn(fn) +{ + m_element.set(contextPropertyName(m_eventName).c_str(), emscripten::val(intptr_t(this))); + m_element.set((std::string("on") + m_eventName).c_str(), emscripten::val::module_property("qtStdWebEventCallbackActivate")); } void EventCallback::activate(emscripten::val event) @@ -317,7 +325,7 @@ void EventCallback::activate(emscripten::val event) emscripten::val target = event["target"]; std::string eventName = event["type"].as<std::string>(); EventCallback *that = reinterpret_cast<EventCallback *>(target[contextPropertyName(eventName).c_str()].as<intptr_t>()); - that->m_fn(); + that->m_fn(event); } std::string EventCallback::contextPropertyName(const std::string &eventName) diff --git a/src/corelib/platform/wasm/qstdweb_p.h b/src/corelib/platform/wasm/qstdweb_p.h index 9d5e2418ec..cd3f029860 100644 --- a/src/corelib/platform/wasm/qstdweb_p.h +++ b/src/corelib/platform/wasm/qstdweb_p.h @@ -129,9 +129,9 @@ namespace qstdweb { ArrayBuffer result() const; void readAsArrayBuffer(const Blob &blob) const; - void onLoad(const std::function<void ()> &onLoad); - void onError(const std::function<void ()> &onError); - void onAbort(const std::function<void ()> &onAbort); + void onLoad(const std::function<void(emscripten::val)> &onLoad); + void onError(const std::function<void(emscripten::val)> &onError); + void onAbort(const std::function<void(emscripten::val)> &onAbort); private: emscripten::val m_fileReader = emscripten::val::global("FileReader").new_(); @@ -166,11 +166,18 @@ namespace qstdweb { class EventCallback { public: - EventCallback(emscripten::val element, const std::string &name, const std::function<void ()> &fn); + EventCallback() = default; + ~EventCallback(); + EventCallback(EventCallback const&) = delete; + EventCallback& operator=(EventCallback const&) = delete; + EventCallback(emscripten::val element, const std::string &name, + const std::function<void(emscripten::val)> &fn); static void activate(emscripten::val event); private: static std::string contextPropertyName(const std::string &eventName); - std::function<void ()> m_fn; + emscripten::val m_element = emscripten::val::undefined(); + std::string m_eventName; + std::function<void(emscripten::val)> m_fn; }; } diff --git a/src/gui/platform/wasm/qwasmlocalfileaccess.cpp b/src/gui/platform/wasm/qwasmlocalfileaccess.cpp index 76e9c6c519..cd1c26c72e 100644 --- a/src/gui/platform/wasm/qwasmlocalfileaccess.cpp +++ b/src/gui/platform/wasm/qwasmlocalfileaccess.cpp @@ -96,7 +96,7 @@ void openFileDialog(const std::string &accept, FileSelectMode fileSelectMode, // Note: there is no event in case the user cancels the file dialog. static std::unique_ptr<qstdweb::EventCallback> changeEvent; - auto callback = [=]() { filesSelected(qstdweb::FileList(input["files"])); }; + auto callback = [=](emscripten::val) { filesSelected(qstdweb::FileList(input["files"])); }; changeEvent.reset(new qstdweb::EventCallback(input, "change", callback)); // Activate file input |