Finding the method name from an ExternalInterface.addCallback - actionscript-3

Let's say we have a number of ExternalInterface.addCallback functions, like so:
ExternalInterface.addCallback( 'foo', handler );
ExternalInterface.addCallback( 'bar', handler );
ExternalInterface.addCallback( 'foobar', handler );
In the function handler I'd like to find the method name called through the external interface, such as foo, bar or foobar; is there a way? Eg:
private function handler(...args):void
{
arguments.callee.arguments[ 0 ];
}
But I doubt that'll work

This should work. Just pass a parameter that identifies your function from the javascript, for example a string. So when you call the flash-function in your javascript code, pass a string, which you then parse in your handler function. For example:
actionscript:
ExternalInterface.addCallback( 'foo', handler );
private function handler(s:String):void
{
if(s == "foo") {
//foo specific code
}
}
javascript:
document.getElementById('flashObj').foo("foo");

Not exactly what you are asking for, but it will give you the info you need.
Just make the first parameter that you send the function name or in this case the object with funcname attribute so you can test if it exists.
JavaSCript
function thisMovie(movieName) {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName];
} else {
return document[movieName];
}
}
thisMovie("ExternalInterfaceExample").genericCallBack({ funcname:'foo' })
thisMovie("ExternalInterfaceExample").genericCallBack({ funcname:'poo' })
thisMovie("ExternalInterfaceExample").genericCallBack({ funcname:'moo' })
AS3
public function foo( ):void{
trace('in foo')
}
public function poo( ):void{
trace('in poo')
}
public function moo( ):void{
trace('in moo')
}
public function genericCallBack( o:Object ):void{
trace( 'calling '+o.funcname)
this[o.funcname]()
}
// add this somewhere in your init process
ExternalInterface.addCallback( 'genericCallBack', genericCallBack );

Related

D (dlang) passing a lambda function as argument

