Skip to content

Commit b14fa16

Browse files
ngokevindmarcos
authored andcommitted
have mixinUpdate wait for entity to load first (#3859)
1 parent 4103950 commit b14fa16

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

‎src/core/a-entity.js‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ var warn = utils.debug('core:a-entity:warn');
1010

1111
var MULTIPLE_COMPONENT_DELIMITER = '__';
1212
var OBJECT3D_COMPONENTS = ['position', 'rotation', 'scale', 'visible'];
13+
var ONCE = {once: true};
1314

1415
/**
1516
* Entity is a container object that components are plugged into to comprise everything in
@@ -599,6 +600,14 @@ var proto = Object.create(ANode.prototype, {
599600
var mixinEl;
600601
var mixinIds;
601602
var i;
603+
var self = this;
604+
605+
if (!this.hasLoaded) {
606+
this.addEventListener('loaded', function () {
607+
self.mixinUpdate(newMixins, oldMixins);
608+
}, ONCE);
609+
return;
610+
}
602611

603612
oldMixins = oldMixins || this.getAttribute('mixin');
604613
mixinIds = this.updateMixins(newMixins, oldMixins);
@@ -627,7 +636,7 @@ var proto = Object.create(ANode.prototype, {
627636
for (component in mixinEl.componentCache) {
628637
if (componentsUpdated.indexOf(component) === -1) {
629638
if (this.components[component]) {
630-
// Compoennt removed. Rebuild data if not yet rebuilt.
639+
// Component removed. Rebuild data if not yet rebuilt.
631640
this.components[component].handleMixinUpdate();
632641
}
633642
}

‎tests/components/scene/pool.test.js‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@ suite('pool', function () {
1111
sceneEl.addEventListener('loaded', function () { done(); });
1212
});
1313

14-
test('pool is initialized', function () {
14+
test('pool is initialized', function (done) {
1515
var sceneEl = this.sceneEl;
1616
var poolComponent = sceneEl.components.pool;
1717
assert.equal(poolComponent.availableEls.length, 1);
1818
assert.equal(poolComponent.usedEls.length, 0);
19-
assert.equal(sceneEl.querySelectorAll('a-entity[material]').length, 1);
19+
setTimeout(() => {
20+
assert.equal(sceneEl.querySelectorAll('a-entity[material]').length, 1);
21+
done();
22+
});
2023
});
2124

2225
test('can specify container', function (done) {

‎tests/core/a-entity.test.js‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,40 @@ suite('a-entity', function () {
13111311
assert.shallowDeepEqual(el.getAttribute('position'), {x: 0, y: 0, z: 0});
13121312
assert.equal(el.mixinEls.length, 0);
13131313
});
1314+
1315+
/**
1316+
* Fixed a weird case where attributeChangedCallback on mixin was fired during scene init.
1317+
* That fired mixinUpdate before the entity was loaded (and el.sceneEl was undefined).
1318+
* And tried to update components before the entity was ready.
1319+
* This test mimics that state where mixinUpdate called when entity not fully loaded but
1320+
* component is still initializing.
1321+
*/
1322+
test('wait for entity to load on mixin update', function (done) {
1323+
const TestComponent = AFRAME.registerComponent('test', {
1324+
update: function () {
1325+
assert.ok(this.el.sceneEl);
1326+
done();
1327+
}
1328+
});
1329+
1330+
elFactory().then(someEl => {
1331+
const sceneEl = someEl.sceneEl;
1332+
1333+
const mixin = document.createElement('a-mixin');
1334+
mixin.setAttribute('id', 'foo');
1335+
mixin.setAttribute('test', '');
1336+
sceneEl.appendChild(mixin);
1337+
1338+
setTimeout(() => {
1339+
const el = document.createElement('a-entity');
1340+
el.setAttribute('mixin', 'foo');
1341+
el.components.test = new TestComponent(el, {}, '');
1342+
el.components.test.oldData = 'foo';
1343+
el.mixinUpdate('foo');
1344+
sceneEl.appendChild(el);
1345+
});
1346+
});
1347+
});
13141348
});
13151349
});
13161350

0 commit comments

Comments
 (0)