We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I'm trying to write a p5 library that creates a new object. On loadObject function I need 2 parameters.
When I register the function to be used at preload, I notice that the 2nd parameter is of type function no matter what I do..
So, the 2nd and 3rd parameters are considered callback and callbackerror functions?
Beside turning the first parameter into an array, are there any other way to serve two parameters to a preload function?
Can a function not registered as a preload method be used at preload?
Am I doing any sense?
Answers
https://GitHub.com/processing/p5.js/wiki/Libraries
I already read it (by the way, registerPreloadMethod('loadSound', 'p5') is wrong: p5 is not a string).
I also looked at the source code, but it's too advanced for someone without previous experience on javascript like me.
I'm looking for some guidance.
I've got no experience in library dev either. 8-|
But you're spot on about registerPreloadMethod()'s 2nd parameter not being a String.
It's instead the prototype object where the registered method (1st parameter) belongs to:
https://GitHub.com/processing/p5.js/blob/master/src/core/core.js#L531
Also I've spotted another mistake at the same sentence:
https://GitHub.com/processing/p5.js/wiki/Libraries#use-registerpreloadmethod-to-register-names-of-methods-with-p5-that-may-be-called-in-preload
"(defaults to p5)" is no longer true anymore b/c
obj = obj || p5.prototype;
is commented out.It means the 2nd parameter is obligatory too. Moreover it was p5.prototype, not just p5. b-(
P.S.: I've corrected that wiki just now! :ar!
Anyways, you should study how other libraries use registerPreloadMethod(): :-B
https://GitHub.com/processing/p5.js-sound/blob/master/src/soundfile.js#L140
https://GitHub.com/processing/p5.js-sound/blob/master/src/soundfile.js#L176
Perhaps my doubts are related to some incoherence on registerPreloadMethod, like in https://github.com/processing/p5.js/issues/1229.
For now, it seems I can't use more than one argument.
Of course you're right. The link is about callback functions.
My weirdness derive from the fact that my 2nd parameter, that should be a string, suddenly turns to a function when I do registerPreloadMethod().
I don't understand the magic involved. :((
Time to move on. I'll keep studying.
Thank you for your time.
I'll be back...
Just some last explanation attempt: registerPreloadMethod() does nothing more than append an extra entry to object _preloadMethods.
It's already pre-initialized this way: https://GitHub.com/processing/p5.js/blob/master/src/core/core.js#L517
Something like
p5.prototype.registerPreloadMethod('loadSound', p5.prototype);
merely adds this following entry to _preloadMethods:{ loadSound: p5.prototype }
Now that I cleared my head, let me explain what happened:
I created a loadX function that return a X object.
I added it to preload methods.
Unlike other preload methods, this function needs 2 parameters (string, string), BUT, and this was where I messed up, the 2nd was optional with a default value.
_wrapPreload add _decrementPreload() after the last parameter. My mistake was to think that all defined parameters where considered. Instead, only the "real" parameters (used when calling the function) are counted. My 2nd optional parameter was replaced by _decrementPreload() function.
Bottom line: preload methods can't use optional parameters.
Thanks for your patience. Now I know a little more magic. :)>-
I confess I still dunno how the preload() voodoo stuff actually works.
But they seem to accept optional parameters. For example loadTable():
http://p5js.org/reference/#/p5/loadTable
Yes. But in LoadTable() all parameters are read in a for loop and tested against "function" type.
I was using optional parameters "by the book": function(a, b = 1).
It doesn't work this way.
Without seeing your code (or even your environment*) it's hard to see what the problem is. If for whatever reason you really can only have a single argument (the docs don't suggest this is the case) could you pass in an object? That's fairly standard in JS, since it's so easy to create them on the fly:
* Note that default arguments are a new feature in JS so may not be supported by your browser; and are perhaps not supported by the p5js registerPreload method - so that could also be the root of your problem.
After understand a little more about callbacks and preload(), GoToLoop link to loadTable was what I needed. My main function is like this:
and it works!
So I moved to the next problem.
Thank you all!
Seems like your loadX() got multiple signatures.
Here's a quick tweaked version. Dunno whether it exactly matches the same behavior as yours though:
That could work.
What I learned is that a preload method ALWAYS have a callback function. So, in this special case,
if (typeof(callback) === 'function') callback(x);
is necessary. callback will be a explicitly written callback function OR the added _decrementPreload(). Without calling it back, you don't get out of preload().I never coded on a language that gives so much rope to hang on, and I'm not starting to talk about async... :))
On top of that, p5 is great, and I'm sure I will finish my library in the next few days.
@GoToLoop: since it seems you can rely on there always being a callback function this should suffice:
@linuxman:
JS is special :(|)
I've been recommending the You don't know JS books a lot here lately: they do a good job of explaining some of the language's supposed idiosyncrasies; and also its flexibility :-B
@blindfish, I was trying to stay as much close to @linuxman's solution. :\">
Nonetheless, here comes another over complicated (w/o any
if ()
blocks) but shorter solution: :ar!That's hardly true. When using preload(), passing a callback is usually pointless: :-B
http://p5js.org/reference/#/p5/preload
That's why we still need to make sure callback parameter is indeed a
function
before invoking it: L-)typeof callback === 'function' && callback(x)
if (typeof callback === 'function') callback(x)
Yesterday I finished my library (it's a port of Processing Ptmx).
Now I'm working on some examples and soon I'll upload it to github. :)
I decided to stick with arguments[] and embrace JS flexibility. With 4 parameters (3 optional), load method looks like this:
In fact, since all optional arguments are of different types, they are interchangeable, but who cares? ;)
Also, I shouldn't need to test callback function, but it's better be safe than sorry. Someone can call loadTiledMap outside preload without a callback function.
Finally it's done!
p5.tiledmap - Add Tiled maps to p5.js - can be found at https://github.com/linux-man/p5.tiledmap.
Your feedback is highly appreciated.
Thanks for all the support.