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>
This commit is contained in:
parent
7c54988b1b
commit
5958c28d9f
@ -151,7 +151,7 @@ void File::stream(uint32_t offset, uint32_t length, char *buffer, const std::fun
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
char *nextChunkBuffer = chunkBuffer + result.byteLength();
|
char *nextChunkBuffer = chunkBuffer + result.byteLength();
|
||||||
fileReader->onLoad([=]() { (*chunkCompleted)(nextChunkBegin, nextChunkBuffer); });
|
fileReader->onLoad([=](emscripten::val) { (*chunkCompleted)(nextChunkBegin, nextChunkBuffer); });
|
||||||
qstdweb::Blob blob = fileHandle.slice(nextChunkBegin, nextChunkEnd);
|
qstdweb::Blob blob = fileHandle.slice(nextChunkBegin, nextChunkEnd);
|
||||||
fileReader->readAsArrayBuffer(blob);
|
fileReader->readAsArrayBuffer(blob);
|
||||||
};
|
};
|
||||||
@ -203,17 +203,17 @@ void FileReader::readAsArrayBuffer(const Blob &blob) const
|
|||||||
m_fileReader.call<void>("readAsArrayBuffer", blob.m_blob);
|
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));
|
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));
|
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));
|
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
|
// 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".
|
// 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)
|
EventCallback::~EventCallback()
|
||||||
:m_fn(fn)
|
|
||||||
{
|
{
|
||||||
element.set(contextPropertyName(name).c_str(), emscripten::val(intptr_t(this)));
|
m_element.set(contextPropertyName(m_eventName).c_str(), emscripten::val::undefined());
|
||||||
element.set((std::string("on") + name).c_str(), emscripten::val::module_property("qtStdWebEventCallbackActivate"));
|
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)
|
void EventCallback::activate(emscripten::val event)
|
||||||
@ -317,7 +325,7 @@ void EventCallback::activate(emscripten::val event)
|
|||||||
emscripten::val target = event["target"];
|
emscripten::val target = event["target"];
|
||||||
std::string eventName = event["type"].as<std::string>();
|
std::string eventName = event["type"].as<std::string>();
|
||||||
EventCallback *that = reinterpret_cast<EventCallback *>(target[contextPropertyName(eventName).c_str()].as<intptr_t>());
|
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)
|
std::string EventCallback::contextPropertyName(const std::string &eventName)
|
||||||
|
@ -129,9 +129,9 @@ namespace qstdweb {
|
|||||||
ArrayBuffer result() const;
|
ArrayBuffer result() const;
|
||||||
void readAsArrayBuffer(const Blob &blob) const;
|
void readAsArrayBuffer(const Blob &blob) const;
|
||||||
|
|
||||||
void onLoad(const std::function<void ()> &onLoad);
|
void onLoad(const std::function<void(emscripten::val)> &onLoad);
|
||||||
void onError(const std::function<void ()> &onError);
|
void onError(const std::function<void(emscripten::val)> &onError);
|
||||||
void onAbort(const std::function<void ()> &onAbort);
|
void onAbort(const std::function<void(emscripten::val)> &onAbort);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
emscripten::val m_fileReader = emscripten::val::global("FileReader").new_();
|
emscripten::val m_fileReader = emscripten::val::global("FileReader").new_();
|
||||||
@ -166,11 +166,18 @@ namespace qstdweb {
|
|||||||
class EventCallback
|
class EventCallback
|
||||||
{
|
{
|
||||||
public:
|
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);
|
static void activate(emscripten::val event);
|
||||||
private:
|
private:
|
||||||
static std::string contextPropertyName(const std::string &eventName);
|
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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
// Note: there is no event in case the user cancels the file dialog.
|
||||||
static std::unique_ptr<qstdweb::EventCallback> changeEvent;
|
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));
|
changeEvent.reset(new qstdweb::EventCallback(input, "change", callback));
|
||||||
|
|
||||||
// Activate file input
|
// Activate file input
|
||||||
|
Loading…
x
Reference in New Issue
Block a user