fix builtin global accessors for instance mode in strands shaders#8878
Conversation
| const sym = Symbol(`_strands_${name}`) | ||
|
|
||
| // Define on window for global mode | ||
| Object.defineProperty(window, name, { |
There was a problem hiding this comment.
I think we need to check _isGlobal here, to avoid adding accessors to the global window object on instance mode.
There was a problem hiding this comment.
thanks for catching it @eupthere, I've added the _isGlobal check so we only define window accessors in global mode now. Also updated the tests to use instance access (myp5.width instead of window.width) since the test framework runs in instance mode anyway.
|
|
||
| // For data properties (like mouseX), save the initial value into Symbol-keyed store | ||
| if (originalProtoDesc && 'value' in originalProtoDesc) { | ||
| strandsContext.p5.prototype[sym] = originalProtoDesc.value; |
There was a problem hiding this comment.
Is there a reason for using a symbol here as opposed to a string?
There was a problem hiding this comment.
Using a symbol here to avoid any chance of colliding with existing properties on the instance/prototype. A string like _strands_mouseX would also work, but symbols are guaranteed to be unique and stay out of things like Object.keys() and for...in, so the backing store remains hidden.
happy to switch to strings if you think that's simpler 🙂
There was a problem hiding this comment.
Do they need to be stored on the prototype? Elsewhere we store this on strandsContext.fnOverrides, e.g.:
p5.js/src/strands/strands_api.js
Line 143 in 82135bb
fn in addons is a shortcut to p5.prototype, so it seems like maybe this should be using that same system.
There was a problem hiding this comment.
switched to storing the original descriptors on strandsContext.fnOverrides instead of the prototype, and also switched from Symbol to a string key for the per-instance backing store, it should be cleaner now.
| //In instance mode, myp5.mouseX and myp5.width should return strands nodes | ||
| const mxInHook = myp5.mouseX; | ||
| const wInHook = myp5.width; | ||
| assert.isTrue(mxInHook.isStrandsNode); |
|
Hi @davepagurek, I added the Also moved the original descriptor storage to |
…ys for backing store
|
Also, the earlier CI failure was in |
|
One thing around p5.js/src/strands/p5.strands.js Lines 32 to 87 in 82135bb Currently we use special keys, so it doesn't quite work as expected -- it'd be adding things to |
|
@davepagurek yes you're right I've removed the |
davepagurek
left a comment
There was a problem hiding this comment.
Thanks for the updates, looks good!
Resolves #8877
Changes:
Fixed
installBuiltinGlobalAccessorsinstrands_api.jsso that the builtin globals likemouseXandwidthwork correctly in instance mode when used inside strands shader callbacks.Previously only
window.mouseXwas intercepted, so in instance mode (p.mouseX), the values got hardcoded into the shader instead of becoming live uniforms.Now the function also installs property interceptors on
p5.prototypeandp5.Graphics.prototype. It correctly handles both data properties (likemouseX) and getter based properties (likewidth, which delegates tothis._renderer?.width) by saving the original property descriptor and delegating to it when strands isn't active.Also I've added a unit test that verifies
myp5.mouseXandmyp5.widthreturn strands nodes inside hooks and normal numbers outside.PR Checklist
npm run lintpasses