From 2c3f9931935d91d3a5f3a1b8afa8e86b10efb083 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Wed, 10 Jul 2019 20:07:51 +0900 Subject: [PATCH 1/7] fully support Promise --- include/promise.h | 181 +++++- src/promise.cc | 1441 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 1589 insertions(+), 33 deletions(-) diff --git a/include/promise.h b/include/promise.h index 97c079a..6ea9256 100644 --- a/include/promise.h +++ b/include/promise.h @@ -5,11 +5,35 @@ NAMESPACE_HTML5_BEGIN; -typedef std::function chainVoid; -typedef std::function chainString; +typedef std::function PromiseVoidFunction; +typedef std::function PromiseDoubleFunction; +typedef std::function PromiseStringFunction; +typedef std::function PromiseObjectFunction; -typedef std::function executor; -typedef std::function executorString; +typedef std::function PromiseVoidPromiseFunction; +typedef std::function PromiseDoublePromiseFunction; +typedef std::function PromiseStringPromiseFunction; +typedef std::function PromiseObjectPromiseFunction; + +typedef std::function PromiseVoidVoidPairFunction; +typedef std::function PromiseVoidDoublePairFunction; +typedef std::function PromiseVoidStringPairFunction; +typedef std::function PromiseVoidObjectPairFunction; + +typedef std::function PromiseDoubleVoidPairFunction; +typedef std::function PromiseDoubleDoublePairFunction; +typedef std::function PromiseDoubleStringPairFunction; +typedef std::function PromiseDoubleObjectPairFunction; + +typedef std::function PromiseStringVoidPairFunction; +typedef std::function PromiseStringDoublePairFunction; +typedef std::function PromiseStringStringPairFunction; +typedef std::function PromiseStringObjectPairFunction; + +typedef std::function PromiseObjectVoidPairFunction; +typedef std::function PromiseObjectDoublePairFunction; +typedef std::function PromiseObjectStringPairFunction; +typedef std::function PromiseObjectObjectPairFunction; class Promise : public Object { @@ -19,21 +43,156 @@ class Promise : public Object { Promise(emscripten::val v); virtual ~Promise(); - static Promise *create(executor fn); - static Promise *create(executorString fn); + static Promise *create(PromiseVoidVoidPairFunction fn); + static Promise *create(PromiseVoidDoublePairFunction fn); + static Promise *create(PromiseVoidStringPairFunction fn); + static Promise *create(PromiseVoidObjectPairFunction fn); + static Promise *create(PromiseDoubleVoidPairFunction fn); + static Promise *create(PromiseDoubleDoublePairFunction fn); + static Promise *create(PromiseDoubleStringPairFunction fn); + static Promise *create(PromiseDoubleObjectPairFunction fn); + static Promise *create(PromiseStringVoidPairFunction fn); + static Promise *create(PromiseStringDoublePairFunction fn); + static Promise *create(PromiseStringStringPairFunction fn); + static Promise *create(PromiseStringObjectPairFunction fn); + static Promise *create(PromiseObjectVoidPairFunction fn); + static Promise *create(PromiseObjectDoublePairFunction fn); + static Promise *create(PromiseObjectStringPairFunction fn); + static Promise *create(PromiseObjectObjectPairFunction fn); static Promise *create(emscripten::val v); + Promise *then(PromiseVoidFunction onFulfilled); + Promise *then(PromiseVoidFunction onFulfilled, PromiseVoidFunction onRejected); + Promise *then(PromiseVoidFunction onFulfilled, PromiseDoubleFunction onRejected); + Promise *then(PromiseVoidFunction onFulfilled, PromiseStringFunction onRejected); + Promise *then(PromiseVoidFunction onFulfilled, PromiseObjectFunction onRejected); + Promise *then(PromiseVoidPromiseFunction onFulfilled); + Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseVoidFunction onRejected); + Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseDoubleFunction onRejected); + Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseStringFunction onRejected); + Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseObjectFunction onRejected); + Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected); + Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected); + Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected); + Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected); + Promise *then(PromiseDoubleFunction onFulfilled); + Promise *then(PromiseDoubleFunction onFulfilled, PromiseVoidFunction onRejected); + Promise *then(PromiseDoubleFunction onFulfilled, PromiseDoubleFunction onRejected); + Promise *then(PromiseDoubleFunction onFulfilled, PromiseStringFunction onRejected); + Promise *then(PromiseDoubleFunction onFulfilled, PromiseObjectFunction onRejected); + Promise *then(PromiseDoublePromiseFunction onFulfilled); + Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseVoidFunction onRejected); + Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseDoubleFunction onRejected); + Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseStringFunction onRejected); + Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseObjectFunction onRejected); + Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected); + Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected); + Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected); + Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected); + Promise *then(PromiseStringFunction onFulfilled); + Promise *then(PromiseStringFunction onFulfilled, PromiseVoidFunction onRejected); + Promise *then(PromiseStringFunction onFulfilled, PromiseDoubleFunction onRejected); + Promise *then(PromiseStringFunction onFulfilled, PromiseStringFunction onRejected); + Promise *then(PromiseStringFunction onFulfilled, PromiseObjectFunction onRejected); + Promise *then(PromiseStringPromiseFunction onFulfilled); + Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseVoidFunction onRejected); + Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseDoubleFunction onRejected); + Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseStringFunction onRejected); + Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseObjectFunction onRejected); + Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected); + Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected); + Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected); + Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected); + Promise *then(PromiseObjectFunction onFulfilled); + Promise *then(PromiseObjectFunction onFulfilled, PromiseVoidFunction onRejected); + Promise *then(PromiseObjectFunction onFulfilled, PromiseDoubleFunction onRejected); + Promise *then(PromiseObjectFunction onFulfilled, PromiseStringFunction onRejected); + Promise *then(PromiseObjectFunction onFulfilled, PromiseObjectFunction onRejected); + Promise *then(PromiseObjectPromiseFunction onFulfilled); + Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseVoidFunction onRejected); + Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseDoubleFunction onRejected); + Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseStringFunction onRejected); + Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseObjectFunction onRejected); + Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected); + Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected); + Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected); + Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected); Promise *all(std::vector iterable); Promise *race(std::vector iterable); Promise *reject(std::string reason); Promise *resolve(void *value); Promise *pcatch(std::function onRejected); - Promise *then(chainString onFulfilled); - executorString execStr; - std::vector chainFns; + PromiseVoidVoidPairFunction vvPairFn; + PromiseVoidDoublePairFunction vdPairFn; + PromiseVoidStringPairFunction vsPairFn; + PromiseVoidObjectPairFunction voPairFn; + PromiseDoubleVoidPairFunction dvPairFn; + PromiseDoubleDoublePairFunction ddPairFn; + PromiseDoubleStringPairFunction dsPairFn; + PromiseDoubleObjectPairFunction doPairFn; + PromiseStringVoidPairFunction svPairFn; + PromiseStringDoublePairFunction sdPairFn; + PromiseStringStringPairFunction ssPairFn; + PromiseStringObjectPairFunction soPairFn; + PromiseObjectVoidPairFunction ovPairFn; + PromiseObjectDoublePairFunction odPairFn; + PromiseObjectStringPairFunction osPairFn; + PromiseObjectObjectPairFunction ooPairFn; + + union PromiseFunction { + PromiseVoidFunction v; + PromiseDoubleFunction d; + PromiseStringFunction s; + PromiseObjectFunction o; + PromiseVoidPromiseFunction vp; + PromiseDoublePromiseFunction dp; + PromiseStringPromiseFunction sp; + PromiseObjectPromiseFunction op; + PromiseFunction() : v([]{}) {}; + ~PromiseFunction(){}; + }; + + class PromiseChainFunction { + public: + PromiseFunction onFulfilled; + PromiseFunction onRejected; + PromiseChainFunction(){}; + ~PromiseChainFunction(){}; + }; - void executeString(emscripten::val resolve, emscripten::val reject); - void callbackThenString(emscripten::val resolve); + std::vector chains; + void callbackVV(emscripten::val resolve, emscripten::val reject); + void callbackVD(emscripten::val resolve, emscripten::val reject); + void callbackVS(emscripten::val resolve, emscripten::val reject); + void callbackVO(emscripten::val resolve, emscripten::val reject); + void callbackDV(emscripten::val resolve, emscripten::val reject); + void callbackDD(emscripten::val resolve, emscripten::val reject); + void callbackDS(emscripten::val resolve, emscripten::val reject); + void callbackDO(emscripten::val resolve, emscripten::val reject); + void callbackSV(emscripten::val resolve, emscripten::val reject); + void callbackSD(emscripten::val resolve, emscripten::val reject); + void callbackSS(emscripten::val resolve, emscripten::val reject); + void callbackSO(emscripten::val resolve, emscripten::val reject); + void callbackOV(emscripten::val resolve, emscripten::val reject); + void callbackOD(emscripten::val resolve, emscripten::val reject); + void callbackOS(emscripten::val resolve, emscripten::val reject); + void callbackOO(emscripten::val resolve, emscripten::val reject); + void callbackThenV(); + void callbackThenD(emscripten::val v); + void callbackThenS(emscripten::val v); + void callbackThenO(emscripten::val v); + void callbackRejectV(); + void callbackRejectD(emscripten::val v); + void callbackRejectS(emscripten::val v); + void callbackRejectO(emscripten::val v); + emscripten::val callbackThenVP(); + emscripten::val callbackThenDP(emscripten::val v); + emscripten::val callbackThenSP(emscripten::val v); + emscripten::val callbackThenOP(emscripten::val v); + emscripten::val callbackRejectVP(); + emscripten::val callbackRejectDP(emscripten::val v); + emscripten::val callbackRejectSP(emscripten::val v); + emscripten::val callbackRejectOP(emscripten::val v); }; NAMESPACE_HTML5_END; diff --git a/src/promise.cc b/src/promise.cc index 4c8bc14..2c2a878 100644 --- a/src/promise.cc +++ b/src/promise.cc @@ -22,59 +22,1456 @@ Promise *Promise::create(emscripten::val v) return p; } -Promise *Promise::create(executor fn) +Promise *Promise::create(PromiseVoidVoidPairFunction fn) { Promise *p = new Promise(emscripten::val(0)); - EM_ASM_({ + p->vvPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackVV({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseVoidDoublePairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->vdPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackVD({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseVoidStringPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->vsPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackVS({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseVoidObjectPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->voPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackVO({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseDoubleVoidPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->dvPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackDV({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseDoubleDoublePairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->ddPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackDD({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseDoubleStringPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->dsPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackDS({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseDoubleObjectPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->doPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackDO({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseStringVoidPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->svPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackSV({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseStringDoublePairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->sdPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackSD({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseStringStringPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->ssPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackSS({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseStringObjectPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->soPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackSO({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseObjectVoidPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->ovPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackOV({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseObjectDoublePairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->odPairFn = fn; + EM_ASM_({ var elem = Module['toPromise']($0); - elem['_value'] = new Promise(function(resolve, reject) { elem.callbackThen(resolve, reject); }); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackOD({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseObjectStringPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->osPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackOS({call: resolve}, {call: reject}); + }); }, p); p->autorelease(); return p; } -Promise *Promise::create(executorString fn) +Promise *Promise::create(PromiseObjectObjectPairFunction fn) { Promise *p = new Promise(emscripten::val(0)); - p->execStr = fn; - EM_ASM_({ + p->ooPairFn = fn; + EM_ASM_({ var elem = Module['toPromise']($0); elem['_value'] = new Promise(function(resolve, reject) { - elem.executeString({call: resolve}, reject); + elem.callbackOO({call: resolve}, {call: reject}); }); }, p); p->autorelease(); return p; } -HTML5_BIND_METHOD(Promise, executeString); +void Promise::callbackVV(emscripten::val resolve, emscripten::val reject) +{ + PromiseVoidFunction resolver = [resolve]{ + HTML5_CALL(resolve, call); + }; + PromiseVoidFunction rejector = [reject]{ + HTML5_CALL(reject, call); + }; + this->vvPairFn(resolver, rejector); +} + +void Promise::callbackVD(emscripten::val resolve, emscripten::val reject) +{ + PromiseVoidFunction resolver = [resolve]{ + HTML5_CALL(resolve, call); + }; + PromiseDoubleFunction rejector = [reject](double v){ + HTML5_CALL(reject, call, v); + }; + this->vdPairFn(resolver, rejector); +} + +void Promise::callbackVS(emscripten::val resolve, emscripten::val reject) +{ + PromiseVoidFunction resolver = [resolve]{ + HTML5_CALL(resolve, call); + }; + PromiseStringFunction rejector = [reject](const std::string &v){ + HTML5_CALL(reject, call, v); + }; + this->vsPairFn(resolver, rejector); +} + +void Promise::callbackVO(emscripten::val resolve, emscripten::val reject) +{ + PromiseVoidFunction resolver = [resolve]{ + HTML5_CALL(resolve, call); + }; + PromiseObjectFunction rejector = [reject](const Object &v){ + HTML5_CALL(reject, call, v.v); + }; + this->voPairFn(resolver, rejector); +} + +void Promise::callbackDV(emscripten::val resolve, emscripten::val reject) +{ + PromiseDoubleFunction resolver = [resolve](double v){ + HTML5_CALL(resolve, call, v); + }; + PromiseVoidFunction rejector = [reject]{ + HTML5_CALL(reject, call); + }; + this->dvPairFn(resolver, rejector); +} + +void Promise::callbackDD(emscripten::val resolve, emscripten::val reject) +{ + PromiseDoubleFunction resolver = [resolve](double v){ + HTML5_CALL(resolve, call, v); + }; + PromiseDoubleFunction rejector = [reject](double v){ + HTML5_CALL(reject, call, v); + }; + this->ddPairFn(resolver, rejector); +} + +void Promise::callbackDS(emscripten::val resolve, emscripten::val reject) +{ + PromiseDoubleFunction resolver = [resolve](double v){ + HTML5_CALL(resolve, call, v); + }; + PromiseStringFunction rejector = [reject](const std::string &v){ + HTML5_CALL(reject, call, v); + }; + this->dsPairFn(resolver, rejector); +} + +void Promise::callbackDO(emscripten::val resolve, emscripten::val reject) +{ + PromiseDoubleFunction resolver = [resolve](double v){ + HTML5_CALL(resolve, call, v); + }; + PromiseObjectFunction rejector = [reject](const Object &v){ + HTML5_CALL(reject, call, v.v); + }; + this->doPairFn(resolver, rejector); +} + +void Promise::callbackSV(emscripten::val resolve, emscripten::val reject) +{ + PromiseStringFunction resolver = [resolve](const std::string &v){ + HTML5_CALL(resolve, call, v); + }; + PromiseVoidFunction rejector = [reject]{ + HTML5_CALL(reject, call); + }; + this->svPairFn(resolver, rejector); +} + +void Promise::callbackSD(emscripten::val resolve, emscripten::val reject) +{ + PromiseStringFunction resolver = [resolve](const std::string &v){ + HTML5_CALL(resolve, call, v); + }; + PromiseDoubleFunction rejector = [reject](double v){ + HTML5_CALL(reject, call, v); + }; + this->sdPairFn(resolver, rejector); +} + +void Promise::callbackSS(emscripten::val resolve, emscripten::val reject) +{ + PromiseStringFunction resolver = [resolve](const std::string &v){ + HTML5_CALL(resolve, call, v); + }; + PromiseStringFunction rejector = [reject](const std::string &v){ + HTML5_CALL(reject, call, v); + }; + this->ssPairFn(resolver, rejector); +} + +void Promise::callbackSO(emscripten::val resolve, emscripten::val reject) +{ + PromiseStringFunction resolver = [resolve](const std::string &v){ + HTML5_CALL(resolve, call, v); + }; + PromiseObjectFunction rejector = [reject](const Object &v){ + HTML5_CALL(reject, call, v.v); + }; + this->soPairFn(resolver, rejector); +} + +void Promise::callbackOV(emscripten::val resolve, emscripten::val reject) +{ + PromiseObjectFunction resolver = [resolve](const Object &v){ + HTML5_CALL(resolve, call, v.v); + }; + PromiseVoidFunction rejector = [reject]{ + HTML5_CALL(reject, call); + }; + this->ovPairFn(resolver, rejector); +} + +void Promise::callbackOD(emscripten::val resolve, emscripten::val reject) +{ + PromiseObjectFunction resolver = [resolve](const Object &v){ + HTML5_CALL(resolve, call, v.v); + }; + PromiseDoubleFunction rejector = [reject](double v){ + HTML5_CALL(reject, call, v); + }; + this->odPairFn(resolver, rejector); +} + +void Promise::callbackOS(emscripten::val resolve, emscripten::val reject) +{ + PromiseObjectFunction resolver = [resolve](const Object &v){ + HTML5_CALL(resolve, call, v.v); + }; + PromiseStringFunction rejector = [reject](const std::string &v){ + HTML5_CALL(reject, call, v); + }; + this->osPairFn(resolver, rejector); +} -void Promise::executeString(emscripten::val resolve, emscripten::val reject) +void Promise::callbackOO(emscripten::val resolve, emscripten::val reject) { - std::function resolver = [resolve](const std::string &s){ - HTML5_CALL(resolve, call, s); + PromiseObjectFunction resolver = [resolve](const Object &v){ + HTML5_CALL(resolve, call, v.v); }; - std::function rejector = []{}; - this->execStr(resolver, rejector); + PromiseObjectFunction rejector = [reject](const Object &v){ + HTML5_CALL(reject, call, v.v); + }; + this->ooPairFn(resolver, rejector); +} + +HTML5_BIND_METHOD(Promise, callbackVV); +HTML5_BIND_METHOD(Promise, callbackVD); +HTML5_BIND_METHOD(Promise, callbackVS); +HTML5_BIND_METHOD(Promise, callbackVO); +HTML5_BIND_METHOD(Promise, callbackDV); +HTML5_BIND_METHOD(Promise, callbackDD); +HTML5_BIND_METHOD(Promise, callbackDS); +HTML5_BIND_METHOD(Promise, callbackDO); +HTML5_BIND_METHOD(Promise, callbackSV); +HTML5_BIND_METHOD(Promise, callbackSD); +HTML5_BIND_METHOD(Promise, callbackSS); +HTML5_BIND_METHOD(Promise, callbackSO); +HTML5_BIND_METHOD(Promise, callbackOV); +HTML5_BIND_METHOD(Promise, callbackOD); +HTML5_BIND_METHOD(Promise, callbackOS); +HTML5_BIND_METHOD(Promise, callbackOO); + +Promise *Promise::then(PromiseVoidFunction onFulfilled) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.v = onFulfilled; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then(function() { elem.callbackThenV(); }); + }, this); + return this; } -Promise *Promise::then(chainString onFulfilled) +Promise *Promise::then(PromiseVoidFunction onFulfilled, PromiseVoidFunction onRejected) { - this->chainFns.push_back(onFulfilled); + auto fn = new PromiseChainFunction(); + fn->onFulfilled.v = onFulfilled; + fn->onRejected.v = onRejected; + this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); - elem._value.then(function(resolve) { elem.callbackThenString(resolve); }); + elem._value.then( + function() { elem.callbackThenV(); }, + function() { elem.callbackRejectV(); } + ); }, this); return this; } -HTML5_BIND_METHOD(Promise, callbackThenString); +Promise *Promise::then(PromiseVoidFunction onFulfilled, PromiseDoubleFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.v = onFulfilled; + fn->onRejected.d = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function() { elem.callbackThenV(); }, + function(v) { elem.callbackRejectD(v); } + ); + }, this); + return this; +} -void Promise::callbackThenString(emscripten::val resolve) +Promise *Promise::then(PromiseVoidFunction onFulfilled, PromiseStringFunction onRejected) { - const chainString &chain = this->chainFns[0]; - chain(resolve.as()); - this->chainFns.erase(this->chainFns.begin()); + auto fn = new PromiseChainFunction(); + fn->onFulfilled.v = onFulfilled; + fn->onRejected.s = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function() { elem.callbackThenV(); }, + function(v) { elem.callbackRejectS(v); } + ); + }, this); + return this; } -HTML5_PROPERTY_IMPL(Promise, unsigned long, length); +Promise *Promise::then(PromiseVoidFunction onFulfilled, PromiseObjectFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.v = onFulfilled; + fn->onRejected.o = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function() { elem.callbackThenV(); }, + function(v) { elem.callbackRejectO(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.vp = onFulfilled; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then(function() { return elem.callbackThenVP(); }); + }, this); + return this; +} + +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseVoidFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.v = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function() { return elem.callbackThenVP(); }, + function() { elem.callbackRejectV(); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseDoubleFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.d = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function() { return elem.callbackThenVP(); }, + function(v) { elem.callbackRejectD(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseStringFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.s = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function() { return elem.callbackThenVP(); }, + function(v) { elem.callbackRejectS(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseObjectFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.o = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function() { return elem.callbackThenVP(); }, + function(v) { elem.callbackRejectO(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.vp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function() { return elem.callbackThenVP(); }, + function() { return elem.callbackRejectVP(); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.dp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function() { return elem.callbackThenVP(); }, + function(v) { return elem.callbackRejectDP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.sp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function() { return elem.callbackThenVP(); }, + function(v) { return elem.callbackRejectSP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.op = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function() { return elem.callbackThenVP(); }, + function(v) { return elem.callbackRejectOP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoubleFunction onFulfilled) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.d = onFulfilled; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then(function(v) { elem.callbackThenD(v); }); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoubleFunction onFulfilled, PromiseVoidFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.d = onFulfilled; + fn->onRejected.v = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function(v) { elem.callbackThenD(v); }, + function() { elem.callbackRejectV(); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoubleFunction onFulfilled, PromiseDoubleFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.d = onFulfilled; + fn->onRejected.d = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function(v) { elem.callbackThenD(v); }, + function(v) { elem.callbackRejectD(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoubleFunction onFulfilled, PromiseStringFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.d = onFulfilled; + fn->onRejected.s = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function(v) { elem.callbackThenD(v); }, + function(v) { elem.callbackRejectS(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoubleFunction onFulfilled, PromiseObjectFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.d = onFulfilled; + fn->onRejected.o = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function(v) { elem.callbackThenD(v); }, + function(v) { elem.callbackRejectO(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.dp = onFulfilled; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then(function(v) { return elem.callbackThenDP(v); }); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseVoidFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.dp = onFulfilled; + fn->onRejected.v = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenDP(v); }, + function() { elem.callbackRejectV(); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseDoubleFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.dp = onFulfilled; + fn->onRejected.d = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenDP(v); }, + function(v) { elem.callbackRejectD(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseStringFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.dp = onFulfilled; + fn->onRejected.s = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenDP(v); }, + function(v) { elem.callbackRejectS(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseObjectFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.dp = onFulfilled; + fn->onRejected.o = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenDP(v); }, + function(v) { elem.callbackRejectO(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.dp = onFulfilled; + fn->onRejected.vp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenDP(v); }, + function() { return elem.callbackRejectVP(); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.dp = onFulfilled; + fn->onRejected.dp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenDP(v); }, + function(v) { return elem.callbackRejectDP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.dp = onFulfilled; + fn->onRejected.sp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenDP(v); }, + function(v) { return elem.callbackRejectSP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.dp = onFulfilled; + fn->onRejected.op = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenDP(v); }, + function(v) { return elem.callbackRejectOP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringFunction onFulfilled) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.s = onFulfilled; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then(function(v) { elem.callbackThenS(v); }); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringFunction onFulfilled, PromiseVoidFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.s = onFulfilled; + fn->onRejected.v = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function(v) { elem.callbackThenS(v); }, + function() { elem.callbackRejectV(); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringFunction onFulfilled, PromiseDoubleFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.s = onFulfilled; + fn->onRejected.d = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function(v) { elem.callbackThenS(v); }, + function(v) { elem.callbackRejectD(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringFunction onFulfilled, PromiseStringFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.s = onFulfilled; + fn->onRejected.s = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function(v) { elem.callbackThenS(v); }, + function(v) { elem.callbackRejectS(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringFunction onFulfilled, PromiseObjectFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.s = onFulfilled; + fn->onRejected.o = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function(v) { elem.callbackThenS(v); }, + function(v) { elem.callbackRejectO(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.sp = onFulfilled; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then(function(v) { return elem.callbackThenSP(v); }); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseVoidFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.sp = onFulfilled; + fn->onRejected.v = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenSP(v); }, + function() { elem.callbackRejectV(); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseDoubleFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.sp = onFulfilled; + fn->onRejected.d = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenSP(v); }, + function(v) { elem.callbackRejectD(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseStringFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.sp = onFulfilled; + fn->onRejected.s = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenSP(v); }, + function(v) { elem.callbackRejectS(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseObjectFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.sp = onFulfilled; + fn->onRejected.o = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenSP(v); }, + function(v) { elem.callbackRejectO(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.sp = onFulfilled; + fn->onRejected.vp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenSP(v); }, + function() { return elem.callbackRejectVP(); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.sp = onFulfilled; + fn->onRejected.dp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenSP(v); }, + function(v) { return elem.callbackRejectDP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.sp = onFulfilled; + fn->onRejected.sp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenSP(v); }, + function(v) { return elem.callbackRejectSP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.sp = onFulfilled; + fn->onRejected.op = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenSP(v); }, + function(v) { return elem.callbackRejectOP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseObjectFunction onFulfilled) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.o = onFulfilled; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then(function(v) { elem.callbackThenO(v); }); + }, this); + return this; +} + +Promise *Promise::then(PromiseObjectFunction onFulfilled, PromiseVoidFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.o = onFulfilled; + fn->onRejected.v = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function(v) { elem.callbackThenO(v); }, + function() { elem.callbackRejectV(); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseObjectFunction onFulfilled, PromiseDoubleFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.o = onFulfilled; + fn->onRejected.d = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function(v) { elem.callbackThenO(v); }, + function(v) { elem.callbackRejectD(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseObjectFunction onFulfilled, PromiseStringFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.o = onFulfilled; + fn->onRejected.s = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function(v) { elem.callbackThenO(v); }, + function(v) { elem.callbackRejectS(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseObjectFunction onFulfilled, PromiseObjectFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.o = onFulfilled; + fn->onRejected.o = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value.then( + function(v) { elem.callbackThenO(v); }, + function(v) { elem.callbackRejectO(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.op = onFulfilled; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then(function(v) { return elem.callbackThenOP(v); }); + }, this); + return this; +} + +Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseVoidFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.op = onFulfilled; + fn->onRejected.v = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(v); }, + function() { elem.callbackRejectV(); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseDoubleFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.op = onFulfilled; + fn->onRejected.d = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(v); }, + function(v) { elem.callbackRejectD(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseStringFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.op = onFulfilled; + fn->onRejected.s = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(v); }, + function(v) { elem.callbackRejectS(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseObjectFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.op = onFulfilled; + fn->onRejected.o = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(v); }, + function(v) { elem.callbackRejectO(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.op = onFulfilled; + fn->onRejected.vp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(v); }, + function() { return elem.callbackRejectVP(); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.op = onFulfilled; + fn->onRejected.dp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(v); }, + function(v) { return elem.callbackRejectDP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.op = onFulfilled; + fn->onRejected.sp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(v); }, + function(v) { return elem.callbackRejectSP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.op = onFulfilled; + fn->onRejected.op = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(); }, + function(v) { return elem.callbackRejectOP(v); } + ); + }, this); + return this; +} + +void Promise::callbackThenV() +{ + PromiseChainFunction *chain = this->chains[0]; + PromiseVoidFunction func = chain->onFulfilled.v; + func(); + this->chains.erase(this->chains.begin()); + delete chain; +} + +void Promise::callbackThenD(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onFulfilled.d; + func(v.as()); + this->chains.erase(this->chains.begin()); + delete chain; +} + +void Promise::callbackThenS(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onFulfilled.s; + func(v.as()); + this->chains.erase(this->chains.begin()); + delete chain; +} + +void Promise::callbackThenO(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onFulfilled.o; + func(Object(v)); + this->chains.erase(this->chains.begin()); + delete chain; +} + +void Promise::callbackRejectV() +{ + PromiseChainFunction *chain = this->chains[0]; + PromiseVoidFunction func = chain->onRejected.v; + func(); + this->chains.erase(this->chains.begin()); + delete chain; +} + +void Promise::callbackRejectD(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onRejected.d; + func(v.as()); + this->chains.erase(this->chains.begin()); + delete chain; +} + + +void Promise::callbackRejectS(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onRejected.s; + func(v.as()); + this->chains.erase(this->chains.begin()); + delete chain; +} + +void Promise::callbackRejectO(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onRejected.o; + func(Object(v)); + this->chains.erase(this->chains.begin()); + delete chain; +} + +emscripten::val Promise::callbackThenVP() +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onFulfilled.vp; + Promise *p = func(); + this->chains.erase(this->chains.begin()); + delete chain; + return p->v; +} + +emscripten::val Promise::callbackThenDP(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onFulfilled.dp; + Promise *p = func(v.as()); + this->chains.erase(this->chains.begin()); + delete chain; + return p->v; +} + +emscripten::val Promise::callbackThenSP(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onFulfilled.sp; + Promise *p = func(v.as()); + this->chains.erase(this->chains.begin()); + delete chain; + return p->v; +} + +emscripten::val Promise::callbackThenOP(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onFulfilled.op; + Promise *p = func(Object(v)); + this->chains.erase(this->chains.begin()); + delete chain; + return p->v; +} + +emscripten::val Promise::callbackRejectVP() +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onRejected.vp; + Promise *p = func(); + this->chains.erase(this->chains.begin()); + delete chain; + return p->v; +} + +emscripten::val Promise::callbackRejectDP(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onRejected.dp; + Promise *p = func(v.as()); + this->chains.erase(this->chains.begin()); + delete chain; + return p->v; +} + +emscripten::val Promise::callbackRejectSP(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onRejected.sp; + Promise *p = func(v.as()); + this->chains.erase(this->chains.begin()); + delete chain; + return p->v; +} + +emscripten::val Promise::callbackRejectOP(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onRejected.op; + Promise *p = func(Object(v)); + this->chains.erase(this->chains.begin()); + delete chain; + return p->v; +} + +HTML5_BIND_METHOD(Promise, callbackThenV); +HTML5_BIND_METHOD(Promise, callbackThenD); +HTML5_BIND_METHOD(Promise, callbackThenS); +HTML5_BIND_METHOD(Promise, callbackThenO); +HTML5_BIND_METHOD(Promise, callbackRejectV); +HTML5_BIND_METHOD(Promise, callbackRejectD); +HTML5_BIND_METHOD(Promise, callbackRejectS); +HTML5_BIND_METHOD(Promise, callbackRejectO); +HTML5_BIND_METHOD(Promise, callbackThenVP); +HTML5_BIND_METHOD(Promise, callbackThenDP); +HTML5_BIND_METHOD(Promise, callbackThenSP); +HTML5_BIND_METHOD(Promise, callbackThenOP); +HTML5_BIND_METHOD(Promise, callbackRejectVP); +HTML5_BIND_METHOD(Promise, callbackRejectDP); +HTML5_BIND_METHOD(Promise, callbackRejectSP); +HTML5_BIND_METHOD(Promise, callbackRejectOP); + +HTML5_PROPERTY_IMPL(Promise, unsigned long, length); + From 71cd61d7147a2a9425fe006362f357df74b8e22b Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Thu, 11 Jul 2019 00:23:05 +0900 Subject: [PATCH 2/7] add fetch test --- CMakeLists.txt | 2 ++ examples/promise.cc | 22 ++++++++++++ include/class.h | 2 ++ include/export.h | 1 + include/file_reader.h | 37 ++++++++++++++++++++ include/libhtml5.h | 27 +++++++++++++++ include/promise.h | 2 +- include/response.h | 36 +++++++++++++++++++ include/window.h | 1 + src/export.cc | 5 +++ src/file_reader.cc | 80 +++++++++++++++++++++++++++++++++++++++++++ src/promise.cc | 4 +-- src/response.cc | 70 +++++++++++++++++++++++++++++++++++++ src/window.cc | 5 +++ 14 files changed, 291 insertions(+), 3 deletions(-) create mode 100644 include/file_reader.h create mode 100644 include/response.h create mode 100644 src/file_reader.cc create mode 100644 src/response.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index d94ff32..0ccf7a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ set(SOURCES src/application_cache.cc src/event_target.cc src/export.cc src/external.cc + src/file_reader.cc src/float32_array.cc src/float64_array.cc src/history.cc @@ -93,6 +94,7 @@ set(SOURCES src/application_cache.cc src/range.cc src/regexp.cc src/rendering_context.cc + src/response.cc src/storage.cc src/string.cc src/style_sheet.cc diff --git a/examples/promise.cc b/examples/promise.cc index 7ebeb9d..ab49c89 100644 --- a/examples/promise.cc +++ b/examples/promise.cc @@ -14,6 +14,28 @@ static void promiseTest() html5::window->console->log(promise); } +static void fetchTest() +{ + HTML5_INIT(); + std::string url = "http://localhost/test/free.jpg"; + html5::fetch(url)->then([](const html5::Object &_response)->html5::Promise* { + auto response = dynamic_cast(const_cast(&_response)); + return response->blob(); + })->then([](const html5::Object &_blob)->html5::Promise* { + auto blob = dynamic_cast(const_cast(&_blob)); + auto reader = html5::FileReader::create(); + reader->onload = [reader](html5::Event *event) { + auto data = reader->result; + auto image = html5::HTMLImageElement::create(); + image->src = data; + html5::window->document->appendChild(image); + }; + reader->readAsDataURL(blob); + return nullptr; + }); +} + EMSCRIPTEN_BINDINGS(Promise) { emscripten::function("promiseTest", &promiseTest); + emscripten::function("fetchTest", &fetchTest); } diff --git a/include/class.h b/include/class.h index c598a54..85b3b75 100644 --- a/include/class.h +++ b/include/class.h @@ -31,6 +31,7 @@ #include "event.h" #include "event_target.h" #include "external.h" +#include "file_reader.h" #include "float32_array.h" #include "float64_array.h" #include "history.h" @@ -84,6 +85,7 @@ #include "processing_instruction.h" #include "promise.h" #include "range.h" +#include "response.h" #include "rendering_context.h" #include "storage.h" #include "style_sheet.h" diff --git a/include/export.h b/include/export.h index aec0378..23e523f 100644 --- a/include/export.h +++ b/include/export.h @@ -51,6 +51,7 @@ extern Promise *createImageBitmap(Blob *image, long sx, long sy, long sw, long s extern Promise *createImageBitmap(ImageData *image, long sx, long sy, long sw, long sh); extern Promise *createImageBitmap(CanvasRenderingContext2D *image, long sx, long sy, long sw, long sh); extern Promise *createImageBitmap(ImageBitmap *image, long sx, long sy, long sw, long sh); +extern Promise *fetch(const std::string &url); extern void focus(); extern CSSStyleDeclaration *getComputedStyle(Element *elt, std::string pseudoElt); extern WindowProxy *getter(void *indexName); diff --git a/include/file_reader.h b/include/file_reader.h new file mode 100644 index 0000000..a96e149 --- /dev/null +++ b/include/file_reader.h @@ -0,0 +1,37 @@ +#pragma once + +#include "event_target.h" + +NAMESPACE_HTML5_BEGIN; + +class Blob; +class File; +class ArrayBuffer; + +class FileReader : public EventTarget { +public: + struct { + FileReader &self; + operator ArrayBuffer *() { return self.resultArrayBuffer(); }; + operator std::string () { return self.resultString(); }; + } result{*this}; + HTML5_EVENT_HANDLER_PROPERTY(FileReader, EventHandler, onload); + + FileReader(emscripten::val v); + virtual ~FileReader(); + static FileReader *create(); + void abort(); + void readAsArrayBuffer(Blob *blob); + void readAsArrayBuffer(File *file); + void readAsBinaryString(Blob *blob); + void readAsBinaryString(File *file); + void readAsDataURL(Blob *blob); + void readAsDataURL(File *file); + void readAsText(Blob *blob, const std::string &encoding = "utf-8"); + void readAsText(File *file, const std::string &encoding = "utf-8"); + + ArrayBuffer *resultArrayBuffer() const; + std::string resultString() const; +}; + +NAMESPACE_HTML5_END; \ No newline at end of file diff --git a/include/libhtml5.h b/include/libhtml5.h index 1199b54..b08193d 100644 --- a/include/libhtml5.h +++ b/include/libhtml5.h @@ -373,6 +373,33 @@ template std::vector toObjectArray(emscripten::val v) } \ HTML5_BIND_METHOD(klass, callback_ ## name); +#define HTML5_EVENT_HANDLER_PROPERTY_IMPL_NEW(klass, type, name) \ + type klass::get_ ## name() const \ + { \ + HTML5_PROPERTY_TRACE_GETTER(name); \ + return this->_ ## name; \ + } \ + \ + void klass::set_ ## name(type value) \ + { \ + HTML5_PROPERTY_TRACE_SETTER(name); \ + this->_ ## name = value; \ + const char *key = __to_text__(to ## klass); \ + const char *callbackFnName = __to_text__(callback_ ## name); \ + EM_ASM_({ \ + var key = Module['toString']($1); \ + var callbackFnName = Module['toString']($2); \ + var elem = Module[key]($0); \ + elem['_value'][#name] = function(e) { elem[callbackFnName](e); }; \ + }, this, key, callbackFnName); \ + } \ + void klass::callback_ ## name(emscripten::val e) \ + { \ + if (!this->_ ## name) return; \ + (this->_ ## name)(Event::create(e)); \ + } \ + HTML5_BIND_METHOD(klass, callback_ ## name); + #define HTML5_ERROR_HANDLER_PROPERTY_IMPL(klass, type, name) \ type klass::get_ ## name() const \ { \ diff --git a/include/promise.h b/include/promise.h index 6ea9256..b673960 100644 --- a/include/promise.h +++ b/include/promise.h @@ -102,12 +102,12 @@ class Promise : public Object { Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected); Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected); Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected); - Promise *then(PromiseObjectFunction onFulfilled); Promise *then(PromiseObjectFunction onFulfilled, PromiseVoidFunction onRejected); Promise *then(PromiseObjectFunction onFulfilled, PromiseDoubleFunction onRejected); Promise *then(PromiseObjectFunction onFulfilled, PromiseStringFunction onRejected); Promise *then(PromiseObjectFunction onFulfilled, PromiseObjectFunction onRejected); Promise *then(PromiseObjectPromiseFunction onFulfilled); + //Promise *then(PromiseObjectFunction onFulfilled); Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseVoidFunction onRejected); Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseDoubleFunction onRejected); Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseStringFunction onRejected); diff --git a/include/response.h b/include/response.h new file mode 100644 index 0000000..c692053 --- /dev/null +++ b/include/response.h @@ -0,0 +1,36 @@ +#pragma once + +#include "libhtml5.h" + +NAMESPACE_HTML5_BEGIN; + +class Headers; +class ReadableStream; + +class Response : public Object { +public: + + HTML5_READONLY_PROPERTY_OBJECT(Response, Headers, headers); + HTML5_READONLY_PROPERTY(Response, bool, ok); + HTML5_READONLY_PROPERTY(Response, bool, redirected); + HTML5_READONLY_PROPERTY(Response, int, status); + HTML5_READONLY_PROPERTY(Response, std::string, type); + HTML5_READONLY_PROPERTY(Response, std::string, url); + HTML5_PROPERTY(Response, bool, useFinalURL); + HTML5_READONLY_PROPERTY_OBJECT(Response, ReadableStream, body); + HTML5_READONLY_PROPERTY(Response, bool, bodyUsed); + + Response(emscripten::val v); + virtual ~Response(); + static Response *create(emscripten::val v); + Response *clone(); + Response *error(); + Response *redirect(const std::string &url, int status = 0); + Promise *arrayBuffer(); + Promise *blob(); + Promise *formData(); + Promise *json(); + Promise *text(); +}; + +NAMESPACE_HTML5_END; diff --git a/include/window.h b/include/window.h index 17c493c..f3f96ea 100644 --- a/include/window.h +++ b/include/window.h @@ -155,6 +155,7 @@ class Window : public EventTarget { Promise *createImageBitmap(ImageData *image, long sx, long sy, long sw, long sh); Promise *createImageBitmap(CanvasRenderingContext2D *image, long sx, long sy, long sw, long sh); Promise *createImageBitmap(ImageBitmap *image, long sx, long sy, long sw, long sh); + Promise *fetch(const std::string &url); void focus(); CSSStyleDeclaration *getComputedStyle(Element *elt, std::string pseudoElt); WindowProxy *getter(void *indexName); diff --git a/src/export.cc b/src/export.cc index 38db19d..be0ee41 100644 --- a/src/export.cc +++ b/src/export.cc @@ -83,6 +83,11 @@ Promise *createImageBitmap(ImageBitmap *image, long sx, long sy, long sw, long s return window->createImageBitmap(image, sx, sy, sw, sh); } +Promise *fetch(const std::string &url) +{ + return window->fetch(url); +} + void focus() { window->focus(); diff --git a/src/file_reader.cc b/src/file_reader.cc new file mode 100644 index 0000000..7eca7eb --- /dev/null +++ b/src/file_reader.cc @@ -0,0 +1,80 @@ +#include "file_reader.h" +#include "blob.h" +#include "array_buffer.h" + +USING_NAMESPACE_HTML5; + +HTML5_BIND_CLASS(FileReader); + +FileReader::FileReader(emscripten::val v) : + EventTarget(v) +{ +} + +FileReader::~FileReader() +{ +} + +FileReader *FileReader::create() +{ + auto reader = new FileReader(HTML5_NEW_PRIMITIVE_INSTANCE(FileReader)); + reader->autorelease(); + return reader; +} + +void FileReader::abort() +{ + HTML5_CALL(this->v, abort); +} + +void FileReader::readAsArrayBuffer(Blob *blob) +{ + HTML5_CALL(this->v, readAsArrayBuffer, blob->v); +} + +void FileReader::readAsArrayBuffer(File *file) +{ +// HTML5_CALL(this->v, readAsArrayBuffer, file->v); +} + +void FileReader::readAsBinaryString(Blob *blob) +{ + HTML5_CALL(this->v, readAsBinaryString, blob->v); +} + +void FileReader::readAsBinaryString(File *file) +{ + //HTML5_CALL(this->v, readAsBinaryString, file->v); +} + +void FileReader::readAsDataURL(Blob *blob) +{ + HTML5_CALL(this->v, readAsDataURL, blob->v); +} + +void FileReader::readAsDataURL(File *file) +{ + //HTML5_CALL(this->v, readAsDataURL, file->v); +} + +void FileReader::readAsText(Blob *blob, const std::string &encoding) +{ + HTML5_CALL(this->v, readAsText, blob->v, encoding); +} + +void FileReader::readAsText(File *file, const std::string &encoding) +{ + //HTML5_CALL(this->v, readAsText, file->v, encoding); +} + +ArrayBuffer *FileReader::resultArrayBuffer() const +{ + return ArrayBuffer::create(this->v["result"]); +} + +std::string FileReader::resultString() const +{ + return this->v["result"].as(); +} + +HTML5_EVENT_HANDLER_PROPERTY_IMPL_NEW(FileReader, EventHandler, onload); \ No newline at end of file diff --git a/src/promise.cc b/src/promise.cc index 2c2a878..3ba6b70 100644 --- a/src/promise.cc +++ b/src/promise.cc @@ -1086,7 +1086,7 @@ Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseObjectPr }, this); return this; } - +/* Promise *Promise::then(PromiseObjectFunction onFulfilled) { auto fn = new PromiseChainFunction(); @@ -1098,7 +1098,7 @@ Promise *Promise::then(PromiseObjectFunction onFulfilled) }, this); return this; } - +*/ Promise *Promise::then(PromiseObjectFunction onFulfilled, PromiseVoidFunction onRejected) { auto fn = new PromiseChainFunction(); diff --git a/src/response.cc b/src/response.cc new file mode 100644 index 0000000..ebc6029 --- /dev/null +++ b/src/response.cc @@ -0,0 +1,70 @@ +#include "response.h" +#include "promise.h" + +USING_NAMESPACE_HTML5; + +Response::Response(emscripten::val v) : + Object(v) +{ +} + +Response::~Response() +{ +} + +Response *Response::create(emscripten::val v) +{ + auto response = new Response(v); + response->autorelease(); + return response; +} + +Response *Response::clone() +{ + return Response::create(HTML5_CALLv(this->v, clone)); +} + +Response *Response::error() +{ + return Response::create(HTML5_CALLv(this->v, error)); +} + +Response *Response::redirect(const std::string &url, int status) +{ + return Response::create(HTML5_CALLv(this->v, redirect, url, status)); +} + +Promise *Response::arrayBuffer() +{ + return Promise::create(HTML5_CALLv(this->v, arrayBuffer)); +} + +Promise *Response::blob() +{ + return Promise::create(HTML5_CALLv(this->v, blob)); +} + +Promise *Response::formData() +{ + return Promise::create(HTML5_CALLv(this->v, formData)); +} + +Promise *Response::json() +{ + return Promise::create(HTML5_CALLv(this->v, json)); +} + +Promise *Response::text() +{ + return Promise::create(HTML5_CALLv(this->v, text)); +} + +//HTML5_READONLY_PROPERTY_OBJECT_IMPL(Response, Headers, headers); +HTML5_READONLY_PROPERTY_IMPL(Response, bool, ok); +HTML5_READONLY_PROPERTY_IMPL(Response, bool, redirected); +HTML5_READONLY_PROPERTY_IMPL(Response, int, status); +HTML5_READONLY_PROPERTY_IMPL(Response, std::string, type); +HTML5_READONLY_PROPERTY_IMPL(Response, std::string, url); +HTML5_PROPERTY_IMPL(Response, bool, useFinalURL); +//HTML5_READONLY_PROPERTY_OBJECT_IMPL(Response, ReadableStream, body); +HTML5_READONLY_PROPERTY_IMPL(Response, bool, bodyUsed); \ No newline at end of file diff --git a/src/window.cc b/src/window.cc index e7adf15..940da23 100644 --- a/src/window.cc +++ b/src/window.cc @@ -134,6 +134,11 @@ Promise *Window::createImageBitmap(ImageBitmap *image, long sx, long sy, long sw return Promise::create(HTML5_CALLv(this->v, createImageBitmap, image->v, sx, sy, sw, sh)); } +Promise *Window::fetch(const std::string &url) +{ + return Promise::create(HTML5_CALLv(this->v, fetch, url)); +} + void Window::focus() { HTML5_CALL(this->v, focus); From 0a35d02ca4ce0052527c5b2975f17c05f1cf39a6 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Thu, 11 Jul 2019 00:56:54 +0900 Subject: [PATCH 3/7] work promise example --- examples/promise.cc | 8 ++++---- src/promise.cc | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/promise.cc b/examples/promise.cc index ab49c89..2e1975d 100644 --- a/examples/promise.cc +++ b/examples/promise.cc @@ -19,16 +19,16 @@ static void fetchTest() HTML5_INIT(); std::string url = "http://localhost/test/free.jpg"; html5::fetch(url)->then([](const html5::Object &_response)->html5::Promise* { - auto response = dynamic_cast(const_cast(&_response)); + auto response = (html5::Response *)(&_response); return response->blob(); })->then([](const html5::Object &_blob)->html5::Promise* { - auto blob = dynamic_cast(const_cast(&_blob)); + auto blob = (html5::Blob *)(&_blob); auto reader = html5::FileReader::create(); reader->onload = [reader](html5::Event *event) { - auto data = reader->result; + std::string data = reader->result; auto image = html5::HTMLImageElement::create(); image->src = data; - html5::window->document->appendChild(image); + html5::window->document->body->appendChild(image); }; reader->readAsDataURL(blob); return nullptr; diff --git a/src/promise.cc b/src/promise.cc index 3ba6b70..fa7fa30 100644 --- a/src/promise.cc +++ b/src/promise.cc @@ -1413,6 +1413,9 @@ emscripten::val Promise::callbackThenOP(emscripten::val v) Promise *p = func(Object(v)); this->chains.erase(this->chains.begin()); delete chain; + if (p == nullptr) { + return emscripten::val(0); + } return p->v; } From 5252f6e2b5f19c09b089dc7108c2443b69b5f38b Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Thu, 11 Jul 2019 14:03:40 +0900 Subject: [PATCH 4/7] fix promise interface --- examples/promise.cc | 7 +- include/promise.h | 129 ++++--- src/promise.cc | 846 ++++---------------------------------------- 3 files changed, 161 insertions(+), 821 deletions(-) diff --git a/examples/promise.cc b/examples/promise.cc index 2e1975d..a56b9d5 100644 --- a/examples/promise.cc +++ b/examples/promise.cc @@ -10,6 +10,7 @@ static void promiseTest() }); promise->then([](const std::string &value) { html5::window->console->log(value); + return nullptr; }); html5::window->console->log(promise); } @@ -18,11 +19,9 @@ static void fetchTest() { HTML5_INIT(); std::string url = "http://localhost/test/free.jpg"; - html5::fetch(url)->then([](const html5::Object &_response)->html5::Promise* { - auto response = (html5::Response *)(&_response); + html5::fetch(url)->then([](html5::Response *response) { return response->blob(); - })->then([](const html5::Object &_blob)->html5::Promise* { - auto blob = (html5::Blob *)(&_blob); + })->then([](html5::Blob *blob) { auto reader = html5::FileReader::create(); reader->onload = [reader](html5::Event *event) { std::string data = reader->result; diff --git a/include/promise.h b/include/promise.h index b673960..3816718 100644 --- a/include/promise.h +++ b/include/promise.h @@ -35,7 +35,6 @@ typedef std::function Promis typedef std::function PromiseObjectStringPairFunction; typedef std::function PromiseObjectObjectPairFunction; - class Promise : public Object { public: @@ -60,62 +59,102 @@ class Promise : public Object { static Promise *create(PromiseObjectStringPairFunction fn); static Promise *create(PromiseObjectObjectPairFunction fn); static Promise *create(emscripten::val v); - Promise *then(PromiseVoidFunction onFulfilled); - Promise *then(PromiseVoidFunction onFulfilled, PromiseVoidFunction onRejected); - Promise *then(PromiseVoidFunction onFulfilled, PromiseDoubleFunction onRejected); - Promise *then(PromiseVoidFunction onFulfilled, PromiseStringFunction onRejected); - Promise *then(PromiseVoidFunction onFulfilled, PromiseObjectFunction onRejected); Promise *then(PromiseVoidPromiseFunction onFulfilled); - Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseVoidFunction onRejected); - Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseDoubleFunction onRejected); - Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseStringFunction onRejected); - Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseObjectFunction onRejected); Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected); Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected); Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected); Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected); - Promise *then(PromiseDoubleFunction onFulfilled); - Promise *then(PromiseDoubleFunction onFulfilled, PromiseVoidFunction onRejected); - Promise *then(PromiseDoubleFunction onFulfilled, PromiseDoubleFunction onRejected); - Promise *then(PromiseDoubleFunction onFulfilled, PromiseStringFunction onRejected); - Promise *then(PromiseDoubleFunction onFulfilled, PromiseObjectFunction onRejected); Promise *then(PromiseDoublePromiseFunction onFulfilled); - Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseVoidFunction onRejected); - Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseDoubleFunction onRejected); - Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseStringFunction onRejected); - Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseObjectFunction onRejected); Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected); Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected); Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected); Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected); - Promise *then(PromiseStringFunction onFulfilled); - Promise *then(PromiseStringFunction onFulfilled, PromiseVoidFunction onRejected); - Promise *then(PromiseStringFunction onFulfilled, PromiseDoubleFunction onRejected); - Promise *then(PromiseStringFunction onFulfilled, PromiseStringFunction onRejected); - Promise *then(PromiseStringFunction onFulfilled, PromiseObjectFunction onRejected); Promise *then(PromiseStringPromiseFunction onFulfilled); - Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseVoidFunction onRejected); - Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseDoubleFunction onRejected); - Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseStringFunction onRejected); - Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseObjectFunction onRejected); Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected); Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected); Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected); Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected); - Promise *then(PromiseObjectFunction onFulfilled, PromiseVoidFunction onRejected); - Promise *then(PromiseObjectFunction onFulfilled, PromiseDoubleFunction onRejected); - Promise *then(PromiseObjectFunction onFulfilled, PromiseStringFunction onRejected); - Promise *then(PromiseObjectFunction onFulfilled, PromiseObjectFunction onRejected); - Promise *then(PromiseObjectPromiseFunction onFulfilled); - //Promise *then(PromiseObjectFunction onFulfilled); - Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseVoidFunction onRejected); - Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseDoubleFunction onRejected); - Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseStringFunction onRejected); - Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseObjectFunction onRejected); - Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected); - Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected); - Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected); - Promise *then(PromiseObjectPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected); + template Promise *then(std::function onFulfilled) { + auto fn = new PromiseChainFunction(); + PromiseObjectPromiseFunction f = [onFulfilled](const Object &o) { + return onFulfilled((T)(&o)); + }; + fn->onFulfilled.op = f; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then(function(v) { return elem.callbackThenOP(v); }); + }, this); + return this; + }; + template Promise *then(std::function onFulfilled, PromiseVoidPromiseFunction onRejected) { + auto fn = new PromiseChainFunction(); + PromiseObjectPromiseFunction f = [onFulfilled](const Object &o) { + return onFulfilled((T)(&o)); + }; + fn->onFulfilled.op = f; + fn->onRejected.vp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(v); }, + function() { return elem.callbackRejectVP(); } + ); + }, this); + return this; + }; + template Promise *then(std::function onFulfilled, PromiseDoublePromiseFunction onRejected) { + auto fn = new PromiseChainFunction(); + PromiseObjectPromiseFunction f = [onFulfilled](const Object &o) { + return onFulfilled((T)(&o)); + }; + fn->onFulfilled.op = f; + fn->onRejected.dp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(v); }, + function(v) { return elem.callbackRejectDP(v); } + ); + }, this); + return this; + }; + template Promise *then(std::function onFulfilled, PromiseStringPromiseFunction onRejected) { + auto fn = new PromiseChainFunction(); + PromiseObjectPromiseFunction f = [onFulfilled](const Object &o) { + return onFulfilled((T)(&o)); + }; + fn->onFulfilled.op = f; + fn->onRejected.sp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(v); }, + function(v) { return elem.callbackRejectSP(v); } + ); + }, this); + return this; + }; + template Promise *then(std::function onFulfilled, PromiseObjectPromiseFunction onRejected) { + auto fn = new PromiseChainFunction(); + PromiseObjectPromiseFunction f = [onFulfilled](const Object &o) { + return onFulfilled((T)(&o)); + }; + fn->onFulfilled.op = f; + fn->onRejected.op = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(); }, + function(v) { return elem.callbackRejectOP(v); } + ); + }, this); + return this; + }; Promise *all(std::vector iterable); Promise *race(std::vector iterable); Promise *reject(std::string reason); @@ -140,15 +179,11 @@ class Promise : public Object { PromiseObjectObjectPairFunction ooPairFn; union PromiseFunction { - PromiseVoidFunction v; - PromiseDoubleFunction d; - PromiseStringFunction s; - PromiseObjectFunction o; PromiseVoidPromiseFunction vp; PromiseDoublePromiseFunction dp; PromiseStringPromiseFunction sp; PromiseObjectPromiseFunction op; - PromiseFunction() : v([]{}) {}; + PromiseFunction() : vp([]{return nullptr;}) {}; ~PromiseFunction(){}; }; diff --git a/src/promise.cc b/src/promise.cc index fa7fa30..f486c7c 100644 --- a/src/promise.cc +++ b/src/promise.cc @@ -439,943 +439,236 @@ HTML5_BIND_METHOD(Promise, callbackOD); HTML5_BIND_METHOD(Promise, callbackOS); HTML5_BIND_METHOD(Promise, callbackOO); -Promise *Promise::then(PromiseVoidFunction onFulfilled) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.v = onFulfilled; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then(function() { elem.callbackThenV(); }); - }, this); - return this; -} - -Promise *Promise::then(PromiseVoidFunction onFulfilled, PromiseVoidFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.v = onFulfilled; - fn->onRejected.v = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function() { elem.callbackThenV(); }, - function() { elem.callbackRejectV(); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseVoidFunction onFulfilled, PromiseDoubleFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.v = onFulfilled; - fn->onRejected.d = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function() { elem.callbackThenV(); }, - function(v) { elem.callbackRejectD(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseVoidFunction onFulfilled, PromiseStringFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.v = onFulfilled; - fn->onRejected.s = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function() { elem.callbackThenV(); }, - function(v) { elem.callbackRejectS(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseVoidFunction onFulfilled, PromiseObjectFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.v = onFulfilled; - fn->onRejected.o = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function() { elem.callbackThenV(); }, - function(v) { elem.callbackRejectO(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.vp = onFulfilled; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then(function() { return elem.callbackThenVP(); }); - }, this); - return this; -} - -Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseVoidFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.vp = onFulfilled; - fn->onRejected.v = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function() { return elem.callbackThenVP(); }, - function() { elem.callbackRejectV(); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseDoubleFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.vp = onFulfilled; - fn->onRejected.d = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function() { return elem.callbackThenVP(); }, - function(v) { elem.callbackRejectD(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseStringFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.vp = onFulfilled; - fn->onRejected.s = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function() { return elem.callbackThenVP(); }, - function(v) { elem.callbackRejectS(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseObjectFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.vp = onFulfilled; - fn->onRejected.o = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function() { return elem.callbackThenVP(); }, - function(v) { elem.callbackRejectO(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.vp = onFulfilled; - fn->onRejected.vp = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function() { return elem.callbackThenVP(); }, - function() { return elem.callbackRejectVP(); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.vp = onFulfilled; - fn->onRejected.dp = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function() { return elem.callbackThenVP(); }, - function(v) { return elem.callbackRejectDP(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.vp = onFulfilled; - fn->onRejected.sp = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function() { return elem.callbackThenVP(); }, - function(v) { return elem.callbackRejectSP(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.vp = onFulfilled; - fn->onRejected.op = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function() { return elem.callbackThenVP(); }, - function(v) { return elem.callbackRejectOP(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseDoubleFunction onFulfilled) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.d = onFulfilled; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then(function(v) { elem.callbackThenD(v); }); - }, this); - return this; -} - -Promise *Promise::then(PromiseDoubleFunction onFulfilled, PromiseVoidFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.d = onFulfilled; - fn->onRejected.v = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function(v) { elem.callbackThenD(v); }, - function() { elem.callbackRejectV(); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseDoubleFunction onFulfilled, PromiseDoubleFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.d = onFulfilled; - fn->onRejected.d = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function(v) { elem.callbackThenD(v); }, - function(v) { elem.callbackRejectD(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseDoubleFunction onFulfilled, PromiseStringFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.d = onFulfilled; - fn->onRejected.s = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function(v) { elem.callbackThenD(v); }, - function(v) { elem.callbackRejectS(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseDoubleFunction onFulfilled, PromiseObjectFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.d = onFulfilled; - fn->onRejected.o = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function(v) { elem.callbackThenD(v); }, - function(v) { elem.callbackRejectO(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.dp = onFulfilled; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then(function(v) { return elem.callbackThenDP(v); }); - }, this); - return this; -} - -Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseVoidFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.dp = onFulfilled; - fn->onRejected.v = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function(v) { return elem.callbackThenDP(v); }, - function() { elem.callbackRejectV(); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseDoubleFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.dp = onFulfilled; - fn->onRejected.d = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function(v) { return elem.callbackThenDP(v); }, - function(v) { elem.callbackRejectD(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseStringFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.dp = onFulfilled; - fn->onRejected.s = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function(v) { return elem.callbackThenDP(v); }, - function(v) { elem.callbackRejectS(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseObjectFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.dp = onFulfilled; - fn->onRejected.o = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function(v) { return elem.callbackThenDP(v); }, - function(v) { elem.callbackRejectO(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.dp = onFulfilled; - fn->onRejected.vp = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function(v) { return elem.callbackThenDP(v); }, - function() { return elem.callbackRejectVP(); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.dp = onFulfilled; - fn->onRejected.dp = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function(v) { return elem.callbackThenDP(v); }, - function(v) { return elem.callbackRejectDP(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.dp = onFulfilled; - fn->onRejected.sp = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function(v) { return elem.callbackThenDP(v); }, - function(v) { return elem.callbackRejectSP(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.dp = onFulfilled; - fn->onRejected.op = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function(v) { return elem.callbackThenDP(v); }, - function(v) { return elem.callbackRejectOP(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseStringFunction onFulfilled) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.s = onFulfilled; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then(function(v) { elem.callbackThenS(v); }); - }, this); - return this; -} - -Promise *Promise::then(PromiseStringFunction onFulfilled, PromiseVoidFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.s = onFulfilled; - fn->onRejected.v = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function(v) { elem.callbackThenS(v); }, - function() { elem.callbackRejectV(); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseStringFunction onFulfilled, PromiseDoubleFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.s = onFulfilled; - fn->onRejected.d = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function(v) { elem.callbackThenS(v); }, - function(v) { elem.callbackRejectD(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseStringFunction onFulfilled, PromiseStringFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.s = onFulfilled; - fn->onRejected.s = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function(v) { elem.callbackThenS(v); }, - function(v) { elem.callbackRejectS(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseStringFunction onFulfilled, PromiseObjectFunction onRejected) +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.s = onFulfilled; - fn->onRejected.o = onRejected; + fn->onFulfilled.vp = onFulfilled; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); - elem._value.then( - function(v) { elem.callbackThenS(v); }, - function(v) { elem.callbackRejectO(v); } - ); + elem._value = elem._value.then(function() { return elem.callbackThenVP(); }); }, this); return this; } -Promise *Promise::then(PromiseStringPromiseFunction onFulfilled) +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.sp = onFulfilled; + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.vp = onRejected; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); - elem._value = elem._value.then(function(v) { return elem.callbackThenSP(v); }); + elem._value = elem._value.then( + function() { return elem.callbackThenVP(); }, + function() { return elem.callbackRejectVP(); } + ); }, this); return this; } -Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseVoidFunction onRejected) +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.sp = onFulfilled; - fn->onRejected.v = onRejected; + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.dp = onRejected; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); elem._value = elem._value.then( - function(v) { return elem.callbackThenSP(v); }, - function() { elem.callbackRejectV(); } + function() { return elem.callbackThenVP(); }, + function(v) { return elem.callbackRejectDP(v); } ); }, this); return this; } -Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseDoubleFunction onRejected) +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.sp = onFulfilled; - fn->onRejected.d = onRejected; + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.sp = onRejected; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); elem._value = elem._value.then( - function(v) { return elem.callbackThenSP(v); }, - function(v) { elem.callbackRejectD(v); } + function() { return elem.callbackThenVP(); }, + function(v) { return elem.callbackRejectSP(v); } ); }, this); return this; } -Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseStringFunction onRejected) +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.sp = onFulfilled; - fn->onRejected.s = onRejected; + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.op = onRejected; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); elem._value = elem._value.then( - function(v) { return elem.callbackThenSP(v); }, - function(v) { elem.callbackRejectS(v); } + function() { return elem.callbackThenVP(); }, + function(v) { return elem.callbackRejectOP(v); } ); }, this); return this; } -Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseObjectFunction onRejected) +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.sp = onFulfilled; - fn->onRejected.o = onRejected; + fn->onFulfilled.dp = onFulfilled; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function(v) { return elem.callbackThenSP(v); }, - function(v) { elem.callbackRejectO(v); } - ); + elem._value = elem._value.then(function(v) { return elem.callbackThenDP(v); }); }, this); return this; } -Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected) +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.sp = onFulfilled; + fn->onFulfilled.dp = onFulfilled; fn->onRejected.vp = onRejected; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); elem._value = elem._value.then( - function(v) { return elem.callbackThenSP(v); }, + function(v) { return elem.callbackThenDP(v); }, function() { return elem.callbackRejectVP(); } ); }, this); return this; } -Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected) +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.sp = onFulfilled; + fn->onFulfilled.dp = onFulfilled; fn->onRejected.dp = onRejected; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); elem._value = elem._value.then( - function(v) { return elem.callbackThenSP(v); }, + function(v) { return elem.callbackThenDP(v); }, function(v) { return elem.callbackRejectDP(v); } ); }, this); return this; } -Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected) +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.sp = onFulfilled; + fn->onFulfilled.dp = onFulfilled; fn->onRejected.sp = onRejected; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); elem._value = elem._value.then( - function(v) { return elem.callbackThenSP(v); }, + function(v) { return elem.callbackThenDP(v); }, function(v) { return elem.callbackRejectSP(v); } ); }, this); return this; } -Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected) +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.sp = onFulfilled; + fn->onFulfilled.dp = onFulfilled; fn->onRejected.op = onRejected; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); elem._value = elem._value.then( - function(v) { return elem.callbackThenSP(v); }, + function(v) { return elem.callbackThenDP(v); }, function(v) { return elem.callbackRejectOP(v); } ); }, this); return this; } -/* -Promise *Promise::then(PromiseObjectFunction onFulfilled) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.o = onFulfilled; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then(function(v) { elem.callbackThenO(v); }); - }, this); - return this; -} -*/ -Promise *Promise::then(PromiseObjectFunction onFulfilled, PromiseVoidFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.o = onFulfilled; - fn->onRejected.v = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function(v) { elem.callbackThenO(v); }, - function() { elem.callbackRejectV(); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseObjectFunction onFulfilled, PromiseDoubleFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.o = onFulfilled; - fn->onRejected.d = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function(v) { elem.callbackThenO(v); }, - function(v) { elem.callbackRejectD(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseObjectFunction onFulfilled, PromiseStringFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.o = onFulfilled; - fn->onRejected.s = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function(v) { elem.callbackThenO(v); }, - function(v) { elem.callbackRejectS(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseObjectFunction onFulfilled, PromiseObjectFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.o = onFulfilled; - fn->onRejected.o = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value.then( - function(v) { elem.callbackThenO(v); }, - function(v) { elem.callbackRejectO(v); } - ); - }, this); - return this; -} - -Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.op = onFulfilled; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then(function(v) { return elem.callbackThenOP(v); }); - }, this); - return this; -} - -Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseVoidFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.op = onFulfilled; - fn->onRejected.v = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function(v) { return elem.callbackThenOP(v); }, - function() { elem.callbackRejectV(); } - ); - }, this); - return this; -} -Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseDoubleFunction onRejected) +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.op = onFulfilled; - fn->onRejected.d = onRejected; + fn->onFulfilled.sp = onFulfilled; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function(v) { return elem.callbackThenOP(v); }, - function(v) { elem.callbackRejectD(v); } - ); + elem._value = elem._value.then(function(v) { return elem.callbackThenSP(v); }); }, this); return this; } -Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseStringFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.op = onFulfilled; - fn->onRejected.s = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function(v) { return elem.callbackThenOP(v); }, - function(v) { elem.callbackRejectS(v); } - ); - }, this); - return this; -} -Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseObjectFunction onRejected) -{ - auto fn = new PromiseChainFunction(); - fn->onFulfilled.op = onFulfilled; - fn->onRejected.o = onRejected; - this->chains.push_back(fn); - EM_ASM_({ - var elem = Module['toPromise']($0); - elem._value = elem._value.then( - function(v) { return elem.callbackThenOP(v); }, - function(v) { elem.callbackRejectO(v); } - ); - }, this); - return this; -} -Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected) +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.op = onFulfilled; + fn->onFulfilled.sp = onFulfilled; fn->onRejected.vp = onRejected; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); elem._value = elem._value.then( - function(v) { return elem.callbackThenOP(v); }, + function(v) { return elem.callbackThenSP(v); }, function() { return elem.callbackRejectVP(); } ); }, this); return this; } -Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected) +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.op = onFulfilled; + fn->onFulfilled.sp = onFulfilled; fn->onRejected.dp = onRejected; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); elem._value = elem._value.then( - function(v) { return elem.callbackThenOP(v); }, + function(v) { return elem.callbackThenSP(v); }, function(v) { return elem.callbackRejectDP(v); } ); }, this); return this; } -Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected) +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.op = onFulfilled; + fn->onFulfilled.sp = onFulfilled; fn->onRejected.sp = onRejected; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); elem._value = elem._value.then( - function(v) { return elem.callbackThenOP(v); }, + function(v) { return elem.callbackThenSP(v); }, function(v) { return elem.callbackRejectSP(v); } ); }, this); return this; } -Promise *Promise::then(PromiseObjectPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected) +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected) { auto fn = new PromiseChainFunction(); - fn->onFulfilled.op = onFulfilled; + fn->onFulfilled.sp = onFulfilled; fn->onRejected.op = onRejected; this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); elem._value = elem._value.then( - function(v) { return elem.callbackThenOP(); }, + function(v) { return elem.callbackThenSP(v); }, function(v) { return elem.callbackRejectOP(v); } ); }, this); return this; } -void Promise::callbackThenV() -{ - PromiseChainFunction *chain = this->chains[0]; - PromiseVoidFunction func = chain->onFulfilled.v; - func(); - this->chains.erase(this->chains.begin()); - delete chain; -} - -void Promise::callbackThenD(emscripten::val v) -{ - PromiseChainFunction *chain = this->chains[0]; - auto func = chain->onFulfilled.d; - func(v.as()); - this->chains.erase(this->chains.begin()); - delete chain; -} - -void Promise::callbackThenS(emscripten::val v) -{ - PromiseChainFunction *chain = this->chains[0]; - auto func = chain->onFulfilled.s; - func(v.as()); - this->chains.erase(this->chains.begin()); - delete chain; -} - -void Promise::callbackThenO(emscripten::val v) -{ - PromiseChainFunction *chain = this->chains[0]; - auto func = chain->onFulfilled.o; - func(Object(v)); - this->chains.erase(this->chains.begin()); - delete chain; -} - -void Promise::callbackRejectV() -{ - PromiseChainFunction *chain = this->chains[0]; - PromiseVoidFunction func = chain->onRejected.v; - func(); - this->chains.erase(this->chains.begin()); - delete chain; -} - -void Promise::callbackRejectD(emscripten::val v) -{ - PromiseChainFunction *chain = this->chains[0]; - auto func = chain->onRejected.d; - func(v.as()); - this->chains.erase(this->chains.begin()); - delete chain; -} - - -void Promise::callbackRejectS(emscripten::val v) -{ - PromiseChainFunction *chain = this->chains[0]; - auto func = chain->onRejected.s; - func(v.as()); - this->chains.erase(this->chains.begin()); - delete chain; -} - -void Promise::callbackRejectO(emscripten::val v) -{ - PromiseChainFunction *chain = this->chains[0]; - auto func = chain->onRejected.o; - func(Object(v)); - this->chains.erase(this->chains.begin()); - delete chain; -} - emscripten::val Promise::callbackThenVP() { PromiseChainFunction *chain = this->chains[0]; @@ -1383,6 +676,9 @@ emscripten::val Promise::callbackThenVP() Promise *p = func(); this->chains.erase(this->chains.begin()); delete chain; + if (p == nullptr) { + return emscripten::val(0); + } return p->v; } @@ -1393,6 +689,9 @@ emscripten::val Promise::callbackThenDP(emscripten::val v) Promise *p = func(v.as()); this->chains.erase(this->chains.begin()); delete chain; + if (p == nullptr) { + return emscripten::val(0); + } return p->v; } @@ -1403,6 +702,9 @@ emscripten::val Promise::callbackThenSP(emscripten::val v) Promise *p = func(v.as()); this->chains.erase(this->chains.begin()); delete chain; + if (p == nullptr) { + return emscripten::val(0); + } return p->v; } @@ -1426,6 +728,9 @@ emscripten::val Promise::callbackRejectVP() Promise *p = func(); this->chains.erase(this->chains.begin()); delete chain; + if (p == nullptr) { + return emscripten::val(0); + } return p->v; } @@ -1436,6 +741,9 @@ emscripten::val Promise::callbackRejectDP(emscripten::val v) Promise *p = func(v.as()); this->chains.erase(this->chains.begin()); delete chain; + if (p == nullptr) { + return emscripten::val(0); + } return p->v; } @@ -1446,6 +754,9 @@ emscripten::val Promise::callbackRejectSP(emscripten::val v) Promise *p = func(v.as()); this->chains.erase(this->chains.begin()); delete chain; + if (p == nullptr) { + return emscripten::val(0); + } return p->v; } @@ -1456,17 +767,12 @@ emscripten::val Promise::callbackRejectOP(emscripten::val v) Promise *p = func(Object(v)); this->chains.erase(this->chains.begin()); delete chain; + if (p == nullptr) { + return emscripten::val(0); + } return p->v; } -HTML5_BIND_METHOD(Promise, callbackThenV); -HTML5_BIND_METHOD(Promise, callbackThenD); -HTML5_BIND_METHOD(Promise, callbackThenS); -HTML5_BIND_METHOD(Promise, callbackThenO); -HTML5_BIND_METHOD(Promise, callbackRejectV); -HTML5_BIND_METHOD(Promise, callbackRejectD); -HTML5_BIND_METHOD(Promise, callbackRejectS); -HTML5_BIND_METHOD(Promise, callbackRejectO); HTML5_BIND_METHOD(Promise, callbackThenVP); HTML5_BIND_METHOD(Promise, callbackThenDP); HTML5_BIND_METHOD(Promise, callbackThenSP); From e16f829dbddc64f678b93bf292992206f3769e37 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Thu, 11 Jul 2019 15:20:13 +0900 Subject: [PATCH 5/7] support catch/finally for Promise --- examples/promise.cc | 6 +++ include/promise.h | 12 +++++ src/promise.cc | 112 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) diff --git a/examples/promise.cc b/examples/promise.cc index a56b9d5..617ed74 100644 --- a/examples/promise.cc +++ b/examples/promise.cc @@ -31,6 +31,12 @@ static void fetchTest() }; reader->readAsDataURL(blob); return nullptr; + })->catchError([]{ + html5::window->console->log("catch"); + return nullptr; + })->finally([]{ + html5::window->console->log("finally"); + return nullptr; }); } diff --git a/include/promise.h b/include/promise.h index 3816718..7455183 100644 --- a/include/promise.h +++ b/include/promise.h @@ -155,6 +155,11 @@ class Promise : public Object { }, this); return this; }; + Promise *catchError(PromiseVoidPromiseFunction onRejected); + Promise *catchError(PromiseDoublePromiseFunction onRejected); + Promise *catchError(PromiseStringPromiseFunction onRejected); + Promise *catchError(PromiseObjectPromiseFunction onRejected); + Promise *finally(PromiseVoidPromiseFunction onFinally); Promise *all(std::vector iterable); Promise *race(std::vector iterable); Promise *reject(std::string reason); @@ -196,6 +201,8 @@ class Promise : public Object { }; std::vector chains; + PromiseFunction catchErrorFn; + PromiseFunction finallyFn; void callbackVV(emscripten::val resolve, emscripten::val reject); void callbackVD(emscripten::val resolve, emscripten::val reject); void callbackVS(emscripten::val resolve, emscripten::val reject); @@ -228,6 +235,11 @@ class Promise : public Object { emscripten::val callbackRejectDP(emscripten::val v); emscripten::val callbackRejectSP(emscripten::val v); emscripten::val callbackRejectOP(emscripten::val v); + emscripten::val callbackCatchVP(); + emscripten::val callbackCatchDP(emscripten::val v); + emscripten::val callbackCatchSP(emscripten::val v); + emscripten::val callbackCatchOP(emscripten::val v); + emscripten::val callbackFinally(); }; NAMESPACE_HTML5_END; diff --git a/src/promise.cc b/src/promise.cc index f486c7c..81653af 100644 --- a/src/promise.cc +++ b/src/promise.cc @@ -782,5 +782,117 @@ HTML5_BIND_METHOD(Promise, callbackRejectDP); HTML5_BIND_METHOD(Promise, callbackRejectSP); HTML5_BIND_METHOD(Promise, callbackRejectOP); + +Promise *Promise::catchError(PromiseVoidPromiseFunction onRejected) +{ + this->catchErrorFn.vp = onRejected; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.catch( + function() { return elem.callbackCatchVP(); } + ); + }, this); + return this; +} + +Promise *Promise::catchError(PromiseDoublePromiseFunction onRejected) +{ + this->catchErrorFn.dp = onRejected; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.catch( + function(v) { return elem.callbackCatchDP(v); } + ); + }, this); + return this; +} + +Promise *Promise::catchError(PromiseStringPromiseFunction onRejected) +{ + this->catchErrorFn.sp = onRejected; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.catch( + function(v) { return elem.callbackCatchSP(v); } + ); + }, this); + return this; +} + +Promise *Promise::catchError(PromiseObjectPromiseFunction onRejected) +{ + this->catchErrorFn.op = onRejected; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.catch( + function(v) { return elem.callbackCatchOP(v); } + ); + }, this); + return this; +} + +Promise *Promise::finally(PromiseVoidPromiseFunction onFinally) +{ + this->finallyFn.vp = onFinally; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.finally( + function() { return elem.callbackFinally(); } + ); + }, this); + return this; +} + +emscripten::val Promise::callbackCatchVP() +{ + Promise *p = this->catchErrorFn.vp(); + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackCatchDP(emscripten::val v) +{ + Promise *p = this->catchErrorFn.dp(v.as()); + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackCatchSP(emscripten::val v) +{ + Promise *p = this->catchErrorFn.sp(v.as()); + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackCatchOP(emscripten::val v) +{ + Promise *p = this->catchErrorFn.op(Object(v)); + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackFinally() +{ + Promise *p = this->finallyFn.vp(); + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +HTML5_BIND_METHOD(Promise, callbackCatchVP); +HTML5_BIND_METHOD(Promise, callbackCatchDP); +HTML5_BIND_METHOD(Promise, callbackCatchSP); +HTML5_BIND_METHOD(Promise, callbackCatchOP); +HTML5_BIND_METHOD(Promise, callbackFinally); + HTML5_PROPERTY_IMPL(Promise, unsigned long, length); From c2869b74a68b296e9000776b51fba5bc0300f0cb Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Thu, 11 Jul 2019 15:37:49 +0900 Subject: [PATCH 6/7] support static method for Promise --- examples/promise.cc | 5 +++- include/promise.h | 16 ++++++++---- src/promise.cc | 63 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 6 deletions(-) diff --git a/examples/promise.cc b/examples/promise.cc index 617ed74..e69772d 100644 --- a/examples/promise.cc +++ b/examples/promise.cc @@ -10,7 +10,10 @@ static void promiseTest() }); promise->then([](const std::string &value) { html5::window->console->log(value); - return nullptr; + return html5::Promise::resolve("bar"); + })->then([](const std::string &value) { + html5::window->console->log(value); + return html5::Promise::resolve(0.0); }); html5::window->console->log(promise); } diff --git a/include/promise.h b/include/promise.h index 7455183..d2d0404 100644 --- a/include/promise.h +++ b/include/promise.h @@ -160,11 +160,17 @@ class Promise : public Object { Promise *catchError(PromiseStringPromiseFunction onRejected); Promise *catchError(PromiseObjectPromiseFunction onRejected); Promise *finally(PromiseVoidPromiseFunction onFinally); - Promise *all(std::vector iterable); - Promise *race(std::vector iterable); - Promise *reject(std::string reason); - Promise *resolve(void *value); - Promise *pcatch(std::function onRejected); + + static Promise *all(std::vector iterable); + static Promise *race(std::vector iterable); + static Promise *reject(); + static Promise *reject(double value); + static Promise *reject(const std::string &value); + static Promise *reject(Object *value); + static Promise *resolve(); + static Promise *resolve(double value); + static Promise *resolve(const std::string &value); + static Promise *resolve(Object *value); PromiseVoidVoidPairFunction vvPairFn; PromiseVoidDoublePairFunction vdPairFn; diff --git a/src/promise.cc b/src/promise.cc index 81653af..9a286af 100644 --- a/src/promise.cc +++ b/src/promise.cc @@ -894,5 +894,68 @@ HTML5_BIND_METHOD(Promise, callbackCatchSP); HTML5_BIND_METHOD(Promise, callbackCatchOP); HTML5_BIND_METHOD(Promise, callbackFinally); + +Promise *Promise::all(std::vector iterable) +{ + emscripten::val array = toJSArray(iterable); + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, all, array)); +} + +Promise *Promise::race(std::vector iterable) +{ + emscripten::val array = toJSArray(iterable); + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, race, array)); +} + +Promise *Promise::reject() +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, reject)); +} + +Promise *Promise::reject(double value) +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, reject, value)); +} + +Promise *Promise::reject(const std::string &value) +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, reject, value)); +} + +Promise *Promise::reject(Object *value) +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, reject, value->v)); +} + +Promise *Promise::resolve() +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, resolve)); +} + +Promise *Promise::resolve(double value) +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, resolve, value)); +} + +Promise *Promise::resolve(const std::string &value) +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, resolve, value)); +} + +Promise *Promise::resolve(Object *value) +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, resolve, value->v)); +} + HTML5_PROPERTY_IMPL(Promise, unsigned long, length); From 1e3273b357eaf877836bf91f4004b5fbc678b713 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Thu, 11 Jul 2019 16:00:48 +0900 Subject: [PATCH 7/7] fix example --- examples/promise.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/promise.cc b/examples/promise.cc index e69772d..b8fbd27 100644 --- a/examples/promise.cc +++ b/examples/promise.cc @@ -18,11 +18,10 @@ static void promiseTest() html5::window->console->log(promise); } -static void fetchTest() +static void fetchImageTest(const std::string &imageURL) { HTML5_INIT(); - std::string url = "http://localhost/test/free.jpg"; - html5::fetch(url)->then([](html5::Response *response) { + html5::fetch(imageURL)->then([](html5::Response *response) { return response->blob(); })->then([](html5::Blob *blob) { auto reader = html5::FileReader::create(); @@ -45,5 +44,5 @@ static void fetchTest() EMSCRIPTEN_BINDINGS(Promise) { emscripten::function("promiseTest", &promiseTest); - emscripten::function("fetchTest", &fetchTest); + emscripten::function("fetchImageTest", &fetchImageTest); }