PDA

View Full Version : calling functions dynamically AS2-AS3 Nightmare



dlivva
January 31st, 2008, 09:34 AM
Hi all,
First of all let me state my position as a designer first and coder second (probably third or fourth if the truth be known). This does not mean that I hate code, its just that I code on a needs basis. Even so I have managed to put (cobble) together some quite interesting things using AS2 and would say that I was comfortable and even moderately proficient with it.

However I have just tried to take the step up to using AS3 and Im dumbfounded. Where's everything gone?

It was bad enough realising almost the entire way of doing things would have to change, but to then find that the documentation seems to assume a level of knowledge of coding structure, practices and methods that are so far beyond me that I feel like Im learning from scratch.

Now that Ive had my rant, here's my problem...
In AS2 this worked fine:


function moveClip(){
myClip._x+=20;
}
functionName=eval(moveClip());
eval(functionName);


How do I achieve the same thing with AS3?

(I know that there are those amongst us that frown upon using the eval function but it works for me and I wasnt aware of an alternative until recently.)

kkos
January 31st, 2008, 10:43 AM
check this (http://www.kirupa.com/forum/showthread.php?t=259717)out. :inc:

dlivva
January 31st, 2008, 11:57 AM
Thanks for that. Ive taken a look and tried it with umteen variations but always get errors. I know Im missing something fundamental but cant put my finger on it.
Obviously the eval script wont work but, here's the ACTUAL code as things stand...


//Create Listeners
obj1.addEventListener(MouseEvent.CLICK, doit);
obj2.addEventListener(MouseEvent.CLICK, doit);
obj3.addEventListener(MouseEvent.CLICK, doit);

//Function to move objects
function doit(e:MouseEvent) {

var functionTitle:String = "DYNAMIC_"+e.currentTarget.name;

// Call correct function depending on which was clicked
eval(functionTitle());

if (e.currentTarget.x>stage.stageWidth) {
e.currentTarget.x=10;
}
e.currentTarget.x+=amt;
}

//Functions to set how far to move
function DYNAMIC_obj1(){
var amt:int=10;
}
function DYNAMIC_obj2(){
var amt:int=20;
}
function DYNAMIC_obj3(){
var amt:int=30;
}

ofeet
January 31st, 2008, 12:17 PM
I'm going to TRY to help, and hopefully not confuse you. If I do- please disregard me, even as a human being.

I've actually been asking about eval this morning and the threads I read say eval doesn't exist anymore. so in your situation you might try something like this:

instead of:


eval(functionTitle());

do:


this[functionTitle]();

Hopefully that works for ya.

Dazzer
January 31st, 2008, 12:42 PM
private function yourMethodHere():void{
trace('hi');
}

private var functionname:Function = yourMethodHere;

functionname(); // If this does not work then try
functionname.apply(this,null); //This



http://livedocs.adobe.com/flex/2/langref/Function.html

dlivva
February 4th, 2008, 05:24 AM
Thanks for the code. It actually solves another problem I was thinking about but hadnt got round to yet.

Sadly it doesn't solve this one.
Assuming I have 2 buttons on the stage called "but1" and "but2". I want to be able to call a function that is unique based on the instance name of the button that called it. This will enable me to create as many instances as I like that can all call different functions.
If I use the syntax you suggest then this code works:

function click1(e:MouseEvent):void{
var functionname:Function = DYNAMIC_but1;
functionname.apply(this,null);
}
HOWEVER. I want to actually state which function I want to call dynamically. So this code is more like what Im trying to acheive:

function click1(e:MouseEvent):void{
var functionname:Function = DYNAMIC_+e.currentTarget.name;
functionname.apply(this,null);
}

Dazzer
February 4th, 2008, 06:10 AM
very eww

You can reference it using the [] syntax



var functionname:Function = this[DYNAMIC_+e.currentTarget.name];


But like i said... Ugly. Think twice before going down this route.

spasticfantastic
February 4th, 2008, 06:30 AM
Looks like Dazzer has got your back. To confirm his posts:


// this is where as3 is different
var someFunction:Function = someOtherFunction;
// this line will have the same effect as someOtherFunction()
// or even this["some" + "Other" + "Function"]()
someFunction();


I'd like to add that probably the most straightforward way to do what you want is to have a switch statement in your handler function, that switches on the event target, a la:



function handleButtonClick(eo:MouseEvent) : void {
switch(eo.target) {
case someButton1:
doButton1Stuff();
break;
case someButton2:
doButton2Stuff();
break;
}
}

dlivva
February 4th, 2008, 06:44 AM
Ok.
I accept that way may be ugly (even if Im not sure why), but I dont have a plan B to think twice about let alone a "pretty way".

Also. Replacing

var functionname:Function=DYNAMIC_+e.currentTarget.nam e;
with

var functionname:Function=this[DYNAMIC_+e.currentTarget.name];
Results in an error.

Here's what Im trying to do (and found really easy to do with AS2)...

1-I have a clip in libary.
2-I want to be able to load multiple instances of that clip and give each a unique name.
(no problems so far)
3-For each clip I need to be able to (a) Dynamically create a function and (b) call that function when the required event occurs.

What I find frustrating is the fact that in AS2 it would have took a grand total of about 5 minutes to do. Surely Im not alone in finding the transition to AS3 somewhat more less than simple :crazy:

spasticfantastic
February 4th, 2008, 06:53 AM
How about as you create the clips, store the clip and it's relating function in a dictionary object. Then when you handle the click, get the function to call from the dictionary a la:



function handleButtonClick(eo:MouseEvent) : void {
dictionary[eo.target]();
}


(Fortunately you can keep coding in AS2 if you like... ;) )

dlivva
February 4th, 2008, 08:00 AM
Fortunately you can keep coding in AS2 if you like...

Yes I could. And that's exactly what I am doing until I'm comfortable with AS3 (I would have assumed that you'd assume that). But thanks for the suggestion ;)