首页 > 代码库 > [网游客户端业务逻辑] unity下使用lua开发业务逻辑
[网游客户端业务逻辑] unity下使用lua开发业务逻辑
我们的游戏有这样一种情景:客户端中角色需要用到一些公会的数据,但服务器不会在玩家(创角后)一进入到游戏里就推送给玩家,而是需要客户端自己在需要的时候向服务器请求公会的数据,之前的实现就是在请求消息的时候加一个回调函数,消息一回来就执行回调函数继续后续的业务!但后面发现存在这样的不足:
1.有时会用到好多个参数,这就需要每次都把一些无关的参数传给消息请求者,然后回调过来再把这些参数原封不动地传回来,很繁琐;
2.这样的回调写法感觉很不符合人类的顺序思维习惯,有点乱;
回调的lua代码写法类似:
--@callbackFunc带的参数可能有(self, p1, p2, ..., [最后还有allianceData, 这个是取到数据后分发时加上的]) function AllianceProxy:requestAllianceData(callbackFunc) --handle send request msg --这里使用一个uniqueKey往一个管理器中注册保存这个回调 end function AllianceProxy:responseAllianceData(allianceData) --handle receive response msg --这里根据上面uniqueKey分发消息,执行回调, 调用类似:callbackFunc(self, p1, p2, ..., allianceData) end --请求公会数据的写法就是这样: function Role:handleAllianceData() local function _callbackFunc(self, p1, p2, allianceData) --使用的到allianceData处理相关的业务逻辑 end AllianceProxy:requestAllianceData(packing(_callbackFunc, self, p1, p2)) --packing返回的仍然是一个function end
上述的参数self, p1, p2, ...等等完全就没必要往requestAllianceData中丢过去的,但就是因为收到回调后需要用到,作为强迫症的我,觉得这种写法很恶心,所以今天想到,这完全可以利用lua提供的协程机制来做这件事,大致思路的代码如下:(注:下面这些代码未经过编译及测试,另外还未考虑协程恢复执行时若其主函数所在table被销毁的情况, 后续会完善下面的代码)
--创建并运行一个协程 --@param mainFunc 协程主函数 function global:createAndRunningCo(mainFunc) self:assertFmt(type(mainFunc) == ‘function‘, ‘func=%s is not function‘, tostring(mainFunc)) local co = coroutine.create(mainFunc) local isSuccess, errMsg = coroutine.resume(co, co) self:assertFmt(isSuccess, ‘one error happened in mainFunc:%s‘, errMsg) end function global:checkCoIsRunning(co) self:assertFmt(type(co) == ‘thread‘) local curCo = coroutine.running() self:assertFmt(co == curCo, ‘co[%s] is not running, current running coroutine is %s, please sure that co is running‘, co, curCo) end function global:yieldAndSaveCo(key, co) self:assertFmt(key ~= nil) self:checkCoIsRunning(co) if coT[key] == nil then coT[key] = {} end table.insert(coT[key], co) return coroutine.yield() end function global:resumeAndRemoveCo(key, ...) if coT[key] then for _, co in ipairs(coT[key]) do if coroutine.status(co) == ‘suspended‘ then local isSuccess, errMsg = coroutine.resume(co, ...) self:assertFmt(isSuccess, ‘one error happened in mainFunc:%s‘, errMsg) end end coT[key] = nil end end
local global = require(‘global‘) global:createAndRunningCo(function(co) local allianceData = http://www.mamicode.com/Alliance:requestAllianceData(co) --do something end) function AllianceProxy:requestAllianceData(co) --send msg : request alliance Data return global:yieldAndSaveCo(‘allianceData‘, co) end function AllianceProxy:responseAllianceData(allianceData) --receive msg : response alliance data global:resumeAndRemoveCo(‘allianceData‘, allianceData) end
需要获取公会数据的用户就使用下面这样的写法则可:
global:createAndRunningCo(function(co)
local allianceData = http://www.mamicode.com/Alliance:requestAllianceData(co)
--do something
end)
然后在消息收发那里做好相应的处理就行了,这个写法跟前面的对比,很明显,我们顺序的编写相应的逻辑就行了,完全不需要像前面的说等回调过来后反过头来再执行相应的逻辑
[网游客户端业务逻辑] unity下使用lua开发业务逻辑
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。