Skip to content

Commit d0071ac

Browse files
authored
Merge pull request #3162 from Zalastax/instance-mode-calls-global
Instance mode calls global
2 parents 347fe7f + 4abb613 commit d0071ac

File tree

7 files changed

+144
-51
lines changed

7 files changed

+144
-51
lines changed

.eslintrc

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,13 @@
22
"env": {
33
"node": true,
44
"browser": true,
5-
"mocha": true,
65
"amd": true,
76
"es6": true
87
},
98
"globals": {
10-
"p5": true,
11-
"assert": true,
12-
"expect": true,
13-
"sinon": true
9+
"p5": true
1410
},
11+
"root": true,
1512
"extends": ["eslint:recommended", "prettier"],
1613
"plugins": ["prettier"],
1714
"parserOptions": {

src/core/main.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ var p5 = function(sketch, node, sync) {
4848

4949
/**
5050
* Called directly before <a href="#/p5/setup">setup()</a>, the <a href="#/p5/preload">preload()</a> function is used to handle
51-
* asynchronous loading of external files in a blocking way. If a preload
51+
* asynchronous loading of external files in a blocking way. If a preload
5252
* function is defined, <a href="#/p5/setup">setup()</a> will wait until any load calls within have
5353
* finished. Nothing besides load calls (<a href="#/p5/loadImage">loadImage</a>, <a href="#/p5/loadJSON">loadJSON</a>, <a href="#/p5/loadFont">loadFont</a>,
5454
* <a href="#/p5/loadStrings">loadStrings</a>, etc.) should be inside the preload function. If asynchronous
@@ -238,7 +238,8 @@ var p5 = function(sketch, node, sync) {
238238
}
239239
}
240240

241-
var userPreload = this.preload || window.preload; // look for "preload"
241+
var context = this._isGlobal ? window : this;
242+
var userPreload = context.preload;
242243
if (userPreload) {
243244
// Setup loading screen
244245
// Set loading screen into dom if not present
@@ -252,11 +253,11 @@ var p5 = function(sketch, node, sync) {
252253
var node = this._userNode || document.body;
253254
node.appendChild(loadingScreen);
254255
}
255-
// var methods = this._preloadMethods;
256-
for (var method in this._preloadMethods) {
256+
var methods = this._preloadMethods;
257+
for (var method in methods) {
257258
// default to p5 if no object defined
258-
this._preloadMethods[method] = this._preloadMethods[method] || p5;
259-
var obj = this._preloadMethods[method];
259+
methods[method] = methods[method] || p5;
260+
var obj = methods[method];
260261
//it's p5, check if it's global or instance
261262
if (obj === p5.prototype || obj === p5) {
262263
if (this._isGlobal) {

src/core/structure.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -313,25 +313,25 @@ p5.prototype.redraw = function(n) {
313313
numberOfRedraws = 1;
314314
}
315315

316-
var userSetup = this.setup || window.setup;
317-
var userDraw = this.draw || window.draw;
316+
var context = this._isGlobal ? window : this;
317+
var userSetup = context.setup;
318+
var userDraw = context.draw;
318319
if (typeof userDraw === 'function') {
319320
if (typeof userSetup === 'undefined') {
320-
this.scale(this._pixelDensity, this._pixelDensity);
321+
context.scale(context._pixelDensity, context._pixelDensity);
321322
}
322-
var self = this;
323323
var callMethod = function(f) {
324-
f.call(self);
324+
f.call(context);
325325
};
326326
for (var idxRedraw = 0; idxRedraw < numberOfRedraws; idxRedraw++) {
327-
this.resetMatrix();
328-
if (this._renderer.isP3D) {
329-
this._renderer._update();
327+
context.resetMatrix();
328+
if (context._renderer.isP3D) {
329+
context._renderer._update();
330330
}
331-
this._setProperty('frameCount', this.frameCount + 1);
332-
this._registeredMethods.pre.forEach(callMethod);
331+
context._setProperty('frameCount', context.frameCount + 1);
332+
context._registeredMethods.pre.forEach(callMethod);
333333
userDraw();
334-
this._registeredMethods.post.forEach(callMethod);
334+
context._registeredMethods.post.forEach(callMethod);
335335
}
336336
}
337337
};

test/.eslintrc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"env": {
3+
"mocha": true
4+
},
5+
"globals": {
6+
"assert": false,
7+
"sinon": false,
8+
"expect": false,
9+
"promisedSketch": true,
10+
"testSketchWithPromise": true,
11+
"createP5Iframe": true,
12+
"P5_SCRIPT_URL": true,
13+
"P5_SCRIPT_TAG": true
14+
}
15+
}

test/js/p5_helpers.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function promisedSketch(sketch_fn) {
1010
myInstance.remove();
1111
});
1212
return promise;
13-
};
13+
}
1414

1515
function testSketchWithPromise(name, sketch_fn) {
1616
var test_fn = function() {
@@ -20,4 +20,27 @@ function testSketchWithPromise(name, sketch_fn) {
2020
return sketch_fn.toString();
2121
};
2222
return test(name, test_fn);
23-
};
23+
}
24+
25+
var P5_SCRIPT_URL = '../../lib/p5.js';
26+
var P5_SCRIPT_TAG = '<script src="' + P5_SCRIPT_URL + '"></script>';
27+
28+
function createP5Iframe(html) {
29+
html = html || P5_SCRIPT_TAG;
30+
31+
var elt = document.createElement('iframe');
32+
33+
document.body.appendChild(elt);
34+
elt.setAttribute('style', 'visibility: hidden');
35+
36+
elt.contentDocument.open();
37+
elt.contentDocument.write(html);
38+
elt.contentDocument.close();
39+
40+
return {
41+
elt: elt,
42+
teardown: function() {
43+
elt.parentNode.removeChild(elt);
44+
}
45+
};
46+
}

test/unit/core/core.js

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -127,51 +127,36 @@ suite('Core', function() {
127127
});
128128

129129
suite('new p5() / global mode', function() {
130-
var P5_SCRIPT_URL = '../../lib/p5.js';
131-
var P5_SCRIPT_TAG = '<script src="' + P5_SCRIPT_URL + '"></script>';
132130
var iframe;
133131

134-
function createP5Iframe(html) {
135-
html = html || P5_SCRIPT_TAG;
136-
137-
iframe = document.createElement('iframe');
138-
139-
document.body.appendChild(iframe);
140-
iframe.setAttribute('style', 'visibility: hidden');
141-
142-
iframe.contentDocument.open();
143-
iframe.contentDocument.write(html);
144-
iframe.contentDocument.close();
145-
}
146-
147132
teardown(function() {
148133
if (iframe) {
149-
iframe.parentNode.removeChild(iframe);
134+
iframe.teardown();
150135
iframe = null;
151136
}
152137
});
153138

154139
test('is triggered when "setup" is in window', function() {
155140
return new Promise(function(resolve, reject) {
156-
createP5Iframe();
157-
iframe.contentWindow.setup = function() {
141+
iframe = createP5Iframe();
142+
iframe.elt.contentWindow.setup = function() {
158143
resolve();
159144
};
160145
});
161146
});
162147

163148
test('is triggered when "draw" is in window', function() {
164149
return new Promise(function(resolve, reject) {
165-
createP5Iframe();
166-
iframe.contentWindow.draw = function() {
150+
iframe = createP5Iframe();
151+
iframe.elt.contentWindow.draw = function() {
167152
resolve();
168153
};
169154
});
170155
});
171156

172157
test('works when p5.js is loaded asynchronously', function() {
173158
return new Promise(function(resolve, reject) {
174-
createP5Iframe(`
159+
iframe = createP5Iframe(`
175160
<script>
176161
window.onload = function() {
177162
var script = document.createElement('script');
@@ -181,13 +166,13 @@ suite('Core', function() {
181166
}
182167
</script>`);
183168

184-
iframe.contentWindow.setup = resolve;
169+
iframe.elt.contentWindow.setup = resolve;
185170
});
186171
});
187172

188173
test('works on-demand', function() {
189174
return new Promise(function(resolve, reject) {
190-
createP5Iframe(
175+
iframe = createP5Iframe(
191176
[
192177
P5_SCRIPT_TAG,
193178
'<script>',
@@ -199,9 +184,9 @@ suite('Core', function() {
199184
'</script>'
200185
].join('\n')
201186
);
202-
iframe.contentWindow.onDoneLoading = resolve;
187+
iframe.elt.contentWindow.onDoneLoading = resolve;
203188
}).then(function() {
204-
var win = iframe.contentWindow;
189+
var win = iframe.elt.contentWindow;
205190
assert.equal(typeof win.myURL, 'string');
206191
assert.strictEqual(win.setupCalled, true);
207192
assert.strictEqual(win.originalP5Instance, win.p5.instance);
@@ -212,7 +197,14 @@ suite('Core', function() {
212197
suite('p5.prototype._createFriendlyGlobalFunctionBinder', function() {
213198
var noop = function() {};
214199
var createBinder = p5.prototype._createFriendlyGlobalFunctionBinder;
215-
var logMsg, globalObject, bind;
200+
var logMsg, globalObject, bind, iframe;
201+
202+
teardown(function() {
203+
if (iframe) {
204+
iframe.teardown();
205+
iframe = null;
206+
}
207+
});
216208

217209
setup(function() {
218210
globalObject = {};
@@ -307,5 +299,33 @@ suite('Core', function() {
307299
assert.equal(globalObject.mouseX, 50);
308300
assert.isUndefined(logMsg);
309301
});
302+
303+
test('instance preload is independent of window', function() {
304+
// callback for p5 instance mode.
305+
// It does not define a preload.
306+
// This tests that we don't call the global preload accidentally.
307+
function cb(s) {
308+
s.setup = function() {
309+
window.afterSetup();
310+
};
311+
}
312+
return new Promise(function(resolve) {
313+
iframe = createP5Iframe(
314+
[
315+
P5_SCRIPT_TAG,
316+
'<script>',
317+
'globalPreloads = 0;',
318+
'function setup() { }',
319+
'function preload() { window.globalPreloads++; }',
320+
'new p5(' + cb.toString() + ');',
321+
'</script>'
322+
].join('\n')
323+
);
324+
iframe.elt.contentWindow.afterSetup = resolve;
325+
}).then(function() {
326+
var win = iframe.elt.contentWindow;
327+
assert.strictEqual(win.globalPreloads, 1);
328+
});
329+
});
310330
});
311331
});

test/unit/core/structure.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,16 @@ suite('Structure', function() {
258258
});
259259
});
260260

261-
suite('p5.prototype.redraw', function() {
261+
suite.only('p5.prototype.redraw', function() {
262+
var iframe;
263+
264+
teardown(function() {
265+
if (iframe) {
266+
iframe.teardown();
267+
iframe = null;
268+
}
269+
});
270+
262271
test('resets the rendering matrix between frames', function() {
263272
return new Promise(function(resolve, reject) {
264273
myp5.draw = function() {
@@ -274,5 +283,33 @@ suite('Structure', function() {
274283
resolve();
275284
});
276285
});
286+
287+
test('instance redraw is independent of window', function() {
288+
// callback for p5 instance mode.
289+
// It does not call noLoop so redraw will be called many times.
290+
// Redraw is not supposed to call window.draw even though no draw is defined in cb
291+
function cb(s) {
292+
s.setup = function() {
293+
setTimeout(window.afterSetup, 1000);
294+
};
295+
}
296+
return new Promise(function(resolve) {
297+
iframe = createP5Iframe(
298+
[
299+
P5_SCRIPT_TAG,
300+
'<script>',
301+
'globalDraws = 0;',
302+
'function setup() { noLoop(); }',
303+
'function draw() { window.globalDraws++; }',
304+
'new p5(' + cb.toString() + ');',
305+
'</script>'
306+
].join('\n')
307+
);
308+
iframe.elt.contentWindow.afterSetup = resolve;
309+
}).then(function() {
310+
var win = iframe.elt.contentWindow;
311+
assert.strictEqual(win.globalDraws, 1);
312+
});
313+
});
277314
});
278315
});

0 commit comments

Comments
 (0)