WebView async RunScript

78 views
Skip to first unread message

Tobias T

unread,
Apr 6, 2021, 4:21:53 AM4/6/21
to wx-dev
Hi,
not only as a solution to #19075 (where RunScript hangs from edge event callbacks), I was thinking about implementing an asynchronous RunScript, as all underlying backends (except for maybe IE) already implement it as such and we just force it to be syncronous.

My current idea would be a RunScriptAsync() method and an event like wxWEBVIEWVIEW_SCRIPT_RESULT to deliver the result. The method would have to take at least an id as an additional argument so the event can have a correlation to the RunScriptAsync() call.

It would of course be nice to have some sort of direct lambda support, but I think for the sake of consistency it wouldn't make sense. 

Any ideas feedback would be welcome, before starting on this.

Regards,
Tobias

Vadim Zeitlin

unread,
Apr 6, 2021, 5:06:33 AM4/6/21
to wx-...@googlegroups.com
On Tue, 6 Apr 2021 01:21:53 -0700 (PDT) Tobias T wrote:

TT> Hi,
TT> not only as a solution to #19075 <https://trac.wxwidgets.org/ticket/19075>
TT> (where RunScript hangs from edge event callbacks), I was thinking about
TT> implementing an asynchronous RunScript, as all underlying backends
TT> (except for maybe IE) already implement it as such and we just force it to
TT> be syncronous.
TT>
TT> My current idea would be a *RunScriptAsync()* method and an event like
TT> *wxWEBVIEWVIEW_SCRIPT_RESULT* to deliver the result. The method would have
TT> to take at least an id as an additional argument so the event can have a
TT> correlation to the *RunScriptAsync()* call.

This definitely makes sense to me. The only question I have is about the
error handling: would it make sense to treat the case when the script
execution throws an exception specially, perhaps?

TT> It would of course be nice to have some sort of direct lambda support, but
TT> I think for the sake of consistency it wouldn't make sense.

Using Bind() with a lambda is not that bad of a substitute, but if we really
wanted, we could provide a simple wrapper function doing it, i.e. binding
the lambda, calling RunScriptAsync(), and then unbinding it.

Thanks in advance!
VZ

Tobias T

unread,
Apr 7, 2021, 4:45:06 PM4/7/21
to wx-dev
I've added a draft PR with my current idea/implementation start:


This definitely makes sense to me. The only question I have is about the
error handling: would it make sense to treat the case when the script
execution throws an exception specially, perhaps?


I've implemented the success via GetInt() in the new event. Might make sense to provide a convince IsError() or similar.

TT> It would of course be nice to have some sort of direct lambda support, but
TT> I think for the sake of consistency it wouldn't make sense.

Using Bind() with a lambda is not that bad of a substitute, but if we really
wanted, we could provide a simple wrapper function doing it, i.e. binding
the lambda, calling RunScriptAsync(), and then unbinding it.


That kind of wrapper sounds interesting but I'm not sure how that would be implemented (named/defined).

Vadim Zeitlin

unread,
Apr 7, 2021, 7:48:23 PM4/7/21
to wx-...@googlegroups.com
On Wed, 7 Apr 2021 13:45:06 -0700 (PDT) Tobias T wrote:

TT> I've added a draft PR with my current idea/implementation start:
TT> https://github.com/wxWidgets/wxWidgets/pull/2316

Thanks, I'll look at it a.s.a.p. but probably after 3.1.5 release, as this
won't make it into it (unless you really want it to?).

TT> I've implemented the success via GetInt() in the new event. Might make
TT> sense to provide a convince IsError() or similar.

Yes, I think a wrapper like this would be nice.

TT> TT> It would of course be nice to have some sort of direct lambda support,
TT> TT> but I think for the sake of consistency it wouldn't make sense.
TT> >
TT> > Using Bind() with a lambda is not that bad of a substitute, but if we
TT> > really wanted, we could provide a simple wrapper function doing it,
TT> > i.e. binding the lambda, calling RunScriptAsync(), and then unbinding
TT> > it.
TT> >
TT> That kind of wrapper sounds interesting but I'm not sure how that would
TT> be implemented (named/defined).

In pseudo code just like what I described in English above, i.e.

void RunScriptAsync(
const wxString& script,
const std::function<void (wxWebViewEvent&)> handler)
{
Bind(wxEVT_WEBVIEW_SCRIPT_RESULT,
[this, handler](wxWebViewEvent& e)
{
handler(e);
Unbind(wxEVT_WEBVIEW_SCRIPT_RESULT);
});
}

Except for the questions of lifetimes, I don't see why wouldn't this work?
VZ

Tobias T

unread,
Apr 8, 2021, 3:28:52 AM4/8/21
to wx-dev
VZ schrieb am Donnerstag, 8. April 2021 um 01:48:23 UTC+2:
On Wed, 7 Apr 2021 13:45:06 -0700 (PDT) Tobias T wrote:

TT> I've added a draft PR with my current idea/implementation start:
TT> https://github.com/wxWidgets/wxWidgets/pull/2316

Thanks, I'll look at it a.s.a.p. but probably after 3.1.5 release, as this
won't make it into it (unless you really want it to?).

No need to rush, this can certainly wait till after 3.1.5 (with the current timeframe) and I'm not even sure when I'll be done with it.
 

In pseudo code just like what I described in English above, i.e.

void RunScriptAsync(
const wxString& script,
const std::function<void (wxWebViewEvent&)> handler)
{
Bind(wxEVT_WEBVIEW_SCRIPT_RESULT,
[this, handler](wxWebViewEvent& e)
{
handler(e);
Unbind(wxEVT_WEBVIEW_SCRIPT_RESULT);
});
}

I'm not sure how to handle parallel running calls this way, but my idea would be to use a unique id for each call/Bind.
 
Reply all
Reply to author
Forward
0 new messages