Skip to content

[p5.js 2.0+ Bug Report]: Add a productive error when loop protection is going to break a p5.strands for loop #8721

@davepagurek

Description

@davepagurek

Most appropriate sub-area of p5.js?

  • Accessibility
  • Color
  • Core/Environment/Rendering
  • Data
  • DOM
  • Events
  • Image
  • IO
  • Math
  • Typography
  • Utilities
  • WebGL
  • WebGPU
  • p5.strands
  • Build process
  • Unit testing
  • Internationalization
  • Friendly errors
  • Other (specify if possible)

p5.js version

2.2.3

Web browser and version

All

Operating system

All

Steps to reproduce this

Steps:

  1. Make a new sketch on the p5 web editor
  2. Make a p5.strands shader
  3. Include a for loop

When you run it, you'll get an error like:

Error: [p5.strands internal error]: undefined code generation not implemented yet

It goes away if you add this to the top of your sketch:

// noprotect

Without the noprotect comment, if you add a debugger at the top of your sketch and then run your sketch with the debugger open, you'll see how it gets transpiled:

OriginalTranspiled
function doBlur() {
  filterColor.begin()
  let total = [0, 0, 0, 0]
  for (let i = 0; i < 20; i++) {
    total += getTexture(
      filterColor.canvasContent,
      filterColor.texCoord + 15 * [
        cos(i/20 * TWO_PI),
        sin(i/20 * TWO_PI)
      ] / filterColor.canvasSize
    )
  }
  let avg = total / 20
  filterColor.set(avg)
  filterColor.end()
}
function doBlur() {
  filterColor.begin()
  let total = [0, 0, 0, 0]
  {;loopProtect.protect({ line: 11, reset: true }); for (let i = 0; i < 20; i++) {;if (loopProtect.protect({ line: 11 })) break;
    total += getTexture(
      filterColor.canvasContent,
      filterColor.texCoord + 15 * [
        cos(i/20 * TWO_PI),
        sin(i/20 * TWO_PI)
      ] / filterColor.canvasSize
    )
  }}
  let avg = total / 20
  filterColor.set(avg)
  filterColor.end()
}

The loopProtect code causes it to break. Something similar happens on OpenProcessing:

function doBlur() {
  filterColor.begin()
  let total = [0, 0, 0, 0]
  for (let i = 0; i < 20; i++) {window.$OP && $OP.loopProtect({line: 11,ch: 2}); 
    total += getTexture(
      filterColor.canvasContent,
      filterColor.texCoord + 15 * [
        cos(i/20 * TWO_PI),
        sin(i/20 * TWO_PI)
      ] / filterColor.canvasSize
    )
  }
  let avg = total / 20
  filterColor.set(avg)
  filterColor.end()
}

This gives the error:

window.$OP.and is not a function

What to do about it

Other than making loop protection smarter on the platforms running your code, it would be great to detect when loop protection has been added to a p5.strands function and throw an error immediately with info on how to turn off loop protection.

Snippet:

Try deleting the noprotect in this:

// noprotect
let blur
function setup() {
  createCanvas(400, 400, WEBGL)
  blur = buildFilterShader(doBlur)
}

function doBlur() {
  filterColor.begin()
  let total = [0, 0, 0, 0]
  for (let i = 0; i < 20; i++) {
    total += getTexture(
      filterColor.canvasContent,
      filterColor.texCoord + 15 * [
        cos(i/20 * TWO_PI),
        sin(i/20 * TWO_PI)
      ] / filterColor.canvasSize
    )
  }
  let avg = total / 20
  filterColor.set(avg)
  filterColor.end()
}

function draw() {
  background(220)
  noStroke()
  circle(0, 0, 100)
  filter(blur)
}

Live: https://editor.p5js.org/davepagurek/sketches/ByAq44OVU

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions