源战役客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

413 lines
12 KiB

  1. BaseController = BaseController or BaseClass()
  2. local BaseController = BaseController
  3. local UserMsgAdapter = UserMsgAdapter
  4. BaseController.request_protocals_list = Array.New()
  5. BaseController.handle_protocals = {} --处理的指令列表
  6. BaseController.is_delay_send_protocal = false
  7. function BaseController:__init()
  8. --销毁引用
  9. local function onViewDestoryHandler(view)
  10. self:clearViewQuoted(view)
  11. end
  12. self.clearViewQuoted_BindId = self:Bind(BaseView.DestroyEvent,onViewDestoryHandler)
  13. end
  14. function BaseController:RemoveCheckOutEvent()
  15. end
  16. function BaseController:EnableCheckoutClear(bool)
  17. bool = bool == nil and true or bool
  18. self.checkout_clear_view = bool
  19. if bool then
  20. self.view_list = {} --依附于该控制器的界面
  21. setmetatable(self.view_list, {__mode = "v"}) --弱引用
  22. --创建窗口
  23. local function onViewCreateHandler(list)
  24. self:addView(list)
  25. end
  26. self.CreateView_BindId = self:Bind(BaseView.CreateView,onViewCreateHandler)
  27. local function close_view()
  28. for k,v in pairs(self.view_list) do
  29. v:Close()
  30. end
  31. self:RemoveCheckOutEvent()
  32. end
  33. self:Bind(EventName.CHANGE_ACCOUNT, close_view)
  34. self:Bind(EventName.CHANGE_ROLE, close_view)
  35. end
  36. end
  37. function BaseController:__delete()
  38. if GlobalEventSystem then
  39. if self.clearViewQuoted_BindId then
  40. GlobalEventSystem:UnBind(self.clearViewQuoted_BindId)
  41. self.clearViewQuoted_BindId = nil
  42. end
  43. if self.CreateView_BindId then
  44. GlobalEventSystem:UnBind(self.CreateView_BindId)
  45. self.CreateView_BindId = nil
  46. end
  47. end
  48. if self.checkout_timer then
  49. for k, timer_id in pairs(self.checkout_timer) do
  50. GlobalTimerQuest:CancelQuest(timer_id)
  51. end
  52. self.checkout_timer = nil
  53. end
  54. end
  55. function BaseController:addView(list)
  56. if list and list[1] then
  57. for k,v in pairs(self) do
  58. if list[1] == v then
  59. table.insert(self.view_list,v)
  60. return
  61. end
  62. end
  63. end
  64. end
  65. --清除view的引用
  66. function BaseController:clearViewQuoted(view)
  67. -- if self._class_type._source == view._source then
  68. --只检测baseitem
  69. local function checkBaseItem(table)
  70. --判断纯队列 或者单个baseitem
  71. if type(table) == "table" and (not table._class_type or table._class_type.Class_Type == "BaseItem" or table._is_uitabwindow) then
  72. if (table._class_type and table._class_type.Class_Type == "BaseItem") or table._is_uitabwindow then
  73. if not table._use_delete_method then
  74. if table._is_uitabwindow then
  75. GlobalEventSystem:Fire(LuaErrorModel.SEND_LUAERROR_MESSAGE,"BaseView没清除UITabWindow")
  76. else
  77. GlobalEventSystem:Fire(LuaErrorModel.SEND_LUAERROR_MESSAGE,view._class_type._source.."有baseitem没deleteMe " .. table._class_type._source)
  78. end
  79. end
  80. else
  81. for k, value in pairs(table) do
  82. checkBaseItem(value)
  83. end
  84. end
  85. end
  86. return
  87. end
  88. for k,v in pairs(self) do
  89. if view == v then
  90. -- for p,value in pairs(view) do
  91. -- if type(value) == "number" then
  92. -- if EventSystem.checkHasUnBind(value) then
  93. -- Alert.show(view._class_type._source.."有事件没解绑 "..p)
  94. -- end
  95. -- end
  96. -- end
  97. if not Application.isMobilePlatform then
  98. for p,value in pairs(view) do
  99. if type(value) == "table" and (not value._class_type or value._class_type.Class_Type == "BaseItem" or value._is_uitabwindow) then
  100. checkBaseItem(value)
  101. end
  102. end
  103. end
  104. self[k] = nil
  105. break
  106. end
  107. end
  108. -- end
  109. end
  110. function BaseController:AddSendFmtCheckout(cmd, time, callback)
  111. self.checkout_timer = self.checkout_timer or {}
  112. local timer_id = self.checkout_timer[cmd]
  113. if timer_id then
  114. GlobalTimerQuest:CancelQuest(timer_id)
  115. timer_id = nil
  116. end
  117. timer_id = GlobalTimerQuest:AddDelayQuest(callback,time)
  118. self.checkout_timer[cmd] = timer_id
  119. end
  120. function BaseController:RemoveSendFmtCheckout(cmd)
  121. if self.checkout_timer then
  122. local timer_id = self.checkout_timer[cmd]
  123. if timer_id then
  124. GlobalTimerQuest:CancelQuest(timer_id)
  125. self.checkout_timer[cmd] = nil
  126. end
  127. end
  128. end
  129. --[[@
  130. :
  131. :
  132. id
  133. func_name ProtocalBase类的成员函数名称
  134. :
  135. :
  136. : raowei
  137. ]]
  138. function BaseController:RegisterProtocal(id, func_name)
  139. local register_func = nil
  140. register_func = function(data_list)
  141. local oper_func = self[func_name]
  142. if oper_func then
  143. oper_func(self, data_list)
  144. end
  145. if self.checkout_timer then
  146. local timer_id = self.checkout_timer[id]
  147. if timer_id then
  148. GlobalTimerQuest:CancelQuest(timer_id)
  149. self.checkout_timer[id] = nil
  150. end
  151. end
  152. end
  153. UserMsgAdapter.RegisterMsgOperate(id, register_func)
  154. end
  155. --[[@
  156. : Game服
  157. :
  158. cmd int
  159. fmt_str () string
  160. ...
  161. :
  162. :
  163. : raowei
  164. ]]
  165. function BaseController.SendFmtFromDelayList(vo)
  166. if vo == nil then return end
  167. local cmd = vo.cmd
  168. local fmt_str = vo.fmt_str
  169. local arg_list = vo.args
  170. UserMsgAdapter.WriteBegin(cmd)
  171. if fmt_str ~= nil then
  172. UserMsgAdapter.WriteFMT(fmt_str, unpack(vo.args))
  173. end
  174. UserMsgAdapter.SendToGame()
  175. end
  176. function BaseController:RegisterProtocal2(id, func)
  177. UserMsgAdapter.RegisterMsgOperate(id, func)
  178. end
  179. function BaseController:SendFmtToGame(cmd, fmt_str, ...)
  180. -- if cmd == 32007 or cmd == 12005 or cmd == 12002 or cmd == 61105 then
  181. -- if not LoginModel:getInstance().show_loading_state or cmd == 32007 or cmd == 12005 or cmd == 12002 or cmd == 61105 then
  182. -- BaseController.SendFmtFromDelayList(vo)
  183. -- else
  184. if ... and cmd ~= 12001 then--12001走路发的协议
  185. print("send cmd log: ",cmd,fmt_str,...)
  186. end
  187. if BaseController.is_delay_send_protocal or BaseController.request_protocals_list:GetSize() > 0 then
  188. local vo = {cmd = cmd, fmt_str = fmt_str, args = {...}}
  189. BaseController.request_protocals_list:PushBack(vo)
  190. else
  191. UserMsgAdapter.SendAllFmtToGame(cmd, fmt_str, ...)
  192. end
  193. -- end
  194. end
  195. function BaseController:SendAllFmtToGame2(cmd, fmt_str, ...)
  196. UserMsgAdapter.SendAllFmtToGame2(cmd, fmt_str, ...)
  197. end
  198. function BaseController.DelaySendFmtToGame()
  199. if BaseController.request_protocals_list:GetSize() > 0 then
  200. local vo = BaseController.request_protocals_list:PopFront()
  201. UserMsgAdapter.SendAllFmtToGame(vo.cmd, vo.fmt_str, unpack(vo.args))
  202. end
  203. end
  204. function BaseController:WriteBegin(cmd)
  205. UserMsgAdapter.WriteBegin(cmd)
  206. end
  207. function BaseController:WriteFMT(fmt_str, ...)
  208. UserMsgAdapter.WriteFMT(fmt_str, ...)
  209. end
  210. function BaseController:SendToGame()
  211. UserMsgAdapter.SendToGame()
  212. end
  213. --[[@
  214. :
  215. :
  216. fmt_str () string
  217. :
  218. :
  219. : raowei
  220. ]]
  221. function BaseController:ReadFmt(fmt_str)
  222. return UserMsgAdapter.ReadFmt(fmt_str)
  223. end
  224. --[[@
  225. :
  226. : id
  227. : handler
  228. :
  229. : raowei
  230. ]]
  231. function BaseController:Bind(event_id, event_func,class_name)
  232. return GlobalEventSystem:Bind(event_id,event_func,class_name)
  233. end
  234. --[[@
  235. :
  236. : handler
  237. :
  238. :
  239. : raowei
  240. ]]
  241. function BaseController:UnBind( obj )
  242. GlobalEventSystem:UnBind( obj )
  243. end
  244. --[[@
  245. :
  246. : id
  247. : id
  248. :
  249. : raowei
  250. ]]
  251. function BaseController:Fire(event_id,...)
  252. GlobalEventSystem:Fire( event_id ,...)
  253. end
  254. --[[@
  255. :
  256. : id
  257. : id
  258. :
  259. : raowei
  260. ]]
  261. function BaseController:FireNextFrame(event_id,...)
  262. GlobalEventSystem:FireNextFrame( event_id ,...)
  263. end
  264. --生成model的绑定请求协议的事件
  265. local function BindReqEvent(self, id, req_event_data, register_func)
  266. local req_event_failed_str = "req net proto " .. id .. " failed with fire event " .. req_event_data[1]
  267. local function on_req( ... )
  268. req_event_data[2] = req_event_data[2] or ""
  269. local need_print = self.proto_info[id].show_print
  270. local arge = {req_event_data[2], ...}
  271. if need_print then
  272. local arge_str = ""
  273. if #arge > 0 then
  274. for i,v in ipairs(arge) do
  275. arge_str = arge_str.."[No."..(i)..":"..tostring(arge[i]).."] "
  276. end
  277. else
  278. arge_str = "none arge"
  279. end
  280. print('Cat:BaseController.lua req net proto : '..id.." arges:", arge_str)
  281. --网络协议的参数数量不对!比如"cii"就只需要传入3个,具体传了哪些见上条打印
  282. local has_proto_field_desc = (arge[1] and type(arge[1])=="string")
  283. local need_assert = has_proto_field_desc and (#arge[1] ~= #arge - 1)
  284. if need_assert then
  285. local error_str = req_event_failed_str..":proto fields num not match!"
  286. assert(false, error_str)
  287. end
  288. end
  289. if not self.proto_info[id].is_debug then
  290. if self.proto_info[id].req_func then
  291. table.remove(arge,1)
  292. self.proto_info[id].req_func( self, unpack(arge))
  293. else
  294. self:SendFmtToGame(id, unpack(arge))
  295. end
  296. else
  297. self.proto_info[id].req_arge = arge
  298. register_func()
  299. end
  300. end
  301. self.model:Bind(req_event_data[1], on_req)
  302. end
  303. --自动生成发送和收到网络协议的处理代码,注:之所以是local function就是不想外部调用
  304. local function RegisterProtocalAndReqEvent(self, id, req_event_data)
  305. local register_func = function()
  306. local proto = self.proto_info[id]
  307. if proto.handler_manual then
  308. proto.handler_manual(self)
  309. return
  310. end
  311. if proto.show_print then
  312. assert(_G["SCMD"..id]~=nil, "cannot find SCMD"..id..".lua, have you generated this proto file yet?")
  313. end
  314. --Cat_Todo : 这里可以考虑用个协议对象池,这样就不需要频繁new协议对象了
  315. local scmd = _G["SCMD"..id].New(not proto.is_debug)
  316. if proto.is_debug and self.CreateDebugSCMD then
  317. --如果该协议的is_debug属性为true,调用handler前将进入CreateDebugSCMD函数,在这里返回一个调试用的结构体模仿收到网络信息,之所以放在一个函数里处理是因为想删掉时可以方便点
  318. scmd = self:CreateDebugSCMD(id, scmd, self.proto_info[id].req_arge)
  319. end
  320. if proto.show_print then
  321. print("Cat:BaseController [start:handle"..id..(proto.is_debug and " Debug Model!" or "").."] scmd:", scmd)
  322. PrintTable(scmd)
  323. print("Cat:BaseController [end]")
  324. end
  325. -- local handler = proto.handler or self["Handle"..id]
  326. if proto.handler then
  327. proto.handler(self, scmd, id)
  328. end
  329. end
  330. UserMsgAdapter.RegisterMsgOperate(id, register_func)
  331. if req_event_data and req_event_data[1] then
  332. BindReqEvent(self, id, req_event_data, register_func)
  333. end
  334. end
  335. --[[说明:
  336. :Req请求协议的代码,Req请求协议事件时可以传入收到回复协议的回调函数,Ack收到协议的事件;CreateDebugSCMD函数里方便管理;,show_print为true时除了打印请求和收到的协议内容,,便bug
  337. :proto_info:
  338. )key值为协议id
  339. )req_event_data会生成self.model的绑定事件,BaseController,nil就不生成;:
  340. req_event_data第一个参数是事件名
  341. )handler就是收到后端回复时的处理函数,CreateDebugSCMD之后
  342. )handler_manual就是收到后端回复时的手写处理函数,CreateDebugSCMD
  343. )req_func就是适应部分自己处理发协议的事件响应{self, }
  344. )is_debug为true的话将不发送协议,;
  345. )show_print控制是否在请求和收到协议时打印相关信息
  346. ]]--
  347. function BaseController:RegisterProtocalByCFG(proto_info)
  348. self.proto_info = proto_info
  349. self.ack_call_back = self.ack_call_back or {}
  350. for k,v in pairs(self.proto_info) do
  351. RegisterProtocalAndReqEvent(self, k, v.req_event_data)
  352. end
  353. end
  354. --打开界面
  355. function BaseController:OpenView( class_name, show, ... )
  356. if show then
  357. if not self[class_name] then
  358. self[class_name] = _G[class_name].New()
  359. end
  360. if not self[class_name]:HasOpen() then
  361. self[class_name]:Open(...)
  362. end
  363. else
  364. if self[class_name] then
  365. self[class_name]:Close(...)
  366. end
  367. end
  368. end