获取函数表达式的参数(AS3)

时间:2014-04-22 17:26:46

标签: actionscript-3

这适用于我正在使用的网络库(ActionScript3)。我在其他库(player.io)中看到了这个概念。没有对代码的完全访问权限,所以我试图找出它是如何完成的。我喜欢它的外观,易于理解和简化过程,所以试图做类似的事情。

var myclass:Connection = new Connection(ip, port); //create new connection
//move is packet ID

myclass.addMsgHandler("move", function (x:int, y:int):void
{

bob.x = x;
bob.y = y;

});

myclass.addMsgHandler("attack", function (mob:String, atk:String, dmg:int):void
{

mobDict[mob].hp -= dmg*atk;

});

然后我清楚地写出我的数据包,以及当我收到某些身份证时该怎么做......

Inside Connection类需要做什么:

public function addMsgHandler(id:*, listener:Function):void
{
//get id, add it to packet id list...

//figure out parameters of listener (example: x:int, y:int)
//if I encounter the id "move" in tcp stream expect 2 integers

//for example mob:String, atk:String, dmg:int
//expect 2 strings in stream after "attack", probably will have to look for /0 to know where string ends
//also expect dmg 4 bytes......

}

不确定实施的复杂程度,但是我看过的图书馆似乎正在这样做......也许我误解了它是如何工作的,但这正是我想要完成的。

2 个答案:

答案 0 :(得分:0)

首先,这两者之间没有区别:

myclass.addMsgHandler("move", function (x:int, y:int):void{ });

myclass.addMsgHandler("move", moveHandler);

function moveHandler(x:int, y:int():void { }

您只需传递对函数的引用。

第二 - 我无法想出一种完全获得函数参数的方法。您可以使用length属性来检查其计数。但我认为你不能得到他们的类型。

这就是为什么最好的方法是将类型化对象(类)作为属性。通过这种方式,您的Connection课程可以简单地检查所发生的事情(if (handler == MoveHandler)),并且您将确切地知道该做什么以及您有多少参数。

答案 1 :(得分:0)

您可以在类上使用describeType()来访问其所有方法,包括参数和返回类型。所以这个:

trace( describeType( this ).toXMLString() );

会返回这样的内容:

<method name="addChild" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject">
  <parameter index="1" type="flash.display::DisplayObject" optional="false"/>
</method>

你可以解析你的类,然后根据你传递的函数的字符串名称,你知道要读什么。

不幸的是,对于方法闭包,它会返回类似于:

的内容
<type name="builtin.as$0::MethodClosure" base="Function" isDynamic="false" isFinal="true" isStatic="false">
  <extendsClass type="Function"/>
  <extendsClass type="Object"/>
  <accessor name="length" access="readonly" type="int" declaredBy="Function"/>
  <accessor name="prototype" access="readwrite" type="*" declaredBy="builtin.as$0::MethodClosure"/>
</type>

这不是非常有用,因为它没有传递我们需要的任何信息。你可能会按照以下方式解决问题:

public function addMsgHandler( event:String, obj:*, funcName:String ):void
{
    // 1) parse obj (you'd only need to do this once per class, as it's not quick)
    // 2) find the definition of obj[funcName]
    // 3) read the params etc
    // 4) add the listener - obj[funcName] is a Function object
}

尽管如此,大多数服务器库都发送一个预定义的对象,其中每个消息都以长度(推荐)为前缀或以空字节结束。

在您的情况下,您的对象可能如下所示:

public class ServerMsg
{
    public var event:String = null;
    public var success:Boolean = false;
    public var attachment:* = null;
}

然后你以正常的信号/事件监听器风格调度你的事件 - 它仍然是干净的,可以说是更干净 - 每个回调只需要一个ServerMsg类型的参数,并且特定的参数只是被需要它们的对象所知(即你的Connection类并不需要知道attack()需要两个Stringsint