Skip to content

Commit 778516c

Browse files
committed
Fix initiliaze and postInitialize not being called when script instances where enabled or when a script component was enabled, Fix script attributes not being initialized for disabled entities or script components, Do not call postInitialize if script was disabled in initialize but call it when the script becomes enabled later, Added unit tests for script component
1 parent 2483358 commit 778516c

File tree

14 files changed

+1901
-39
lines changed

14 files changed

+1901
-39
lines changed

src/framework/application.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,10 @@ pc.extend(pc, function () {
667667

668668
// called after scripts are preloaded
669669
var _loaded = function () {
670+
671+
self.systems.script.preloading = true;
670672
var entity = handler.open(url, data);
673+
self.systems.script.preloading = false;
671674

672675
// clear from cache because this data is modified by entity operations (e.g. destroy)
673676
self.loader.clearCache(url, "hierarchy");
@@ -738,7 +741,9 @@ pc.extend(pc, function () {
738741
if (!err) {
739742
var _loaded = function () {
740743
// parse and create scene
744+
self.systems.script.preloading = true;
741745
var scene = handler.open(url, data);
746+
self.systems.script.preloading = false;
742747

743748
// clear scene from cache because we'll destroy it when we load another one
744749
// so data will be invalid

src/framework/components/script/component.js

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pc.extend(pc, function () {
1515
this._scriptsIndex = { };
1616
this._scriptsData = null;
1717
this._oldState = true;
18+
this._beingEnabled = false;
1819
this.on('set_enabled', this._onSetEnabled, this);
1920
};
2021
ScriptComponent = pc.inherits(ScriptComponent, pc.Component);
@@ -160,7 +161,14 @@ pc.extend(pc, function () {
160161
pc.extend(ScriptComponent.prototype, {
161162
onEnable: function () {
162163
ScriptComponent._super.onEnable.call(this);
164+
this._beingEnabled = true;
163165
this._checkState();
166+
167+
if (! this.entity._beingEnabled) {
168+
this.onPostStateChange();
169+
}
170+
171+
this._beingEnabled = false;
164172
},
165173

166174
onDisable: function () {
@@ -170,10 +178,10 @@ pc.extend(pc, function () {
170178

171179
onPostStateChange: function() {
172180
var script;
173-
for (var i = 0; i < this.scripts.length; i++) {
181+
for (var i = 0, len = this.scripts.length; i < len; i++) {
174182
script = this.scripts[i];
175183

176-
if (script._initialized && ! script._postInitialized) {
184+
if (script._initialized && ! script._postInitialized && script.enabled) {
177185
script._postInitialized = true;
178186

179187
if (script.postInitialize)
@@ -182,8 +190,13 @@ pc.extend(pc, function () {
182190
}
183191
},
184192

193+
// We also need this handler because it is fired
194+
// when value === old instead of onEnable and onDisable
195+
// which are only fired when value !== old
185196
_onSetEnabled: function(prop, old, value) {
197+
this._beingEnabled = true;
186198
this._checkState();
199+
this._beingEnabled = false;
187200
},
188201

189202
_checkState: function() {
@@ -193,22 +206,13 @@ pc.extend(pc, function () {
193206

194207
this._oldState = state;
195208

196-
this.fire(this.enabled ? 'enable' : 'disable');
197-
this.fire('state', this.enabled);
209+
this.fire(state ? 'enable' : 'disable');
210+
this.fire('state', state);
198211

199212
var script;
200213
for (var i = 0, len = this.scripts.length; i < len; i++) {
201214
script = this.scripts[i];
202215
script.enabled = script._enabled;
203-
204-
if (! script._initialized && script.enabled) {
205-
script._initialized = true;
206-
207-
script.__initializeAttributes(true);
208-
209-
if (script.initialize)
210-
this._scriptMethod(script, ScriptComponent.scriptMethods.initialize);
211-
}
212216
}
213217
},
214218

@@ -257,16 +261,7 @@ pc.extend(pc, function () {
257261
},
258262

259263
_onPostInitialize: function() {
260-
var script, scripts = this._scripts;
261-
262-
for (var i = 0, len = scripts.length; i < len; i++) {
263-
script = scripts[i];
264-
if (! script._postInitialized && script.enabled) {
265-
script._postInitialized = true;
266-
if (script.postInitialize)
267-
this._scriptMethod(script, ScriptComponent.scriptMethods.postInitialize);
268-
}
269-
}
264+
this.onPostStateChange();
270265
},
271266

272267
_onUpdate: function(dt) {
@@ -379,17 +374,23 @@ pc.extend(pc, function () {
379374

380375
this.system.app.scripts.on('swap:' + scriptType.__name, this._scriptsIndex[scriptType.__name].onSwap);
381376

382-
if (! args.preloading && this.enabled && scriptInstance.enabled && ! scriptInstance._initialized) {
383-
scriptInstance._initialized = true;
384-
scriptInstance._postInitialized = true;
377+
if (! args.preloading) {
378+
379+
if (scriptInstance.enabled && ! scriptInstance._initialized) {
380+
scriptInstance._initialized = true;
385381

386-
if (scriptInstance.initialize)
387-
this._scriptMethod(scriptInstance, ScriptComponent.scriptMethods.initialize);
382+
if (scriptInstance.initialize)
383+
this._scriptMethod(scriptInstance, ScriptComponent.scriptMethods.initialize);
384+
}
388385

389-
if (scriptInstance.postInitialize)
390-
this._scriptMethod(scriptInstance, ScriptComponent.scriptMethods.postInitialize);
386+
if (scriptInstance.enabled && ! scriptInstance._postInitialized) {
387+
scriptInstance._postInitialized = true;
388+
if (scriptInstance.postInitialize)
389+
this._scriptMethod(scriptInstance, ScriptComponent.scriptMethods.postInitialize);
390+
}
391391
}
392392

393+
393394
return scriptInstance;
394395
} else {
395396
console.warn('script \'' + scriptName + '\' is already added to entity \'' + this.entity.name + '\'');

src/framework/components/script/system.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ pc.extend(pc, function () {
2222
// list of all entities script components
2323
this._components = [ ];
2424

25+
this.preloading = true;
26+
2527
this.on('beforeremove', this._onBeforeRemove, this);
2628
pc.ComponentSystem.on('initialize', this._onInitialize, this);
2729
pc.ComponentSystem.on('postInitialize', this._onPostInitialize, this);
@@ -45,7 +47,7 @@ pc.extend(pc, function () {
4547
component.create(data.order[i], {
4648
enabled: data.scripts[data.order[i]].enabled,
4749
attributes: data.scripts[data.order[i]].attributes,
48-
preloading: true
50+
preloading: this.preloading
4951
});
5052
}
5153
}
@@ -95,6 +97,8 @@ pc.extend(pc, function () {
9597
},
9698

9799
_onInitialize: function() {
100+
this.preloading = false;
101+
98102
// initialize attributes
99103
for (var i = 0; i < this._components.length; i++)
100104
this._components[i]._onInitializeAttributes();

src/framework/entity.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ pc.extend(pc, function () {
160160
if (node === this && this._app._enableList.length === 0)
161161
enableFirst = true;
162162

163+
node._beingEnabled = true;
164+
163165
node._onHierarchyStateChanged(enabled);
164166

165167
if (node._onHierarchyStatePostChanged)
@@ -172,6 +174,8 @@ pc.extend(pc, function () {
172174
this._notifyHierarchyStateChanged(c[i], enabled);
173175
}
174176

177+
node._beingEnabled = false;
178+
175179
if (enableFirst) {
176180
for (i = 0, len = this._app._enableList.length; i < len; i++)
177181
this._app._enableList[i]._onHierarchyStatePostChanged();

src/script/script.js

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -529,14 +529,34 @@ pc.extend(pc, function () {
529529
return this._enabled && this.entity.script.enabled && this.entity.enabled;
530530
},
531531
set: function(value) {
532-
value = !!value;
533-
if (this._enabled !== value)
534-
this._enabled = value;
535-
536-
if (this.enabled !== this._enabledOld) {
537-
this._enabledOld = this.enabled;
538-
this.fire(this.enabled ? 'enable' : 'disable');
539-
this.fire('state', this.enabled);
532+
this._enabled = !!value;
533+
534+
if (this.enabled === this._enabledOld) return;
535+
536+
this._enabledOld = this.enabled;
537+
this.fire(this.enabled ? 'enable' : 'disable');
538+
this.fire('state', this.enabled);
539+
540+
// initialize script if not initialized yet and script is enabled
541+
if (! this._initialized && this.enabled) {
542+
this._initialized = true;
543+
544+
this.__initializeAttributes(true);
545+
546+
if (this.initialize)
547+
this.entity.script._scriptMethod(this, pc.ScriptComponent.scriptMethods.initialize);
548+
}
549+
550+
// post initialize script if not post initialized yet and still enabled
551+
// (initilize might have disabled the script so check this.enabled again)
552+
// Warning: Do not do this if the script component is currently being enabled
553+
// because in this case post initialize must be called after all the scripts
554+
// in the script component have been initialized first
555+
if (this._initialized && ! this._postInitialized && this.enabled && !this.entity.script._beingEnabled) {
556+
this._postInitialized = true;
557+
558+
if (this.postInitialize)
559+
this.entity.script._scriptMethod(this, pc.ScriptComponent.scriptMethods.postInitialize);
540560
}
541561
}
542562
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
var Cloner = pc.createScript('cloner');
2+
3+
Cloner.attributes.add('entityToClone', {type: 'entity'});
4+
5+
Cloner.prototype.initialize = function() {
6+
window.initializeCalls.push(this.entity.getGuid() + ' initialize cloner');
7+
var clone = this.entityToClone.clone();
8+
clone.name += ' - clone';
9+
this.app.root.addChild(clone);
10+
};
11+
12+
Cloner.prototype.postInitialize = function () {
13+
window.initializeCalls.push(this.entity.getGuid() + ' postInitialize cloner');
14+
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
var Disabler = pc.createScript('disabler');
2+
3+
Disabler.attributes.add('disableEntity', {type: 'boolean'});
4+
Disabler.attributes.add('disableScriptComponent', {type: 'boolean'});
5+
Disabler.attributes.add('disableScriptInstance', {type: 'boolean'});
6+
7+
Disabler.prototype.initialize = function() {
8+
window.initializeCalls.push(this.entity.getGuid() + ' initialize disabler');
9+
10+
if (this.disableEntity) {
11+
this.entity.enabled = false;
12+
}
13+
14+
if (this.disableScriptComponent) {
15+
this.entity.script.enabled = false;
16+
}
17+
18+
if (this.disableScriptInstance) {
19+
if (this.entity.script.scriptA) {
20+
this.entity.script.scriptA.enabled = false;
21+
}
22+
23+
if (this.entity.script.scriptB) {
24+
this.entity.script.scriptB.enabled = false;
25+
}
26+
}
27+
};
28+
29+
Disabler.prototype.postInitialize = function () {
30+
window.initializeCalls.push(this.entity.getGuid() + ' postInitialize disabler');
31+
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
var Enabler = pc.createScript('enabler');
2+
3+
Enabler.attributes.add('entityToEnable', {type: 'entity'});
4+
5+
Enabler.prototype.initialize = function() {
6+
window.initializeCalls.push(this.entity.getGuid() + ' initialize enabler');
7+
this.entityToEnable.enabled = true;
8+
this.entityToEnable.script.enabled = true;
9+
if (this.entityToEnable.script.scriptA) {
10+
this.entityToEnable.script.scriptA.enabled = true;
11+
}
12+
if (this.entityToEnable.script.scriptB) {
13+
this.entityToEnable.script.scriptB.enabled = true;
14+
}
15+
16+
};
17+
18+
Enabler.prototype.postInitialize = function () {
19+
window.initializeCalls.push(this.entity.getGuid() + ' postInitialize enabler');
20+
};

0 commit comments

Comments
 (0)