The syntax is a little different, but the C++11 promise/future template offers essentially the same functionality. See http://www.cplusplus.com/reference/future/promise/ for the usage of this, and http://promises-aplus.github.io/promises-spec/ for the proposed Javascript spec. On Mar 17, 2014 3:16 PM, "Alon Zakai" <[email protected]> wrote:
> I didn't know about the JavaScript Promises stuff, that's interesting. To > allow sync-looking code on the C++ side, it would need to integrate with > something there, if there is a c++11 feature that works there, as you say, > then this might work very well. > > - Alon > > > > On Sun, Mar 16, 2014 at 11:44 PM, Joel Croteau <[email protected]> wrote: > >> I was able to implement this using Javascript Promises (I haven't made >> this a pull request because it's rather experimental): >> >> emscripten_sync_wget2_data: function(url, request, param, arg, free, >> onload, onerror, onprogress) { >> var _url = Pointer_stringify(url); >> var _request = Pointer_stringify(request); >> var _param = Pointer_stringify(param); >> >> var promise = new Promise(function(resolve, reject) { >> var http = new XMLHttpRequest(); >> http.open(_request, _url, true); >> http.responseType = 'arraybuffer'; >> >> // LOAD >> http.onload = function http_onload(e) { >> if (http.status == 200 || _url.substr(0,4).toLowerCase() != >> "http") { >> resolve(http.response); >> } >> else { >> reject(http.status, http.statusText); >> } >> }; >> >> // ERROR >> http.onerror = function http_onerror(e) { >> reject(http.status, http.statusText); >> }; >> >> // PROGRESS >> http.onprogress = function http_onprogress(e) { >> if (onprogress) Runtime.dynCall('viii', onprogress, [arg, >> e.loaded, e.lengthComputable || e.lengthComputable === undefined ? e.total >> : 0]); >> }; >> >> // Useful because the browser can limit the number of redirection >> try { >> if (http.channel instanceof Ci.nsIHttpChannel) >> http.channel.redirectionLimit = 0; >> } catch (ex) { /* whatever */ } >> >> if (_request == "POST") { >> //Send the proper header information along with the request >> http.setRequestHeader("Content-type", >> "application/x-www-form-urlencoded"); >> http.setRequestHeader("Content-length", _param.length); >> http.setRequestHeader("Connection", "close"); >> http.send(_param); >> } else { >> http.send(null); >> } >> }); >> >> promise.then(function(data) { >> var byteArray = new Uint8Array(data); >> var buffer = _malloc(byteArray.length); >> HEAPU8.set(byteArray, buffer); >> if (onload) Runtime.dynCall('viii', onload, [arg, buffer, >> byteArray.length]); >> if (free) _free(buffer); >> }, function(status, statusText) { >> if (onerror) Runtime.dynCall('viii', onerror, [arg, status, >> statusText]); >> }); >> }, >> >> Promises are still fairly new, and only supported by the most recent >> versions of Chrome and Firefox, but they do give us the functionality we >> want here. I think the best way to implement this in code would be if I >> could use the C++ promise and future APIs. You can use these if you compile >> with -std=c++11. All this seems to do at present is send the code into an >> infinite loop, but if they could map into equivalent Javascript promise >> calls, I think it could work quite well. At least in the case of >> emscripten_sync_wget2_data, it could be set to use synchronous XHRs as a >> fallback. This would still work, just require some extra conversion work, >> and wouldn't call onprogress events. >> >> On Sunday, March 16, 2014 7:17:56 PM UTC-7, Alon Zakai wrote: >> >>> It can capture its environment, so you can put the second half of the >>> function in a lambda, and call the lambda later on when you want to, in >>> response to something. >>> >>> - Alon >>> >>> >>> >>> On Sun, Mar 16, 2014 at 7:12 PM, Joel Croteau <[email protected]> wrote: >>> >>>> I can understand using Javascript generators, but how would c++ >>>> lambdas help? >>>> On Mar 16, 2014 3:47 PM, "Alon Zakai" <[email protected]> wrote: >>>> >>>>> Currently not. It would require a very different code generation >>>>> approach than we currently have. >>>>> >>>>> In theory something similar could be done using generators, in very >>>>> recent versions of firefox and chrome. But even with the help of >>>>> generators, this is not easy to do, and it is not clear how it would >>>>> affect >>>>> performance - likely very adversely. >>>>> >>>>> One similar thing you can do is manage your own code using c++11 >>>>> lambdas. You could write a little system that continues to run the current >>>>> function once a callback triggers that. >>>>> >>>>> - Alon >>>>> >>>>> >>>>> >>>>> On Sun, Mar 16, 2014 at 1:43 AM, Joel Croteau <[email protected]>wrote: >>>>> >>>>>> I would like to have a function that makes an async call, and returns >>>>>> control to the browser during the call, then resumes once the async call >>>>>> is >>>>>> complete. However, I would like this to appear to the calling code to be >>>>>> a >>>>>> synchronous call. So for instance, I could do something like this: >>>>>> >>>>>> struct FileInfo >>>>>> { >>>>>> void* buffer; >>>>>> unsigned size; >>>>>> }; >>>>>> >>>>>> FileInfo loadUrl(const char* url) >>>>>> { >>>>>> FileInfo info; >>>>>> emscripten_async_wget2_data(url, "GET", "", &info, false, >>>>>> onload, onerror, onprogress); >>>>>> emscripten_pause(); // Blocks until emscripten_resume() is called >>>>>> return info; >>>>>> } >>>>>> >>>>>> void onerror(void* ptr, int code, const char* desc) >>>>>> { >>>>>> // Handle not found, etc. >>>>>> } >>>>>> >>>>>> void onprogress(void* ptr, int loaded, int total) >>>>>> { >>>>>> // Update progress bar >>>>>> } >>>>>> >>>>>> void onload(void* ptr, void* buffer, unsigned size) >>>>>> { >>>>>> static_cast<FileInfo*>(ptr)->buffer = buffer; >>>>>> static_cast<FileInfo*>(ptr)->size = size; >>>>>> >>>>>> emscripten_resume(); // Now loadUrl resumes and returns FileInfo. >>>>>> } >>>>>> >>>>>> Is there any way to do this? >>>>>> >>>>>> -- >>>>>> You received this message because you are subscribed to the Google >>>>>> Groups "emscripten-discuss" group. >>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>> send an email to [email protected]. >>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>> >>>>> >>>>> -- >>>>> You received this message because you are subscribed to a topic in the >>>>> Google Groups "emscripten-discuss" group. >>>>> To unsubscribe from this topic, visit https://groups.google.com/d/ >>>>> topic/emscripten-discuss/Op5ifeMjauA/unsubscribe. >>>>> To unsubscribe from this group and all its topics, send an email to >>>>> [email protected]. >>>>> >>>>> For more options, visit https://groups.google.com/d/optout. >>>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "emscripten-discuss" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to [email protected]. >>>> For more options, visit https://groups.google.com/d/optout. >>>> >>> >>> -- >> You received this message because you are subscribed to the Google Groups >> "emscripten-discuss" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> For more options, visit https://groups.google.com/d/optout. >> > > -- > You received this message because you are subscribed to a topic in the > Google Groups "emscripten-discuss" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/emscripten-discuss/Op5ifeMjauA/unsubscribe > . > To unsubscribe from this group and all its topics, send an email to > [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "emscripten-discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
