mirror of
https://github.com/wgh136/flutter_qjs.git
synced 2025-09-27 13:27:24 +00:00
add function channel
This commit is contained in:
@@ -3,16 +3,17 @@
|
||||
* @Author: ekibun
|
||||
* @Date: 2020-08-07 13:55:52
|
||||
* @LastEditors: ekibun
|
||||
* @LastEditTime: 2020-08-13 13:47:16
|
||||
* @LastEditTime: 2020-08-15 14:45:00
|
||||
*/
|
||||
#pragma once
|
||||
#include "quickjspp/quickjspp.hpp"
|
||||
#include "quickjspp/quickjs/list.h"
|
||||
#include <future>
|
||||
#include <string.h>
|
||||
|
||||
namespace qjs
|
||||
{
|
||||
#include "quickjspp/quickjs/list.h"
|
||||
|
||||
static JSClassID js_dart_promise_class_id;
|
||||
|
||||
typedef struct
|
||||
@@ -22,11 +23,12 @@ namespace qjs
|
||||
} JSOSFutureArgv;
|
||||
|
||||
using JSFutureReturn = std::function<JSOSFutureArgv(JSContext *)>;
|
||||
using DartChannel = std::function<std::future<JSFutureReturn>(std::string, std::string)>;
|
||||
using DartChannel = std::function<std::promise<JSFutureReturn> *(std::string, Value)>;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct list_head link;
|
||||
std::promise<JSFutureReturn> *promise;
|
||||
std::shared_future<JSFutureReturn> future;
|
||||
JSValue resolve;
|
||||
JSValue reject;
|
||||
@@ -35,10 +37,10 @@ namespace qjs
|
||||
typedef struct JSThreadState
|
||||
{
|
||||
struct list_head os_future; /* list of JSOSFuture.link */
|
||||
std::function<std::future<JSFutureReturn>(std::string, std::string)> channel;
|
||||
DartChannel channel;
|
||||
} JSThreadState;
|
||||
|
||||
static JSValue js_add_future(Value resolve, Value reject, std::shared_future<JSFutureReturn> future)
|
||||
static JSValue js_add_future(Value resolve, Value reject, std::promise<JSFutureReturn> *promise)
|
||||
{
|
||||
JSRuntime *rt = JS_GetRuntime(resolve.ctx);
|
||||
JSThreadState *ts = (JSThreadState *)JS_GetRuntimeOpaque(rt);
|
||||
@@ -61,7 +63,8 @@ namespace qjs
|
||||
JS_FreeValue(resolve.ctx, obj);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
th->future = future;
|
||||
th->promise = promise;
|
||||
th->future = promise->get_future();
|
||||
th->resolve = JS_DupValue(resolve.ctx, jsResolve);
|
||||
th->reject = JS_DupValue(reject.ctx, jsReject);
|
||||
list_add_tail(&th->link, &ts->os_future);
|
||||
@@ -69,7 +72,7 @@ namespace qjs
|
||||
return obj;
|
||||
}
|
||||
|
||||
JSValue js_dart_future(Value resolve, Value reject, std::string name, std::string args)
|
||||
JSValue js_dart_future(Value resolve, Value reject, std::string name, Value args)
|
||||
{
|
||||
JSRuntime *rt = JS_GetRuntime(resolve.ctx);
|
||||
JSThreadState *ts = (JSThreadState *)JS_GetRuntimeOpaque(rt);
|
||||
@@ -116,6 +119,7 @@ namespace qjs
|
||||
{
|
||||
JSOSFuture *th = list_entry(el, JSOSFuture, link);
|
||||
th->future.get();
|
||||
delete th->promise;
|
||||
unlink_future(rt, th);
|
||||
free_future(rt, th);
|
||||
}
|
||||
@@ -159,7 +163,6 @@ namespace qjs
|
||||
{
|
||||
JSOSFutureArgv argv = th->future.get()(ctx);
|
||||
JSValue resolve, reject;
|
||||
int64_t delay;
|
||||
/* the timer expired */
|
||||
resolve = th->resolve;
|
||||
th->resolve = JS_UNDEFINED;
|
||||
|
@@ -3,7 +3,7 @@
|
||||
* @Author: ekibun
|
||||
* @Date: 2020-08-08 10:30:59
|
||||
* @LastEditors: ekibun
|
||||
* @LastEditTime: 2020-08-13 13:47:28
|
||||
* @LastEditTime: 2020-08-15 13:13:43
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@@ -21,8 +21,7 @@ namespace qjs
|
||||
{
|
||||
struct EngineTask
|
||||
{
|
||||
std::string command;
|
||||
std::string name;
|
||||
std::function<Value(Context&)> invoke;
|
||||
std::function<void(std::string)> resolve;
|
||||
std::function<void(std::string)> reject;
|
||||
};
|
||||
@@ -72,10 +71,26 @@ namespace qjs
|
||||
R"xxx(
|
||||
import * as __DartImpl from "__DartImpl";
|
||||
globalThis.dart = (method, ...args) => new Promise((res, rej) =>
|
||||
__DartImpl.__invoke((v) => res(JSON.parse(v)), rej, method, JSON.stringify(args)));
|
||||
__DartImpl.__invoke(res, rej, method, args));
|
||||
)xxx",
|
||||
"<dart>", JS_EVAL_TYPE_MODULE);
|
||||
std::vector<EngineTaskResolver> unresolvedTask;
|
||||
Value promiseWrapper = ctx.eval(
|
||||
R"xxx(
|
||||
(value) => {
|
||||
const __ret = Promise.resolve(value)
|
||||
.then(v => {
|
||||
__ret.__value = v;
|
||||
__ret.__resolved = true;
|
||||
}).catch(e => {
|
||||
__ret.__error = e;
|
||||
__ret.__rejected = true;
|
||||
});
|
||||
return __ret;
|
||||
}
|
||||
)xxx",
|
||||
"<PromiseWrapper>", JS_EVAL_TYPE_GLOBAL);
|
||||
|
||||
// 循环
|
||||
while (!this->stoped)
|
||||
{
|
||||
@@ -93,25 +108,11 @@ namespace qjs
|
||||
if (task.resolve)
|
||||
try
|
||||
{
|
||||
ctx.global()["__evalstr"] = JS_NewString(ctx.ctx, task.command.c_str());
|
||||
Value ret = ctx.eval(
|
||||
R"xxx(
|
||||
(() => {
|
||||
const __ret = Promise.resolve(eval(__evalstr))
|
||||
.then(v => {
|
||||
__ret.__value = v;
|
||||
__ret.__resolved = true;
|
||||
}).catch(e => {
|
||||
__ret.__error = e;
|
||||
__ret.__rejected = true;
|
||||
});
|
||||
return __ret;
|
||||
})()
|
||||
)xxx",
|
||||
task.name.c_str());
|
||||
Value val = task.invoke(ctx);
|
||||
Value ret = Value{ctx.ctx, JS_Call(ctx.ctx, promiseWrapper.v, ctx.global().v, 1, &(val.v))};
|
||||
unresolvedTask.emplace_back(EngineTaskResolver{ret, std::move(task.resolve), std::move(task.reject)});
|
||||
}
|
||||
catch (exception e)
|
||||
catch (exception)
|
||||
{
|
||||
task.reject(getStackTrack(ctx.getException()));
|
||||
}
|
||||
@@ -152,16 +153,16 @@ namespace qjs
|
||||
{
|
||||
idle = js_dart_poll(ctx.ctx);
|
||||
}
|
||||
catch (exception e)
|
||||
catch (exception)
|
||||
{
|
||||
handleException(ctx.getException());
|
||||
}
|
||||
// 空闲时reject所有task
|
||||
if (idle && !JS_IsJobPending(rt.rt) && !unresolvedTask.empty())
|
||||
{
|
||||
for (EngineTaskResolver &task : unresolvedTask)
|
||||
for (EngineTaskResolver &_task : unresolvedTask)
|
||||
{
|
||||
task.reject("Promise cannot resolve");
|
||||
_task.reject("Promise cannot resolve");
|
||||
}
|
||||
unresolvedTask.clear();
|
||||
}
|
||||
|
Submodule cxx/quickjspp updated: b98fbc128a...0768b665d5
Reference in New Issue
Block a user