一、 自定义事件用在xml里面自定义的control里面,也就是里面的event_def,目前的自定义事件支持多种类型的多个参数和多个返回值,例如下面一个定义:
<event_def>
<OnSelChange>
<param>
<string/>
<string/>
<int/>
</param>
<return>
<int/>
</return>
</OnSelChange>
</event_def>
上面的例子中定义了一个自定义事件OnSelChange,该事件接收3个参数(实际上是接收5个参数,见下面详述),分别是两个字符串和一个整型,返回值为一个参数,是一个整型;那么可以按照如下方法来使用这个自定义事件:
Catalog是控件的id,也就是事件定义所在的control,第一个参数指明了事件名是“OnSelChange”
catalog:FireExtEvent("OnSelChange", curID, oldID, 0)
二、 自定义事件格式
从上面的例子可以看出,自定义事件的xml格式如下:
<event_def>
<事件名>
<param>
根据需要自定义的参数
</param>
<return>
根据需要自定义的返回值
</return>
</事件名>
</event_def>
每个控件的event_def节点下面可以有多个自定义事件,每个自自定义事件的节点 就是事件名称,在同一个event_def下面,事件名称不可重复。如上面例子中的OnSelChange就是一个自定义事件。
每个自定义事件下面由param和return两个节点来指明参数和返回值。Param和return均可以有零个或者多个,也可以省略不写,则代表没有参数或者返回值,例如:
<param>
<uint>
<hostwnd>
<param>
<return>
</return>
表示接受一个无符号整型和一个hostwnd对象,并且无返回值,具体可定义的参数类型见下面详细描述。
三、 支持的参数类型:
名称 | 代表的类型 |
bool | bool |
char | char |
uchar | unsigned char |
short | short |
ushort | unsigned short |
int | int |
uint | unsigned int |
long | long |
ulong | unsigned long |
float | float |
double | double |
string | string |
layoutobj | object或者control |
objtree | 对象树 |
hostwnd | hostwnd对象 |
animation | 动画对象 |
template | 模板对象 |
table | Lua table数据类型 |
function | Lua function数据类型 |
在配置好自定义事件的类型后,在调用FireExtEvent(“事件名称”, 自定义参数列表)时候,自定义参数列表需要按照param自顶向下定义的类型,自左向右的依次传递相应的参数,
关于类型转换:
1、 这里需要注意的是:假如定义的参数类型是对象类型,也就是layoutobj、objtree、hostwnd、animation或者template,那么需要传入指定类型的参数或者0,否则现在由于类型机制的缺陷,出现不可预期的结果,比如崩溃。
2、 对于lua数据类型table和function,内部不对尝试做转型处理,会直接传递给事件收听者使用。
3、 对于其它的c和c++自定义的类型,则具有自动转型的功能,比如定义了bool,可以传一个int进去,内部转型时候会截断成bool类型,会按照c和c++的类型转换机制进行转换,但是尽量传递的实参和定义的形参的类型要一致。
4、 假如定义了n个参数,那么可以传递的参数个数m有以下情况:
a) m=n 也就是最常见的情况,一个萝卜一个坑儿,并且类型尽量匹配。
b) m<n 也就是实参个数少于定义的参数个数,没有被对应上的参数将采用每个参数类型的默认值,字符串是””,其它类型都是0.
c) m>n 也就是传递的实参个数多于定义的参数个数,那么多于定义参数个数的参数将会被忽略,这种情况应该是不小心写错了吧。。。
5、 这里需要注意的是,所有自定义事件的都有两个默认参数在最前面,第一个是obj对象,也就是layoutobj类型,第二个是事件名称xxx,也就是string类型。也就是说对于事件定义和触发者来说,事件是有n个参数,则对于事件接收者来说,会有n+2个参数,这个时候前面那两个隐藏函数就显示出来了,可以使用。这两个类型是每个事件都有的,也不需要用户显示指明,在调用FireExtEvent时候也不需要关心,但是对于事件接收者来说是可见的。
比如对于上面的例子,用户定义了三个参数,那么实际上该事件的参数列表应该是
<param>
<layoutobj>
<string>
<string/>
<string/>
<int/>
</param>
前面两个参数就是隐藏的参数。
四、 自定义事件的响应函数/接收者
和普通事件的响应函数一样,不同的是接收的实际参数和返回值需要按照自定义事件的param和return的定义列表来使用。比如事件OnSelChange的响应函数如下:
<event name="OnSelChange">
local arg = {...}
local item = arg[1] // 第一个参数,隐藏参数layoutobj,指明了触发事件的obj
local eventname = arg[2]//第二个参数,隐藏参数string,指明了事件名
//称”OnSelChange”
local curID= arg[3] // 第三个参数,也就是param里面定义的第一个显示参数
local oldID = arg[4] // 第四个参数,也就是param里面定义的第一个显示参数
local data = arg[5] // 第五个参数,也就是param里面定义的第一个显示参数
。。。。。。
return 0 // 返回者,需要和return里面定义的类型匹配。
</event>