I want to make async call to C++ native function, but have some problems: when I call native function in async block (in Promise, exactly), it blocks UI thread and no async call is made. I want to pass callback to C++ function and call it. How can I pass function object?
class frame : public sciter::window {
public:
frame() : window(SW_TITLEBAR | SW_RESIZEABLE | SW_CONTROLS | SW_MAIN | SW_ENABLE_DEBUG) {}
void assertion(const std::string& val)
{
stream << std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count()
<< ' '
<< val
<< '\n';
stream.flush();
}
void asyncFunction(::sciter::value callback)
{
std::thread{ [callback]()
{
std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // if I use it in same thread, it blocks UI thread and no async call is made
// call callback function
} }.detach();
}
SOM_PASSPORT_BEGIN(frame)
SOM_FUNCS(
SOM_FUNC(assertion),
SOM_FUNC(asyncFunction)
)
SOM_PASSPORT_END
private:
std::ofstream stream{ "log.txt" };
};
In this implementation I use another thread to make a logic. But if I want to return values (or notify, that call has completed), I need fire event (what I don't want to do, because logic will be spread on whole code) or call some sort of callback. sciter::value
have methods is_function_object
and is_function
, so, probably, I have opportinuty to cast value to the C++ function object. But how can I do this?
<html>
<head>
<title>Test</title>
</head>
<body>
<button #test>Assert</button>
<script>
function sleep(time) {
return new Promise(resolve => {
Window.this.frame.asyncFunction(function (result)
{
Window.this.frame.assertion(result);
resolve(result);
}); // resolve(Window.this.frame.asyncFunction()) blocks code execution until asyncFunction returns
});
}
async function answer() {
Window.this.frame.assertion("sleep start");
await sleep(5000);
Window.this.frame.assertion("sleep end");
return 50;
}
document.$("button#test").onclick = function () {
var p = answer();
p.then(result => { Window.this.frame.assertion("Ended: " + result) });
Window.this.frame.assertion("go next");
}
</script>
</body>
</html>