macromedia flash actionscript scripting, php, remoting, webservices, c#, javascript
After i have found the failure of our addClass-method,
i took a deep watch to the proto-chain, constructor,
__constructor__ things.
Well, in the first moment my picture was off a big
anaconda-snake which i had to wrestle to become
sir of the situation, but a few traces later i got back
the controll over the situation.
Hence, i have the method-complete. And i think it
realy cool tool for inheritance.
Till now i have found the following Advantages and
Disadvantages:
Disadvantages
if (Object.prototype.addClass != undefined) {
trace('ERROR: Method with the name Object.prototype.addClass is allready defined!');
}
Object.prototype.addClass = function (pConstructor) {
//
// Adds a class to an existing as-obj or mc-obj.
//
// The added class will be interjected to the
// beginning of the objects proto-chain.
// The super-operator works than in the new
// chain-order.
// The class to add can be specialized(inherited).
//
// Tests i have done:
// - Multiple inheterence
// - multiple call of addClass
// - using with mcs
// - using with mcs which was Object.registerClassed
// - Allways i taked a deep watch to the generated
// proto-chain and allways compared to the proto-chain
// that comes out by standard inheritance and i have
// found no difference. So polimorphy works still fine.
//
// Untested
// - it should also no problem to add an Class
// to a prototype.__proto__ for the multiple
// extending of a Class
//
var tmp = this.__proto__;
this.__proto__ = pConstructor.prototype;
var pp, p = this.__proto__;
while (pp = p.__proto__) {
if (pp == Object.prototype || pp == MovieClip.prototype) {
p.__proto__ = tmp;
p.constructor = this.constructor;
p.__constructor__ = (tmp == MovieClip.prototype) ? MovieClip : this.__constructor__;
this.constructor = pConstructor;
this.__constructor__ = pConstructor;
return true;
} else {
p = pp;
}
}
return false;
}
Posted by hOk at April 30, 2003 04:57 PM
I have just thought about possible side-effects
that can occur if we use an prototype-extension
with the same name twice. Uhh, that could be
horrible especially for teamwork, so that everyone
have to know exactly what extensions the other
did.
A really simple solution is to check wether that
extension exist before we define the extension, if so
we can throw an error otherwise our trace-window
stay nice and clean...;-)
if (Object.prototype.addClass != undefined) {
trace('ERROR: Object.prototype.addClass exist allready!');
}
Object.prototype.addClass = function (pConstructor) {
// Adds a class to an object, to the
// beginning of the proto-chain.
var tmp = this.__proto__;
this.__proto__ = pConstructor.prototype;
this.__proto__.__proto__ = tmp;
}
ASSetPropFlags(Object.prototype, null, 1, 0);
So we can stay concentrate on the real importent
things in our programms.
The little philosophy behind this test is the self-testing-code
philosophy. That means that we only get a message if an
error happens and we did not have to evaluate trace window
for inconsistencies by our self.
Posted by hOk at April 29, 2003 03:12 PM
Here is a way to use the constructor of an abstract-class
as factory:
Object.prototype.addClass = function (pConstructor) {
// Adds a class to an object, to the
// beginning of the proto-chain.
var tmp = this.__proto__;
this.__proto__ = pConstructor.prototype;
this.__proto__.__proto__ = tmp;
}
ASSetPropFlags(Object.prototype, null, 1, 0);
// Abstract-Factory-Constructor
AbstractCarClass = function (pConcreteClass) {
// default-properties
this.intMaxSpeed = 130;
this.intPrice = 15000;
//
this.addClass(pConcreteClass);
this.init();
}
AbstractCarClass.prototype.changeClass = function (pConcreteClass, pBlnInitialize) {
this.__proto__ = pConcreteClass.prototype;
if (pBlnInitialize) this.init();
}
AbstractCarClass.prototype.init = function () {
//
// Should be overwritten in concrete-class to
// initialize properties.
//
}
// concrete-class
PorscheClass = function () {}
PorscheClass.prototype.init = function () {
this.intMaxSpeed = 240;
this.intPrice = 70000;
}
PorscheClass.prototype.toString = function () {
return '[object PorscheClass]';
}
// concrete-class
LanciaClass = function () {}
PorscheClass.prototype.init = function () {
this.intMaxSpeed = 120;
this.intPrice = 10000;
}
LanciaClass.prototype.toString = function () {
return '[object LanciaClass]';
}
// test
objCar = new AbstractCarClass(PorscheClass);
trace(objCar); // [object PorscheClass]
//
objCar.changeClass(LanciaClass, true);
trace(objCar); // [object LanciaClass]
Posted by hOk at April 27, 2003 04:49 PM
I have written a little vbs, that extracts methods from
your as-files into a getMethodsResult.txt-file.
Each line in the result-file have the following format:
methodName(param1, param2[,...]) // className
If you put the result-text in the flash.api-file from
the Scite|Flash-Editor you get autocomplete and
hints for your methods.
You simply have to run the getMethods.vbs
in the directory where your as-files are.
Posted by hOk at April 26, 2003 11:50 AM
initMovieClipBroadcasters = function () { _level0.createEmptyMovieClip('mcEventSource', 1000000); var arrBroadcaster = ['EnterFrame','MouseMove','MouseUp','MouseDown']; for (var i = 0; i < arrBroadcaster.length; i++) { var strBcName = 'bc' + arrBroadcaster[i]; var strEventName = 'on' + arrBroadcaster[i]; var objBroadcaster = MovieClip[strBcName] = new Object(); ASBroadcaster.initialize(objBroadcaster); objBroadcaster.strEventName = strEventName; objBroadcaster.$oldAddListener = objBroadcaster.addListener; objBroadcaster.$oldRemoveListener = objBroadcaster.removeListener; objBroadcaster.addListener = function (pObjListener) { this.$oldAddListener(pObjListener); var objBroadcaster = this; var strEventName = this.strEventName; _level0.mcEventSource[strEventName] = function () { objBroadcaster.broadcastMessage(strEventName); } } objBroadcaster.removeListener = function (pObjListener) { this.$oldRemoveListener(pObjListener); if (this._listeners.length == 0) { _level0.mcEventSource[this.strEventName] = null; } } }}initMovieClipBroadcasters();delete initMovieClipBroadcasters;// Example:obj = new Object();MovieClip.bcEnterFrame.addListener(obj);MovieClip.bcMouseUp.addListener(obj);//MovieClip.bcEnterFrame.removeListener(obj);obj.onEnterFrame = function () { trace('onEnterFrame'); }obj.onMouseUp = function () { trace('onMouseUp'); }
Posted by hOk at April 18, 2003 01:49 PM
// Example 1(without toString)Car = function (pHexColor) { this.hexColor = pHexColor;}objAudi = new Car();trace(objAudi); // output: [object Object]// Example 2(with toString)Car = function (pHexColor) { this.hexColor = pHexColor;}Car.prototype.toString = function () { return '[object Car]';}objAudi = new Car();trace(objAudi); // output: [object Car]
So the difference is the Information we get// Example 3Car = function (pHexColor) { // unique-id this.intId = ++arguments.callee.intGeneratedObjects; this.hexColor = pHexColor;}// class-property or static-propertyCar.intGeneratedObjects = 0;Car.prototype.strClassName = 'Car';Car.prototype.toString = function () { return '[object '+this.strClassName+this.intId+']';}objAudi = new Car();trace(objAudi); // output: [object Car1]
Now lets see how easy it is to store our object in// create the listener-hashhashListeners = new Object();// store our object as listenerhashListeners[objAudi] = objAudi;// delete our object from the listener-hashdelete hashListeners[objAudi];
OK, that was not really a big deal, Posted by hOk at April 17, 2003 12:52 PM
Sometimes it is important to know what function exactly
calls a function or a method. Making use of the function
above you can simply determine the caller by tracing the
'arguments.caller.name' within a function.
setFunctionNames = function (pObjContainer) {
// Description:
// Sets the property "name" for every Function
// that was found in "pObjContainer"
// Arguments:
// pObjContainer -> Obj|Mc in which to rekusivly
// search for functions
pObjContainer = pObjContainer || _root;
for (var p in pObjContainer) {
if (typeof pObjContainer[p] == 'object') {
arguments.callee(pObjContainer[p]);
} else if (typeof pObjContainer[p] == 'function') {
pObjContainer[p].name = p; // <-- sets the name
arguments.callee(pObjContainer[p].prototype);
}
}
}
Posted by hOk at April 7, 2003 04:29 PM
c = 40000;t = getTimer();l = c;while (l--);trace(getTimer() - t);t = getTimer();l = c;while (--l+1);trace(getTimer() - t);t = getTimer();l = c;while (--l-(-1));trace(getTimer() - t);// output:// 744// 549// 545
Posted by hOk at April 5, 2003 05:11 PM
k = 3-kk = (k==1)?2:1;if(!(k--)) k=2;k = (k%=2)+1;k = k%2+1;k = !(k-1) + 1;k = 1 + sin(asin(k-1) + PI/2);k = pow(2,2-k);(k-1)? (k >>= 1) : (k <<= 1);k = (Math.log(k)) ? --k : ++k;k = (((k&1)<<2)|k)>>1;k = (Math.sqrt(--k)) + 2*(!k);k = 1-(k--*--k);k = 1+!(--k/k);k = !(++k%--k)+1;k = (k>>1|k<<1)&3;k = 2/k;k = Math.abs(k*3-5);k = Math.ceil(Math.cos(k))+1;k = Math.round(2.4-k/2);k = 2-Math.floor(Math.tan(--k));k = Math.abs((k^2)-1);
Posted by hOk at April 5, 2003 04:28 PM
Sometimes you need to know which methods of an
object called in which order, here is a function that
do this job.
traceMessages = function (pObj, pBlnLastMethodOnly) {
for (var p in pObj) {
if (typeof pObj[p] != 'function') continue;
var tmp = pObj[p];
pObj[p] = function() {
var t = getTimer() - arguments.callee.__traceMessages.intLastCallTime;
arguments.callee.__traceMessages.intLastCallTime = getTimer();
trace('<call-of ['+t+']> ' + arguments.callee.__methodName + '(' + arguments.join(', ') + ')');
return arguments.callee.__originalMethod.apply(this, arguments);
}
pObj[p].__methodName = p;
pObj[p].__originalMethod = tmp;
pObj[p].__traceMessages = arguments.callee;
if (pBlnLastMethodOnly) return '';
}
return '';
}
// example:
// ========
CarClass = function () {
}
CarClass.prototype.init = function () {
this.turnEngineOn();
}
CarClass.prototype.turnEngineOn = function () {
trace('brum brum...');
}
objCar = new CarClass();
traceMessages(objCar); // <--
objCar.init();
// output:
// =======
// <call-of [38]> init()
// <call-of [0]> turnEngineOn()
// brum brum...
Posted by hOk at April 4, 2003 01:53 PM
