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

Actionscript 3 获取函数表达式的参数(AS3),actionscript-3,Actionscript 3,这是网络库,我正在编写ActionScript3。我在其他library player.io中看到了这个概念。。我没有完全访问代码的权限,所以我正在试图弄清楚它是如何完成的。我喜欢它的外观,易于理解并简化了流程,因此尝试完成类似的工作 var myclass:Connection = new Connection(ip, port); //create new connection //move is packet ID myclass.addMsgHandler("move", functi

这是网络库,我正在编写ActionScript3。我在其他library 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;

});
然后我清楚地写下我的数据包,当我收到某个ID时该怎么办

内部连接类需要执行的操作:

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......

}

不知道实现起来会有多复杂,但我浏览过的库似乎正在这样做。。也许我误解了它的工作原理,但这正是我想要实现的。

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

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

只需将引用传递给函数

第二,我想不出一个方法来完全得到函数的参数是什么。您可以使用length属性检查它们的计数。但我认为你不能得到他们的类型

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

您可以在类上使用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>
尽管如此,大多数服务器lib发送一个预定义的对象,其中每条消息要么以建议的长度开头,要么以空字节结尾

在您的情况下,您的对象可能看起来像:

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

然后以正常的信号/事件侦听器样式发送事件-它仍然是干净的,可以说更干净-每个回调只需要接受一个ServerMsg类型的参数,特定参数只由需要它们的对象知道,即您的连接类不需要知道攻击需要两个字符串和int

过早地点击submit?:Phaha,是的-我在写示例时一直在按tab键:D认为你已经编辑了它,但显然没有,我强烈建议不要使用describeType,因为它非常慢。但我同意你最新的部分,说它应该发送键入的对象:正如我还写的“干杯!”!是的,describeType不是你一直想做的事情,但是将结果缓存到字典中是非常简单的,所以你只需要为每个类做一次。而且,如果您知道将要使用的类,您可以在加载状态或其他情况下对它们进行预缓存。如果您知道您的类,最好只为该特定类编写if语句。在这里使用describeType将产生我无法想象的抽象。但是,是的,有时它是有帮助的:
<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;
}