目前觉得比较好的做法,C++写具体控件效果,lua处理事件响应
<EventList>
<Event Name="OnCreate" File="LogonWnd.xml.lua" Func="MSG_OnCreate"/>
</EventList>
function MSG_OnCreate(self)
i = 0
print(self)
end
self为事件源注册到lua中的类型事例。
迅雷界面库中还有另一种做法:
function OnInit()
local owner = self:GetOwner()
local objFactory = XLGetObject("Xunlei.UIEngine.ObjectFactory")
local newIcon = objFactory:CreateUIObject("icon2","ImageObject")
local xarManager = XLGetObject("Xunlei.UIEngine.XARManager")
newIcon:SetResProvider(xarManager)
newIcon:SetObjPos(45,165,45+70,165+70)
newIcon:SetResID("app.icon2")
local function onClickIcon()
XLMessageBox("Don't touch me!")
end
newIcon:AttachListener("OnLButtonDown",true,onClickIcon)
self:AddChild(newIcon)
end
直接在lua层处理事件,貌似更舒服了。但是所引用的函数不能是上层C的,也不能有self参数了,否则内存管理又是一大害处。
这里的AttachListener应该和上层的Wnd类或者对应的派发消息的CPP里边的《EventList》关联,貌似这样能动态添加消息处理器,而且不用担心对象生命周期管理。
观摩了一下迅雷的sdk给的粒子,发现他们可能修改了虚拟机,发现在不同的文件中会有相同的函数,而且都是全局的,联想到前面配置的时候要给定一个文件名和一个函数名,要么就傻逼的每次调用前都要loadfile一次,不然很可能修改lua虚拟机,或者lua api支持按文件索引。
问题:cpp向lua派发事件的时候函数名,名字冲突。迅雷的做法是文件名+函数名索引,但是目前我的技术积累做不到。
解决办法:
1.靠自己约定,即自己确保所有lua文件中都没有相同的函数
2.参考魔兽世界,然后加点佐料的做法:<scripts file="LogonWnd.lua" /> <Event EventName="BtnClick" EventSink="LogonWnd.BtnClick">
也就是默认每个文件名中的所有函数都在以文件名为名字控件的作用域下