diff --git a/autojs/src/main/assets/modules/__continuation__.js b/autojs/src/main/assets/modules/__continuation__.js new file mode 100644 index 00000000..532139c7 --- /dev/null +++ b/autojs/src/main/assets/modules/__continuation__.js @@ -0,0 +1,48 @@ +module.exports = function (runtime, global) { + const Continuation = com.stardust.autojs.rhino.continuation.Continuation; + + function continuation() { + + } + + continuation.create = function (scope) { + scope = scope || global; + var cont = Object.create(runtime.createContinuation(scope)); + cont.await = function () { + let result = cont.suspend(); + if (result.error != null) { + throw result.error; + } + return result.result; + }; + cont.resumeError = function (error) { + if (error == null || error == undefined) { + throw TypeError("error is null or undefined"); + } + cont.resumeWith(Continuation.Result.Companion.failure(error)); + } + cont.resume = function (result) { + cont.resumeWith(Continuation.Result.Companion.success(result)); + } + return cont; + } + + function awaitPromise(scope, promise) { + var cont = continuation.create(scope); + promise.then(result => { + cont.resume(result); + }).catch(error => { + cont.resumeError(error); + }); + return cont.await(); + } + + continuation.await = function (any) { + if (Object.getPrototypeOf(any).constructor === Promise) { + return awaitPromise(global, any); + } + throw new TypeError('cannot await ' + any); + } + + return continuation; +} \ No newline at end of file diff --git a/autojs/src/main/assets/modules/result_adapter.js b/autojs/src/main/assets/modules/result_adapter.js new file mode 100644 index 00000000..0f52acbe --- /dev/null +++ b/autojs/src/main/assets/modules/result_adapter.js @@ -0,0 +1,83 @@ +function ResultAdapter() { + if (ui.isUiThread()) { + this.cont = continuation.create(); + this.impl = { + setResult: (result) => { + this.cont.resume(result); + }, + setError: (error) => { + this.cont.resumeError(error); + }, + get: () => { + return this.cont.await(); + } + }; + } else { + this.disposable = threads.disposable(); + this.impl = { + setResult: (result) => { + this.disposable.setAndNotify({ result: result }); + }, + setError: (error) => { + this.disposable.setAndNotify({ error: error }); + }, + get: () => { + let result = this.disposable.blockedGet(); + return getOrThrow(result); + } + }; + } +} + +function getOrThrow(result) { + if (result.error) { + throw result.error; + } + return result.result; +} + +ResultAdapter.prototype.setResult = function (result) { + this.impl.setResult(result); +} + +ResultAdapter.prototype.setError = function (error) { + this.impl.setError(error); +} + +ResultAdapter.prototype.callback = function () { + var that = this; + return function (result, error) { + if(that.result !== undefined){ + that.result = { + result: result, + error: error + }; + return; + } + if (error) { + that.setError(error); + } else { + that.setResult(result); + } + }; +} + +ResultAdapter.prototype.get = function () { + if(this.result){ + return getOrThrow(this.result); + } + this.result = null; + return this.impl.get(); +} + +ResultAdapter.promise = function(promiseAdapter) { + return new Promise(function(resolve, reject){ + promiseAdapter.onResolve(function(result) { + resolve(result); + }).onReject(function(error){ + reject(error); + }); + }) +} + +module.exports = ResultAdapter; \ No newline at end of file