Skip to content
27 changes: 24 additions & 3 deletions src/core/friendly_errors/param_validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -573,17 +573,38 @@ function validateParams(p5, fn, lifecycles) {

fn._validate = validate; // TEMP: For unit tests

// Suppress FES param checking for the duration of a callback.
// Use this to wrap internal p5 calls that happen after an await.
// NOTE: shares the same _isUserCall flag logic as the decorator below.
fn._internal = function(callback) {
const wasInternalCall = this._isUserCall;
this._isUserCall = true;
try {
return callback();
} finally {
this._isUserCall = wasInternalCall;
}
};

// Skip FES validation for nested (internal) calls.
// NOTE: shares the same _isUserCall flag logic as _internal() above.
p5.registerDecorator(
({ path }) => {
return path.startsWith('p5.prototype');
},
function(target, { kind, name }){
if(kind === 'method'){
return function(...args){
if (!p5.disableFriendlyErrors && !p5.disableParameterValidator) {
validate(name, args);
const wasInternalCall = this._isUserCall;
this._isUserCall = true;
try {
if (!wasInternalCall && !p5.disableFriendlyErrors && !p5.disableParameterValidator) {
validate(name, args);
}
return target.apply(this, args);
} finally {
this._isUserCall = wasInternalCall;
}
return target.apply(this, args);
};
}
}
Expand Down
16 changes: 9 additions & 7 deletions src/image/loading_displaying.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,15 @@ function loadingDisplaying(p5, fn){
pImg.drawingContext.drawImage(img, 0, 0);
}

pImg.modified = true;

if(successCallback){
return successCallback(pImg);
}else{
return pImg;
}
const cb = () => {
pImg.modified = true;
if(successCallback){
return successCallback(pImg);
}else{
return pImg;
}
};
return this._internal ? this._internal(cb) : cb();

} catch(err) {
p5._friendlyFileLoadError(0, path);
Expand Down
87 changes: 51 additions & 36 deletions src/io/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,11 @@ function files(p5, fn){

try{
const { data } = await request(path, 'json');
if (successCallback) return successCallback(data);
return data;
const cb = () => {
if (successCallback) return successCallback(data);
return data;
};
return this._internal ? this._internal(cb) : cb();
} catch(err) {
p5._friendlyFileLoadError(5, path);
if(errorCallback) {
Expand Down Expand Up @@ -414,10 +417,12 @@ function files(p5, fn){

try{
let { data } = await request(path, 'text');
data = data.split(/\r?\n/);

if (successCallback) return successCallback(data);
return data;
const cb = () => {
data = data.split(/\r?\n/);
if (successCallback) return successCallback(data);
return data;
};
return this._internal ? this._internal(cb) : cb();
} catch(err) {
p5._friendlyFileLoadError(3, path);
if(errorCallback) {
Expand Down Expand Up @@ -501,28 +506,30 @@ function files(p5, fn){

try{
let { data } = await request(path, 'text');
const cb = () => {
let ret = new p5.Table();
data = parse(data, {
separator
});

if(header){
ret.columns = data.shift();
}else{
ret.columns = Array(data[0].length).fill(null);
}

let ret = new p5.Table();
data = parse(data, {
separator
});

if(header){
ret.columns = data.shift();
}else{
ret.columns = Array(data[0].length).fill(null);
}

data.forEach(line => {
const row = new p5.TableRow(line);
ret.addRow(row);
});
data.forEach(line => {
const row = new p5.TableRow(line);
ret.addRow(row);
});

if (successCallback) {
return successCallback(ret);
} else {
return ret;
}
if (successCallback) {
return successCallback(ret);
} else {
return ret;
}
};
return this._internal ? this._internal(cb) : cb();
} catch(err) {
p5._friendlyFileLoadError(2, path);
if(errorCallback) {
Expand Down Expand Up @@ -686,11 +693,13 @@ function files(p5, fn){
const parser = new DOMParser();

let { data } = await request(path, 'text');
const parsedDOM = parser.parseFromString(data, 'application/xml');
data = new p5.XML(parsedDOM);

if (successCallback) return successCallback(data);
return data;
const cb = () => {
const parsedDOM = parser.parseFromString(data, 'application/xml');
data = new p5.XML(parsedDOM);
if (successCallback) return successCallback(data);
return data;
};
return this._internal ? this._internal(cb) : cb();
} catch(err) {
p5._friendlyFileLoadError(1, path);
if(errorCallback) {
Expand Down Expand Up @@ -734,9 +743,12 @@ function files(p5, fn){
fn.loadBytes = async function (path, successCallback, errorCallback) {
try{
let { data } = await request(path, 'arrayBuffer');
data = new Uint8Array(data);
if (successCallback) return successCallback(data);
return data;
const cb = () => {
data = new Uint8Array(data);
if (successCallback) return successCallback(data);
return data;
};
return this._internal ? this._internal(cb) : cb();
} catch(err) {
p5._friendlyFileLoadError(6, path);
if(errorCallback) {
Expand Down Expand Up @@ -789,8 +801,11 @@ function files(p5, fn){
fn.loadBlob = async function(path, successCallback, errorCallback) {
try{
const { data } = await request(path, 'blob');
if (successCallback) return successCallback(data);
return data;
const cb = () => {
if (successCallback) return successCallback(data);
return data;
};
return this._internal ? this._internal(cb) : cb();
} catch(err) {
if(errorCallback) {
return errorCallback(err);
Expand Down
8 changes: 5 additions & 3 deletions src/type/p5.Font.js
Original file line number Diff line number Diff line change
Expand Up @@ -1578,9 +1578,11 @@ function font(p5, fn) {
throw err;
}
}
if (success) return success(pfont);

return pfont;
const cb = () => {
if (success) return success(pfont);
return pfont;
};
return this._internal ? this._internal(cb) : cb();
};
};

Expand Down
70 changes: 38 additions & 32 deletions src/webgl/loading.js
Original file line number Diff line number Diff line change
Expand Up @@ -419,50 +419,56 @@ function loading(p5, fn){
try{
if (fileType.match(/\.stl$/i)) {
const { data } = await request(path, 'arrayBuffer');
parseSTL(model, data);
const cb = () => {
parseSTL(model, data);

if (normalize) {
model.normalize();
}
if (normalize) {
model.normalize();
}

if (flipU) {
model.flipU();
}
if (flipU) {
model.flipU();
}

if (flipV) {
model.flipV();
}
model._makeTriangleEdges();
if (flipV) {
model.flipV();
}
model._makeTriangleEdges();

if (successCallback) {
return successCallback(model);
} else {
return model;
}
if (successCallback) {
return successCallback(model);
} else {
return model;
}
};
return this._internal ? this._internal(cb) : cb();

} else if (fileType.match(/\.obj$/i)) {
const { data } = await request(path, 'text');
const lines = data.split('\n');

const parsedMaterials = await getMaterials(lines);
parseObj(model, lines, parsedMaterials);
const cb = () => {
parseObj(model, lines, parsedMaterials);

if (normalize) {
model.normalize();
}
if (flipU) {
model.flipU();
}
if (flipV) {
model.flipV();
}
model._makeTriangleEdges();
if (normalize) {
model.normalize();
}
if (flipU) {
model.flipU();
}
if (flipV) {
model.flipV();
}
model._makeTriangleEdges();

if (successCallback) {
return successCallback(model);
} else {
return model;
}
if (successCallback) {
return successCallback(model);
} else {
return model;
}
};
return this._internal ? this._internal(cb) : cb();
}
} catch(err) {
p5._friendlyFileLoadError(3, path);
Expand Down
16 changes: 8 additions & 8 deletions src/webgl/material.js
Original file line number Diff line number Diff line change
Expand Up @@ -524,11 +524,11 @@ function material(p5, fn) {
// Test if we've loaded GLSL or not by checking for the existence of `void main`
let loadedShader;
if (/void\s+main/.exec(fragString)) {
loadedShader = this.createFilterShader(fragString, true);
loadedShader = this._internal(() => this.createFilterShader(fragString, true));
} else {
loadedShader = withGlobalStrands(this, () =>
loadedShader = this._internal(() => withGlobalStrands(this, () =>
this.baseFilterShader().modify(new Function(fragString)),
);
));
}

if (successCallback) {
Expand Down Expand Up @@ -1635,7 +1635,7 @@ function material(p5, fn) {
fn.loadMaterialShader = async function (url, onSuccess, onFail) {
try {
const cb = await urlToStrandsCallback(url);
let shader = withGlobalStrands(this, () => this.buildMaterialShader(cb));
let shader = this._internal(() => withGlobalStrands(this, () => this.buildMaterialShader(cb)));
if (onSuccess) {
shader = onSuccess(shader) || shader;
}
Expand Down Expand Up @@ -1854,9 +1854,9 @@ function material(p5, fn) {
fn.loadNormalShader = async function (url, onSuccess, onFail) {
try {
const cb = await urlToStrandsCallback(url);
let shader = this.withGlobalStrands(this, () =>
let shader = this._internal(() => this.withGlobalStrands(this, () =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! While we're at it, can we do the other known methods? In the reference it looks like that means loadModel, loadFont, loadImage, loadBlob, loadBytes, loadJSON, loadStrings, loadTable, and loadXML

this.buildNormalShader(cb),
);
));
if (onSuccess) {
shader = onSuccess(shader) || shader;
}
Expand Down Expand Up @@ -2020,7 +2020,7 @@ function material(p5, fn) {
fn.loadColorShader = async function (url, onSuccess, onFail) {
try {
const cb = await urlToStrandsCallback(url);
let shader = withGlobalStrands(this, () => this.buildColorShader(cb));
let shader = this._internal(() => withGlobalStrands(this, () => this.buildColorShader(cb)));
if (onSuccess) {
shader = onSuccess(shader) || shader;
}
Expand Down Expand Up @@ -2281,7 +2281,7 @@ function material(p5, fn) {
fn.loadStrokeShader = async function (url, onSuccess, onFail) {
try {
const cb = await urlToStrandsCallback(url);
let shader = withGlobalStrands(this, () => this.buildStrokeShader(cb));
let shader = this._internal(() => withGlobalStrands(this, () => this.buildStrokeShader(cb)));
if (onSuccess) {
shader = onSuccess(shader) || shader;
}
Expand Down
Loading