New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use callbacks for bindings to enable async behavior #2
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is demystifying!
@@ -135,7 +135,8 @@ class WebView | |||
void navigate (const std::string& url); | |||
|
|||
/// A callback function which can be passed to bind(). | |||
using CallbackFn = std::function<choc::value::Value(const choc::value::ValueView& args)>; | |||
using ReplyFn = std::function<void(choc::value::Value, std::string)>; | |||
using CallbackFn = std::function<void(const choc::value::ValueView& args, ReplyFn&& reply)>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clarifying question: in this new world, all functions would be required to call reply
(at their leisure), and not be required to return anything. is that right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right!
@@ -135,7 +135,8 @@ class WebView | |||
void navigate (const std::string& url); | |||
|
|||
/// A callback function which can be passed to bind(). | |||
using CallbackFn = std::function<choc::value::Value(const choc::value::ValueView& args)>; | |||
using ReplyFn = std::function<void(choc::value::Value, std::string)>; | |||
using CallbackFn = std::function<void(const choc::value::ValueView& args, ReplyFn&& reply)>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-blocking thought: I wonder if it's worth supporting both synchronous and async bind()
calls. If this were to get upstreamed I think that would be necessary. Maybe have a separate bindWithAsyncReply()
method.
That would make the implementation a little more complex, but you should be able to do something like:
// Pseudocode
using CallbackFn = std::function<choc::value::Value(const choc::value::ValueView& args)>;
using AsyncCallbackFn = std::function<void(const choc::value::ValueView& args, ReplyFn&& reply)>;
// ...
unordered_map<string, variant<CallbackFn, AsyncCallbackFn>> bindings;
// ...
invokeBinding() {
if (holds_alternative<CallbackFn>(b)) {
doSynchronousCallback();
} else {
doAsyncCallback();
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So pumped about this! really solid solution 🔥
Turns this:
into this
This leans into the already async behavior of choc's binding stuff, using a lambda to enable an async implementation that calls back when it has its value ready (i.e. after a bg thread has finished doing some work). This keeps the sync behavior already have, for cases where we need it, by just synchronously calling the replyFn when we have our value.