-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
About time to provide a consistent asynchronous API for loading stuff in both Java and JavaScript mode #3075
Comments
I would be willing to attempt to tackle this on the Java side if @benfry thinks that these methods can be added without breaking things. I think processing 3 would be a good time to add these functions. I think that simply naming them something like For the callback we could either write it to use traditional Java callbacks (small interface implementation classes) or since Processing 3 uses Java8 lambdas could possibly be used. |
Actually, looking at the docs, the implementation would be essentially the same, passing a Runnable as the callback. |
This sound like a change that would be worth committing as a backward-compatibility-breaking API change. Using names like "asyncLoadStrings" will lead to a dense API that will be hard to understand in terms of what one "should" use versus what is available. Passing a runnable is a nice idea from a java perspective, but not a very nice one from a Processing perspective: it makes things a lot harder for people who come to Processing because it's supposed to be easy, not hard. Especially with an eye towards things like processing.js and processing.py, making sure to bake in as little explicit Java is always worth it, so if I could make a recommendation, I'd use event handling to solve this:
This way you keep it simple -and more importantly, Processy- while maintaining the same concepts you're already teaching users. Any Another benefit is that you might even be able to keep the functions doing "what they did before" while also supporting the new behaviour, yielding a PImage synchronously as well as calling the |
I agree that it must be kept simple, and also take into account that the mechanism needs to be easy to port to ProcessingJS. Async loading in JS is ridiculously easy (it's how JS behaves by default, actually ProcessingJS is crippling itself to keep it synchronous for the sake of compatibility with Processing), so anything too Java-specific and too convoluted would be a great obstacle to port it to ProcessingJS. I don't know about Lambdas in Java, so I can't argue whether that's a good idea or not. Care must be taken, however, with "too-simple" solutions. If I understand correctly Pomax's suggestion, it would be something like:
That (unless it's just an oversimplified description) is a BAD pattern which, if I'm not mistaken, has been used pretty much in Processing (I don't remember an example right now, but I think I've seen it a few times, and suffered from its limitations).
The latter is perhaps acceptable, anyway. But care must be taken to avoid (1). Maybe the solution is just to allow the loadWhatever() method to take a parameter which is a map (of arbitrary key-value pairs), which will be passed to the callback together with the loaded data. Regarding BC, I agree that it's worth breaking it here if necessary. Processing breaks BC all the time anyway, for things much less worth it. (I rarely upgraded processing without seeing all my old sketches break) However, perhaps it may even possible to avoid it. |
I also am not a huge fan of the I also understand the desire to avoid Java-esque solutions that are more complicated than standard Processing. But I think (haven't done much with it) the standard way of handling asynchronous tasks in JavaScript is also a callback function. Maybe the correct solution to avoid API bloat is to keep the original name and add an asynchronous method with the same name and added parameters like @teo1978 suggests. This would give a method signature that might look something like this Calling the function with an old school interface implementation is a bit syntactically ugly, but using a lambda (which are strange looking at first) makes it a little better //old version ( <= Java 7)
loadStrings("someString",new Callback() {
public void done(String[] strings){
//do work with strings
}
});
//new version (>= Java 8)
loadStrings("someString",(String[] strings)->{
//do work with strings
}); I don't think that the lambda version is difficult to read, but I've programmed in Java for a while so I'm definitely biased. I think that this also is closer to JavaScript's asynchronous method handling which usually looks something like this loadStrings("someString", function(strings) {
//do work with strings
}); |
If that's what a lambda is in Java (sorry for the ignorance) that looks to me like the PERFECT solution. Clean, simple and flexible. It's only the syntax (strictly speaking, i.e. the very graphical signs used) that is a bit funny. |
Perhaps it is not very "Processy" but that's because the "Processy" way (predetermined callback names for methods defined in the sketch) has never been a good way in the first place (it was only viable as long as sketchs kept small with no ambition to scale). I wish this becomes the new "Processy" way. |
@teo1978 It looks like you'd like to file a feature request about adding API for asynchronous IO. If so, please do so. API extensions for asynchronous IO were worked out for 2.x but I didn't have time to finish the implementation and more importantly, test it properly. Since it's not documented publicly, an issue would give us a way to do that. I'm closing this thread because it's an unnecessarily long-winded rant toward people you haven't met about topics you don't seem to fully understand. It has no place here, because it's not a helpful starting point for a request or a discussion for me (who would be in charge of this implementation) or any of the other volunteers who help make this project happen. The attitude is unnecessary and has no place in the community that we've built around this project. |
Moved here: #3165 |
The fact that basic operations loading data such as loadStrings or loadImage (to name just a couple) are synchronous has always been a poor design choice and a crippling limitation in Processing (an asyncronous interface based on callbacks could have been provided since the very beginning), but it's understandable given that Processing was born based on Java and given the work it requires to handle the threading.
But now it is becoming an unforgivable anachronysm.
JavaScript mode has since long become the only way (and a wonderful way) of publishing sketches on the web, and it would be foolish to not consider exporting sketches in JavaScript mode as the primary way, or at least an essential and indispensable way, of sharing Processing sketches.
JavaScript's data loading operations as you well know are asynchronous by default. Processing JS forces them to be synchronous just to ensure compatibility of sketches between JavaScript and Java mode, but having them asynchronous would be trivial in Processing JS if it hadn't had to emulate Java-Processing's behavior.
So, the time has definitely come (about a few years ago) to switch to a seamless, transparent asynchronous callback-based loading mechanism for all the built-in functions and classes that load stuff in Processing, in a way that will be consistent across Java and JavaScript modes.
This should apply to loadStrings(), loadImage(), loadXML() (which by the way has other critical java-vs-javascript incompatibility issues that I've reported long ago and have sadly been ignored, but that's entirely on the ProcessingJS side) and whatever else loads data.
This should have been done already long, long ago, but now it's becoming URGENT as this message shows up in any browser when running a Processing sketch (any that loads data):
That means that soon enough Processing JS will become totally BROKEN; and since exporting Java applets has been dropped long ago, it will become impossible to publish practically any Processing sketch online. That would be awful, if the current situation is not bad enough.
The text was updated successfully, but these errors were encountered: