在上一篇文章中,我阐述了一下为什么要做分离这种工作,这篇文章没什么重点,只是将上一次没有完善的工作做完.原本我想做到像Lua-tests那样子,能够一次完全显示所有的tests,然后选择要执行的test.可是后来想了一下,没必要做这么多,就简单处理了.不过对于分离处理这个目标是没有偏离的.模块代码部分主要是添加了一个控制和一个接口实现:
1 --------------------------------------------------------------------- 2 -- @Author 小岩 3 -- @Created on 2014-12-25 19:39 4 -- @Brief Tests 5 --------------------------------------------------------------------- 6 require "src/Tests/TestsRequired" 7 8 TestsController = class("TestsController", nil) 9 ----------------------------------------------------------- 10 -- ctor 11 function TestsController:ctor() 12 Logger.Info("--------------------------------------------------") 13 Logger.Debug(" Running Mode [" .. self.__cname .. "]" ) 14 end 15 ----------------------------------------------------------- 16 -- 单例方法 17 function TestsController:getInstance() 18 if self.instance == nil then 19 self.instance = TestsController.new() 20 end 21 return self.instance 22 end 23 ----------------------------------------------------------- 24 -- 运行测试 25 function TestsController:runTests() 26 --TestsCase.new():run() 27 end 28 --------------------------------------------------------------------- 29 -- End Of Lua File 30 ---------------------------------------------------------------------
想要运行test,只需要在runTests方法中运行自己的test就好了.接口实现如下:
1 --------------------------------------------------------------------- 2 -- @Author 小岩 3 -- @Created on 2014-12-25 20:06 4 -- @Brief 测试用例 5 --------------------------------------------------------------------- 6 TestsCase = class("TestsCase", nil) 7 ----------------------------------------------------------- 8 -- 输出当前测试用例的名字,子类不需要override 9 function TestsCase:ctor() 10 Logger.Info("---------------------------------------------------") 11 Logger.Warn(" Start TestCase [" .. self.__cname .. "]" ) 12 end 13 ----------------------------------------------------------- 14 -- 需要子类实现的接口,实现需要的业务逻辑 15 function TestsCase:run() 16 error("Error: " ..self.__cname.. ":run() method not implemented!") 17 end 18 --------------------------------------------------------------------- 19 -- End Of Lua File 20 ---------------------------------------------------------------------
很简单的实现,就需要过多说明什么了,仔细看看extern.lua中class的实现就明白了.我还做了一下额外的工作,也算是对之前写过的代码做了一次修改.不知道怎么回事,看以前写过的代码有的时候会很不爽,禁不住就要做一些修改和重构之类的事情,没办法,这是无药可治的毛病.logger实现,是我在c++部分写的接口,lua这边也做了一点点的封装:
1 --------------------------------------------------------------------- 2 -- @Author 小岩 3 -- @Created on 2014-12-25 19:33 4 -- @Brief Log lua 封装 5 --------------------------------------------------------------------- 6 Logger = {} 7 ----------------------------------------------------------- 8 -- Trace 9 function Logger.Trace(fmt, ...) 10 xy.Logger.Trace(string.format(fmt, ...)) 11 end 12 ----------------------------------------------------------- 13 -- Info 14 function Logger.Info(fmt, ...) 15 xy.Logger.Info(string.format(fmt, ...)) 16 end 17 ----------------------------------------------------------- 18 -- Debug 19 function Logger.Debug(fmt, ...) 20 xy.Logger.Debug(string.format(fmt, ...)) 21 end 22 ----------------------------------------------------------- 23 -- Warn 24 function Logger.Warn(fmt, ...) 25 xy.Logger.Warn(string.format(fmt, ...)) 26 end 27 ----------------------------------------------------------- 28 -- Error 29 function Logger.Error(fmt, ...) 30 xy.Logger.Error(string.format(fmt, ...)) 31 end 32 ----------------------------------------------------------- 33 -- Fatal 34 function Logger.Fatal(fmt, ...) 35 xy.Logger.Fatal(string.format(fmt, ...)) 36 end 37 --------------------------------------------------------------------- 38 -- End Of Lua File 39 ---------------------------------------------------------------------
相应的c++部分的代码是LogUtils.h/LogUtils.cc,我也做了跨平台部分的处理,为了不增加大家的负担,linux部分的处理我就不发出来了.我在opensuse/win7上面都是在使用,所以是没有问题的.代码如下:
1 #include "LogUtils.h" 2 #include "cocos2d.h" 3 4 #if __cplusplus 5 extern "C" { 6 #endif 7 #include "lualib.h" 8 #include "lauxlib.h" 9 #if __cplusplus 10 } 11 #endif 12 enum LoggerLevel 13 { 14 TRACE_, INFO_, DEBUG_, WARN_, ERROR_, FATAL_, NUM_MAX, 15 }; 16 const char* LoggerName[LoggerLevel::NUM_MAX] = 17 { 18 "[Logger.Trace]", "[Logger.Info ]", "[Logger.Debug]", "[Logger.Warn ]", "[Logger.Error]", "[Logger.Fatal]" 19 }; 20 const std::string getLuastackLogMessage(lua_State* L) 21 { 22 int nargs = lua_gettop(L); 23 std::string logMsg; 24 for (int i=1; i <= nargs; i++) 25 { 26 if (lua_istable(L, i)) 27 logMsg += "table"; 28 else if (lua_isnone(L, i)) 29 logMsg += "none"; 30 else if (lua_isnil(L, i)) 31 logMsg += "nil"; 32 else if (lua_isboolean(L, i)) 33 { 34 if (lua_toboolean(L, i) != 0) 35 logMsg += "true"; 36 else 37 logMsg += "false"; 38 } 39 else if (lua_isfunction(L, i)) 40 logMsg += "function"; 41 else if (lua_islightuserdata(L, i)) 42 logMsg += "lightuserdata"; 43 else if (lua_isthread(L, i)) 44 logMsg += "thread"; 45 else 46 { 47 const char * str = lua_tostring(L, i); 48 if (str) 49 logMsg += lua_tostring(L, i); 50 else 51 logMsg += lua_typename(L, lua_type(L, i)); 52 } 53 if (i!=nargs) 54 logMsg += " "; 55 } 56 return logMsg; 57 } 58 #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) 59 WORD LoggerColor[LoggerLevel::NUM_MAX] = 60 { 61 /* intensity */FOREGROUND_INTENSITY, 62 /* green */FOREGROUND_GREEN, 63 /* cyan */FOREGROUND_GREEN|FOREGROUND_BLUE, 64 /* yellow */FOREGROUND_RED|FOREGROUND_GREEN, 65 /* red */FOREGROUND_RED, 66 /* red */FOREGROUND_RED, 67 }; 68 void outputLogMessage(LoggerLevel level, const std::string& logMsg) 69 { 70 HANDLE hConsole = ::GetStdHandle(STD_OUTPUT_HANDLE); 71 if(INVALID_HANDLE_VALUE == hConsole) { return; } 72 ::SetConsoleTextAttribute(hConsole, LoggerColor[level]); 73 cocos2d::log("%s %s", LoggerName[level], logMsg.c_str()); 74 ::SetConsoleTextAttribute(hConsole, 7); 75 return; 76 } 77 #elif (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) 78 void outputLogMessage(LoggerLevel level, const std::string& LogMsg) {} 79 #else 80 void outputLogMessage(LoggerLevel level, const std::string& LogMsg) {} 81 #endif 82 83 #define IMPLEMENTS_LOG_FUNCTION(NAME) 84 int LogUtil_Logger_##NAME(lua_State* L) 85 { 86 const std::string& logMsg = getLuastackLogMessage(L); 87 outputLogMessage(LoggerLevel::NAME, logMsg); 88 return 0; 89 } 90 91 IMPLEMENTS_LOG_FUNCTION(TRACE_) 92 IMPLEMENTS_LOG_FUNCTION(INFO_) 93 IMPLEMENTS_LOG_FUNCTION(DEBUG_) 94 IMPLEMENTS_LOG_FUNCTION(WARN_) 95 IMPLEMENTS_LOG_FUNCTION(ERROR_) 96 IMPLEMENTS_LOG_FUNCTION(FATAL_) 97 98 namespace xy 99 { 100 const luaL_Reg global_log_functions[] = 101 { 102 {"Trace", LogUtil_Logger_TRACE_}, 103 {"Info", LogUtil_Logger_INFO_}, 104 {"Debug", LogUtil_Logger_DEBUG_}, 105 {"Warn", LogUtil_Logger_WARN_}, 106 {"Error", LogUtil_Logger_ERROR_}, 107 {"Fatal", LogUtil_Logger_FATAL_}, 108 {NULL, NULL}, 109 }; 110 void register_xy_LogUtils(lua_State* L) 111 { 112 luaL_register(L, "xy.Logger", global_log_functions); 113 } 114 }
这次调整,大概减少了接近五十多行的代码,另外,在结构和代码实行上面也相应要好了很多.这一部分也算是辅助模块的实现了,接下来做通信,资源更新,资源加载策略,加解密,http验证,模块事件,UI封装部分我都会在测试模块做,最后再考虑要着手做一款什么样的游戏来玩玩,这还要看我能找到什么样的资源.最好是ARPG,复杂度会高一点.
这篇没什么,所以就说到这里吧.