With D, how can I pass a function (possibly reference to a function) as an argument to be executed inside other function?
import std.stdio : writeln;
class Event {}
class EventTarget
{
void addEventListener(string eventName, void delegate(Event event) callback)
{
// TODO: add to slice to execute later, for now execute directly
callback();
}
}
void main()
{
auto variableFromParentScope = "lorem ipsum";
auto target = new EventTarget();
target.addEventListener("load", (Event event) => { writeln(variableFromParentScope, event); }, true);
}
Gives me the error:
onlineapp.d(10): Error: delegate callback(Event event) is not callable using argument types ()
onlineapp.d(10): missing argument for parameter #1: Event event
onlineapp.d(18): Error: function onlineapp.EventTarget.addEventListener(string eventName, void delegate(Event event) callback) is not callable using argument types (string, void delegate() #system delegate(Event event) pure nothrow #safe, bool)
onlineapp.d(18): cannot pass argument __lambda1 of type void delegate() #system delegate(Event event) pure nothrow #safe to parameter void delegate(Event event) callback
I have set up the example here: https://run.dlang.io/is/FnQoId
SOLUTION, With the help from the answers I fixed it like this:
import std.stdio : writeln;
class Event {}
class EventTarget
{
void addEventListener(string eventName, void delegate(Event event) callback)
{
// TODO: add to slice to execute later, for now execute directly
callback(new Event());
}
}
void main()
{
auto variableFromParentScope = "lorem ipsum";
auto target = new EventTarget();
target.addEventListener(
"load",
(Event event) {
writeln(variableFromParentScope, event);
}
);
}
Working example: https://run.dlang.io/is/6aDRoU
You are using the wrong syntax for the delegate, as you can also see in the error message it doesn't have the expected type.
To explain further, I will show you how it changes if you extend it to the longer form of a delegate instead of using the shorthand =>:
(Event event) => { writeln(variableFromParentScope, event); }
becomes
(Event event) { return { writeln(variableFromParentScope, event); }; }
As you can see you are returning a delegate with no parameters inside your actual delegate. If you remove the =>, your delegate will work as expected.
Alternative valid forms for your delegate parameter would be:
(event) { ... }
delegate (Event event) { ... }
delegate (event) { ... }
&someMemberMethod // some object member method taking in Event as first parameter
toDelegate(&someGlobalFunction) // from std.functional
Only if you want to return something you use the => arrow. A use-case for () => { something } would be a delegate returning a delegate (like a delegate generating delegates for a given input)
But also wrong in your question is that you are calling that function with a , true in the calling parameters, which makes the error message very confused, and that you aren't passing an event parameter to the callback, which would be another error in the code snippet.
target.addEventListener("load", (Event event) => { writeln(variableFromParentScope, event); }, true);
(Args) => {} is a lambda which returns a lambda.
Correct forms:
target.addEventListener("load", (Event event) { writeln(variableFromParentScope, event); }, true);
target.addEventListener("load", (Event event) => writeln(variableFromParentScope, event), true);

Is it possible to make use of a value returned from a method called by a delegate?

While experimenting with a basic coding stuff, I wondered, if a value returned by a method called by a delegate, could be used or captured. In other words, where will the return value will go ?
For example :
class Main extends Sprite
{
public var mc:MyMc;
function Main()
{
mc.addEventListener( "myClick" , myClick);
}
function myClick(e:Event):String //returning a string
{
return "What happens to this return value ???"
}
}
class MyMc extends MovieClip
{
function MyMc()
{
addEventListener( MouseEvent.CLICK , onClick);
}
function onClick(e:Event):String //returning a string
{
dispatchEvent(new Event("myClick"));
}
}
As I know it's not possible to do, but, there are at least some ways to implement the logic similar to what you've told about.
For example, you may call a method of a dispatcher, from a listener method:
class Main extends Sprite
{
public var mc:MyMc;
function Main()
{
mc.addEventListener("myClick" , myClick);
}
function myClick(e:Event):void
{
mc.specialMethod("some string");
}
}
class MyMc extends MovieClip
{
function MyMc()
{
addEventListener(MouseEvent.CLICK , onClick);
}
function onClick(e:Event):void
{
dispatchEvent(new Event("myClick"));
}
public function specialMethod(param:String):void
{
// Do something to the param
}
}
Also, you may think about dispatching an event from the Main class, and listen to it in the MyMc class, or pass a callback, which returns a string, from Main to the MyMc.
It's according to you and your needs to return something from the listener function because normally it must return nothing :
... This function must accept an Event object as its only parameter and must return nothing, ...
but you can of course get the returned value(s), take a look on this little example :
var light_on:Boolean = false;
btn_light_on.addEventListener(MouseEvent.CLICK, btn_on_onPress);
btn_light_off.addEventListener(MouseEvent.CLICK, btn_off_onPress);
function btn_on_onPress(e:MouseEvent): Boolean {
light_on = true;
if(e.target === btn_light_off){
light_on = false;
}
return light_on;
}
function btn_off_onPress(e:MouseEvent): void {
trace('The light is', btn_on_onPress(e) ? 'on' : 'off');
}
Hope that can help.

Using a callback (instead of an event) in Actionscript 3.0

Can anyone provide an example of how to write a callback instead of using an event to communicate between two classes (objects) in Actionscript 3.0?
Just pass a function to another one as parameter to make your callback :
class A {
function A(){
}
// function to be called when work is finished
private function workDone():void {
//...
}
public function foo():void {
var b:B=new B();
b.doWork(workDone); // pass the callback to the work function
//can also be an anonymous function, etc..
b.doWork(
function():void{
//....
}
);
}
}
class B {
function B(){
}
public function doWork(callback:Function):void{
// do my work
callback(); // call the callback function when necessary
}
}
What do you mean? A callback is a function that is called in response to an event - in AS parlance, it's an event listener. If you just want classes to communicate, have one of them call a method on the other.

How to call "this" from an anonymous method?(flex, as)

This is my code:
public function setPaneContent(names : Array, parent : AbstractPane) : void {
//....
okButton.addEventListener(MouseEvent.CLICK, function okMouseClickHandler(e : Event) : void {
parent.addNewPane(valuesPane, parent);
PopUpManager.removePopUp(/*need to put "this"*/);
});
//.....
}
When i call PopUpManager.removePopUp(/*need to put "this"*/);, i need to make a reference at the object that contains this method(this).
So my question is: "Is it possible to make a reference at 'this' keyword within an anonymous method?"
store this to some variable: _this = this in the constructor, use _this. (it works in javascript)
You don't have to, you can call another function
public function setPaneContent(names : Array, parent : AbstractPane) : void
{
okButton.addEventListener(MouseEvent.CLICK,
function okMouseClickHandler(e : Event) :void
{
parent.addNewPane(valuesPane, parent);
// call the remove function where you can reference "this"
remove();
});
//.....
}
private function remove():void
{
PopUpManager.removePopUp(this);
}

Passing a function to another function in Actionscript 3

I have a function that passes an array to another function as an argument, there will be multiple data types in this array but I want to know how to pass a function or a reference to a function so the other function can call it at any time.
ex.
function A:
add(new Array("hello", some function));
function B:
public function b(args:Array) {
var myString = args[0];
var myFunc = args[1];
}
Simply pass the function name as an argument, no, just like in AS2 or JavaScript?
function functionToPass()
{
}
function otherFunction( f:Function )
{
// passed-in function available here
f();
}
otherFunction( functionToPass );
This is very easy in ActionScript:
function someFunction(foo, bar) {
...
}
function a() {
b(["hello", someFunction]);
}
function b(args:Array) {
var myFunc:Function = args[1];
myFunc(123, "helloworld");
}
You can do the following:
add(["string", function():void
{
trace('Code...');
}]);
...or...
...
add(["string", someFunction]);
...
private function someFunction():void
{
trace('Code...');
}