代码改变世界

cocos2d-x开发: 完善接口范例分离模块

2014-12-25 21:01  respawn  阅读(620)  评论(0编辑  收藏  举报

在上一篇文章中,我阐述了一下为什么要做分离这种工作,这篇文章没什么重点,只是将上一次没有完善的工作做完.原本我想做到像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 += "\t";
 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,复杂度会高一点.

这篇没什么,所以就说到这里吧.