1 decade ago by vincentpiel
Rq 1) There's a much 'cleaner' way of implementing staticInstantiate than the
one given in the documentation :
http://impactjs.com/documentation/class-reference/class#staticinstantiate-function
In the code i suggest below :
- no code needed after the class extension to initialize the _staticInstance member.
( MySingleton.instance = null;)
- the _staticInstance member is not enumerable, so it does not 'pollute' the object.
(by default, Object.defineProperty set the property as non enumerable).
- But most important : the init() is not affected by the class being static or not.
Rq 1.1 : this code requires Object.defineProperty to work, but any browser
implementing Canvas does also implement defineProperty.
Rq 1.2 : for those who don't care about 'hiding' the property, you can use
this simpler code :
Rq 2) This staticInstantiate function is now be the same for all classes, so it
should stand inside ig.Class, and we'd better use another convention for static
classes. The clearest convention i can think of is : static object should
make use of a staticInit() that replaces the init().
So 1) the coder/code reader does not get fooled by an init() function that will
in fact only get executed once,
and 2) the object is not 'polluted' with a property (staticInstantiate) that in fact is a meta-property.
This would give this code, for a static class :
...cannot be simpler...
and when a class has both init() and staticInit() set, ig.Class.extend should throw an exception.
Backward compatibility is easy to have. To write it short,
if (this.staticInstantiate) / consider that init is staticInit /
So it would break only the dirty tricks done in staticInstantiate, like the
one done in ig.Game :
Notice that it always return null !!! and that creating a game changes
sorting options (?), and sets a global variable... nothing anyone could claim as
a good design that should be kept as is. (with all due respect to Impact) )
one given in the documentation :
http://impactjs.com/documentation/class-reference/class#staticinstantiate-function
In the code i suggest below :
- no code needed after the class extension to initialize the _staticInstance member.
( MySingleton.instance = null;)
- the _staticInstance member is not enumerable, so it does not 'pollute' the object.
(by default, Object.defineProperty set the property as non enumerable).
- But most important : the init() is not affected by the class being static or not.
var MySingleton= ig.Class.extend({ someProperty: 'someValue', staticInstantiate: function () { if (MySingleton._staticInstance) return MySingleton._staticInstance; this.init.apply(this,arguments); Object.defineProperty(MySingleton,'_staticInstance', { value : this}); return this; }, init: function( newValue ) { this.someProperty = newValue; // standard init code } });
Rq 1.1 : this code requires Object.defineProperty to work, but any browser
implementing Canvas does also implement defineProperty.
Rq 1.2 : for those who don't care about 'hiding' the property, you can use
this simpler code :
staticInstantiate: function () { if (MySingleton._staticInstance) return MySingleton._staticInstance; this.init.apply(this,arguments); return (MySingleton._staticInstance = this); },
Rq 2) This staticInstantiate function is now be the same for all classes, so it
should stand inside ig.Class, and we'd better use another convention for static
classes. The clearest convention i can think of is : static object should
make use of a staticInit() that replaces the init().
So 1) the coder/code reader does not get fooled by an init() function that will
in fact only get executed once,
and 2) the object is not 'polluted' with a property (staticInstantiate) that in fact is a meta-property.
This would give this code, for a static class :
var staticClass = ig.Class.extend ({ prop1 : 0, staticInit (value1) { this.prop1 = value1; } })
...cannot be simpler...
and when a class has both init() and staticInit() set, ig.Class.extend should throw an exception.
Backward compatibility is easy to have. To write it short,
if (this.staticInstantiate) / consider that init is staticInit /
So it would break only the dirty tricks done in staticInstantiate, like the
one done in ig.Game :
staticInstantiate: function() { this.sortBy = this.sortBy || ig.Game.SORT.Z_INDEX; ig.game = this; return null; },
Notice that it always return null !!! and that creating a game changes
sorting options (?), and sets a global variable... nothing anyone could claim as
a good design that should be kept as is. (with all due respect to Impact) )