• `cocos2dx非完整` 开始自己的FW模块


    上一篇的文章中说到了一些个人习惯的东西以及一些简单的项目配置,这一篇文章我们来进一步完善一些东西.首先,打开编译以后的客户端执行,会看到一大堆的fileutils加载luac文件的提示,在终端显示一大堆,挺烦人的,我做的第一件事就是去修改他.这个很简单,有两种做法,第一种是在c++部分添加调用

     1 cocos2d::FileUtils::getInstance()->setPopupNotify(false); 

    当然也可以在lua部分添加,

     1 cc.FileUtils:getInstance():setPopupNotify(false) 

    两种做法都很简单,根据自己选择.我选择是在AppDelegate.cpp中添加.暂时没有在c++部分添加自己的模块,因为现在还不需要,后面需要的时候会再说.我将新项目中的其他lua文件全部删除了,res下面的所有资源也都删除了,修改了main.lua中的源码,只留下了引擎启动初始化glview部分的代码,这样就足够了,无论是开发一款什么样子的项目,我们都是从这里开始的.修改后的源码如下,很多同学不用看,只是为了保持我写文章的原始目的,尽量说明我的思路.

     1 -- 小岩<757011285@qq.com>
     2 -- 2015-5-25 13:10
     3 cc.FileUtils:getInstance():addSearchPath("res")
     4 cc.FileUtils:getInstance():addSearchPath("src")
     5 
     6 require "cocos.init"
     7 local fw = require "fw.init"
     8 
     9 function __G__TRACKBACK__(msg)
    10     print("lua error: " .. tostring(msg) .. "
    ")
    11     print(debug.traceback())
    12     return msg
    13 end
    14 
    15 local function main()
    16     collectgarbage("collect")
    17     -- avoid memory leak
    18     collectgarbage("setpause", 100)
    19     collectgarbage("setstepmul", 5000)
    20 
    21     -- initialize director
    22     local director = cc.Director:getInstance()
    23     local glview = director:getOpenGLView()
    24     if nil == glview then
    25         glview = cc.GLViewImpl:createWithRect("HelloLua", cc.rect(0,0,900,640))
    26         director:setOpenGLView(glview)
    27     end
    28 
    29     glview:setDesignResolutionSize(480, 320, cc.ResolutionPolicy.NO_BORDER)
    30 
    31     --turn on display FPS
    32     director:setDisplayStats(true)
    33 
    34     --set FPS. the default value is 1.0/60 if you don't call this
    35     director:setAnimationInterval(1.0 / 60)
    36 
    37 end
    38 
    39 local status, msg = xpcall(main, __G__TRACKBACK__)
    40 if not status then
    41     error(msg)
    42 end
    main.lua

    好的,可能很多人做到这里,就会思考并开始写代码了.我像这样应该还是缺少很多东西的,尤其是我们做过一些项目后就知道,有很多基础的模块和功能还是需要的,实现这个过程就像是盖房子打地基,我就花费了半天的时间来做这件事情.我先是构思了一下,然后稍作修改了一下项目的目录结构.修改后的目录结构如下:

    -- res

    -- src

       -- cocos

       -- fw

          -- ini.lua

          -- util

             -- fileutil.lua

             -- platform.lua

             -- convert.lua

          -- oop

             -- ini.lua

             -- csv.lua

             -- kv.lua

             -- classickv.lua

       -- game

       -- main.lua

    好的下面我来解释一下这个目录.我添加了fw目录作为项目通用的模块,这样做是有好处的,如果以后项目需要的话,做的好,我完全可以直接把这个模块拿过去,稍作修改甚至是不用修改就可以胜任了,也就是积累我们自己的代码.当然,鱿鱼经验受限,我们会一次又一次的重构这个模块,就像我,不停的去修改去完善,让它在某些方面更合理.其实昨天我主要是添加了三个方面的功能:

    1.我将cc.FileUtils里面的结构全部倒入了我写的fileutil中,并添加了部分自己的功能,源码如下:

     1 -- 小岩<757011285@qq.com>
     2 -- 2015-5-25
     3 local platform = require "fw.util.platform"
     4 
     5 local fu = {}
     6 local cc_fileutils_ = cc.FileUtils:getInstance()
     7 
     8 function fu.is_dir(filename)
     9     return string.byte(filename, -1) == 47
    10 end
    11 
    12 function fu.is_absolute_path(filename)
    13     return cc_fileutils_:isAbsolutePath(filename)
    14 end
    15 
    16 function fu.get_writable_path(filename)
    17     if filename then
    18         return platform.get_writable_path() .. filename
    19     end
    20     return platform.get_writable_path()
    21 end
    22 
    23 function fu.get_full_path(filename)
    24     return cc_fileutils_:fullPathForFilename(filename)
    25 end
    26 
    27 function fu.get_string(filename)
    28     return cc_fileutils_:getStringFromFile(filename)
    29 end
    30 
    31 function fu.write_content(filename, content, mode)
    32     mode = mode or "w+b"
    33     local file = io.open(filename, mode)
    34     if file then
    35         if file:write(content) == nil then 
    36             return false
    37         end
    38         io.close(file)
    39         return true
    40     else
    41         return false
    42     end
    43 end
    44 
    45 function fu.is_exists(filename)
    46     if fu.is_dir(filename) then
    47         return cc_fileutils_:isDirectoryExist(filename)
    48     end
    49     return cc_fileutils_:isFileExist(filename)
    50 end
    51 
    52 function fu.make_dir(dirname)
    53     return cc_fileutils_:createDirectory(dirname)
    54 end
    55 
    56 function fu.remove(filename)
    57     if fu.is_dir(filename) then
    58         return cc_fileutils_:removeDirectory(filename)
    59     end
    60     return cc_fileutils_:removeFile(filename)
    61 end
    62 
    63 function fu.rename_file(dir, old, new)
    64     return cc_fileutils_:renameFile(dir, old, new)
    65 end
    66 
    67 function fu.get_file_size(filename)
    68     return cc_fileutils_:getFileSize(filename)
    69 end
    70 
    71 return fu
    fileutil.lua

    2.添加了跨平台部分的文件存储处理,主要是处理writablepath.这个在platform.lua中,很快我就会写到增量动态更新模块,我期望在windows下面存储的路径就是res/,而在android下面则是writablepath.所以这个修改也是为了这部分功能先行的.源码如下:

     1 -- 小岩<757011285@qq.com>
     2 -- 2015-5-25
     3 local p = {}
     4 
     5 local OS_NAME = 
     6 {
     7     "WINDOWS",
     8     "LINUX",
     9     "MAC",
    10     "ANDROID",
    11     "IPHONE",
    12     "IPAD",
    13     "BLACKBERRY",
    14     "NACL",
    15     "EMSCRIPTEN",
    16     "TIZEN",
    17     "WINRT",
    18     "WP8",
    19 }
    20 
    21 local arch_code = cc.Application:getInstance():getTargetPlatform()
    22 local arch_name = OS_NAME[arch_code+1]
    23 
    24 p.arch_code = arch_code
    25 p.arch_name = arch_name
    26 
    27 function p.get_writable_path()
    28     if p.arch_code == cc.PLATFORM_OS_WINDOWS then
    29         return "res/"
    30     else
    31         return cc.FileUtils:getInstance():getWritablePath()
    32     end
    33 end
    34 
    35 return p
    platform.lua

    3.处理各种配置文件,我暂时添加了四种,k-v有两种,ini格式,csv格式,准确的说是三种,不过我提供的classickv是支持lua语法的,因为本质上就是使用luastring返回的函数生成的,所以可以直接在其中使用lua语法,如果是使用sublime,可以直接ctrl+shift+p, 然后输入set synatax:lua去直接编辑配置文件.不过很快我就会再次介绍这种使用lua语法的好处,用在启动引擎的各种参数上面再好不过了.下面我就一一给出这四个文件.不过首先得看convert.lua 这个其实就是各加载到内存的配置字符串,解析成为对应的lua table.

      1 -- 小岩<757011285@qq.com>
      2 -- 2015-5-25
      3 local c = {}
      4 
      5 c.t = 
      6 {
      7     kv     = "key-value format",
      8     ini = "section-key-value format",
      9     csv = "export csv format",
     10     classickv = "classic key-value format",
     11 }
     12 
     13 local function lua_split(str, reps)
     14     local str_list = {}
     15     string.gsub(str, '[^' .. reps ..']+', function(w) 
     16             table.insert(str_list, w) 
     17         end)
     18     return str_list
     19 end
     20 
     21 function c.c2t(content, type, ...)
     22     if type == c.t.kv then
     23         return c.c2t_kv(content, ...)
     24     elseif type == c.t.ini then
     25         return c.c2t_ini(content, ...)
     26     elseif type == c.t.csv then
     27         return c.c2t_csv(content, ...)
     28     elseif type == c.t.classickv then
     29         return c.c2t_kv(content)
     30     end
     31     return "unsupport-format"
     32 end
     33 
     34 function c.c2t_kv(content, sep, l_sep)
     35     sep   = sep or "="
     36     l_sep = l_sep or "
    "
     37     
     38     local ret = {}
     39     for _, line in ipairs(lua_split(content, l_sep)) do
     40         local k,v = line:match('^([%w_]+)%s-' .. sep .. '%s-(.+)$')
     41         if k then
     42             if not v then
     43                 v = ""
     44             end
     45             if tonumber(v) then
     46                 v =tonumber(v)
     47             elseif v == "true" then
     48                 v = true
     49             elseif v == "false" then
     50                 v = false
     51             end
     52             ret[k] = v
     53         end
     54     end
     55     return ret
     56 end
     57 
     58 function c.c2t_classickv(content)
     59     return loadstring("return {" .. content .. "}")()
     60 end
     61 
     62 function c.c2t_ini(content, sl_sep, sr_sep, kv_sep, l_sep)
     63     sl_sep = sl_sep or "["
     64     sr_sep = sr_sep or "]"
     65     kv_sep = kv_sep or "="
     66     l_sep  = l_sep or "
    "
     67 
     68     local ret = {}
     69     local sec
     70     for _, line in ipairs(lua_split(content, l_sep)) do
     71         local section = line:match('^%' .. sl_sep ..  '([^%]]+)%' .. sr_sep .. '$')
     72         if section then
     73             sec = section
     74             ret[sec] = ret[sec] or {}
     75         end
     76 
     77         local k,v = line:match('^([%w_]+)%s-' .. kv_sep .. '%s-(.+)$')
     78         if k and v then
     79             if tonumber(v) then
     80                 v = tonumber(v)
     81             elseif v == "true" then
     82                 v = true
     83             elseif v == "false" then
     84                 v = false
     85             end
     86 
     87             if sec then
     88                 ret[sec][k] = v
     89             end
     90         end
     91     end
     92 
     93     return ret
     94 end
     95 
     96 function c.c2t_csv(content, sep, l_sep)
     97     sep   = sep or ","
     98     l_sep = l_sep or "
    "
     99 
    100     local ct = lua_split(content, l_sep)
    101     local headers = lua_split(ct[1], sep)
    102     table.remove(ct, 1)
    103 
    104     local ret = {}
    105     local n = 1
    106     for _, line in ipairs(ct) do
    107         local vks = lua_split(line, sep)
    108         ret[n] = {}
    109         for j =1, #headers do
    110             ret[n][headers[j]] = vks[j]
    111         end
    112         n = n + 1
    113     end
    114 
    115     return ret
    116 end
    117 
    118 function c.c2s(t, type, ...)
    119     if type == c.t.kv then
    120         return c.c2s_kv(t, ...)
    121     elseif type == c.t.ini then
    122         return c.c2s_ini(t, ...)
    123     elseif type == c.t.csv then
    124         return c.c2s_csv(t, ...)
    125     elseif type == c.t.classickv then
    126         return c.c2s_kv(t)
    127     end    
    128     return "unsupport-format"
    129 end
    130 
    131 function c.c2s_kv(t, sep, l_sep)
    132     sep   = sep or "="
    133     l_sep = l_sep or "
    "
    134     local content = ""
    135     for k, v in pairs(t) do
    136         content = content .. tostring(k) .. sep .. tostring(v) .. l_sep  
    137     end
    138     return content
    139 end
    140 
    141 function c.c2s_ini(t, sl_sep, sr_sep, kv_sep, l_sep)
    142     sl_sep = sl_sep or "["
    143     sr_sep = sr_sep or "]"
    144     kv_sep = kv_sep or "="
    145     l_sep  = l_sep or "
    "
    146 
    147     local content = ""
    148     for s, kv in pairs(t) do
    149         content = content .. sl_sep .. tostring(s) .. sr_sep .. l_sep 
    150         for k, v in pairs(kv) do
    151             content = content .. tostring(k) .. kv_sep .. tostring(v) .. l_sep 
    152         end
    153     end
    154     return content
    155 end
    156 
    157 function c.c2s_csv(t, sep, l_sep)
    158     sep   = sep or ","
    159     l_sep = l_sep or "
    " 
    160 
    161     local content = "" 
    162     local header = ""
    163     for index, kv in ipairs(t) do
    164         for k, v in pairs(kv) do
    165             if index == 1 then
    166                 header = header .. tostring(k) .. sep                 
    167             end
    168             content = content .. tostring(v) .. sep
    169         end
    170         content = content .. l_sep
    171     end
    172 
    173     return l_sep .. header .. l_sep .. content
    174 end
    175 
    176 return c
    convert.lua
     1 -- 小岩<757011285@qq.com>
     2 -- 2015-5-26
     3 local fu       = require "fw.util.fileutil"
     4 local convert = require "fw.util.convert"
     5 local kv = class("kv")
     6 
     7 function kv:ctor(filename, ...)
     8     self.filename_ = filename
     9     self.extra_cfg_ = {...}
    10     self:init_with_file()
    11 end
    12 
    13 function kv:copy()
    14     return clone(self)
    15 end
    16 
    17 function kv:init_with_file()
    18     assert(self.filename_ and type(self.filename_) == "string", 
    19         string.format("ini assert error: init_with_file() - invalid param %s", self.filename_))
    20     local file_content = fu.get_string(self.filename_)
    21     self.props_ = convert.c2t(file_content, convert.t.kv, unpack(self.extra_cfg_))
    22 end
    23 
    24 function kv:get(k)
    25     assert(k and type(k) == "string",
    26         string.format("ini assert error: get() - invalid param %s", k))
    27     return self.props_[k]
    28 end
    29 
    30 function kv:update(k, nv)
    31     local ov = self.props_[k]
    32     self.props_[k] = nv
    33     return ov
    34 end
    35 
    36 function kv:save_2_path(new_filepath)
    37     local old_filepath = self.filename_
    38     local content = convert.c2s(self.props_, convert.t.kv, unpack(self.extra_cfg_))
    39     if fu.write_content(new_filepath, content) then
    40         self.filename_ = new_filepath
    41         return old_filepath
    42     end
    43     return nil
    44 end
    45 
    46 function kv:save()
    47     local content = convert.c2s(self.props_, convert.t.kv, unpack(self.extra_cfg_))
    48     if fu.write_content(self.filename_, content) then
    49         return true
    50     end
    51     return false
    52 end
    53 
    54 return kv
    kv.lua
     1 --小岩<757011285@qq.com>
     2 --2015-5-26
     3 local fu        = require "fw.util.fileutil"
     4 local convert = require "fw.util.convert"
     5 local classickv = class("classickv")
     6 
     7 function classickv:ctor(filename)
     8     self.filename_  = filename
     9     self:init_with_file() 
    10 end
    11 
    12 function classickv:copy()
    13     return clone(self)
    14 end
    15 
    16 function classickv:init_with_file()
    17     assert(self.filename_ and type(self.filename_) == "string", 
    18         string.format("ini assert error: init_with_file() - invalid param %s", self.filename_))
    19 
    20     local file_content = fu.get_string(self.filename_)
    21     self.props_ = convert.c2t(file_content, convert.t.classickv)
    22 end
    23 
    24 function classickv:get(k)
    25     assert(k and type(k) == "string",
    26         string.format("ini assert error: get() - invalid param %s", k))
    27     return self.props_[k]
    28 end
    29 
    30 function classickv:update(k, nv)
    31     local ov = self.props_[k]
    32     self.props_[k] = nv
    33     return ov
    34 end
    35 
    36 function classickv:save_2_path(new_filepath)
    37     local old_filepath = self.filename_
    38     local content = convert.c2s(self.props_, convert.t.classickv)
    39     if fu.write_content(new_filepath, content) then
    40         self.filename_ = new_filepath
    41         return old_filepath
    42     end
    43     return nil
    44 end
    45 
    46 function classickv:save()
    47     local content = convert.c2s(self.props_, convert.t.classickv)
    48     if fu.write_content(self.filename_, content) then
    49         return true
    50     end
    51     return false
    52 end
    53 
    54 return classickv
    classickv.lua
    -- 小岩<757011285@qq.com>
    -- 2015-5-25
    local fu        = require "fw.util.fileutil"
    local convert = require "fw.util.convert" 
    local ini = class("ini")
    
    function ini:ctor(filename, ...)
        self.filename_ = filename or nil
        self.extra_cfg_ = {...}
        self:init_with_file()
    end
    
    function ini:copy()
        return clone(self)
    end
    
    function ini:init_with_file()
        assert(self.filename_ and type(self.filename_) == "string", 
            string.format("ini assert error: init_with_file() - invalid param %s", self.filename_))
    
        local file_content = fu.get_string(self.filename_)
        self.props_ = convert.c2t(file_content, convert.t.ini, unpack(self.extra_cfg_))
    end
    
    function ini:get(s, k)
        assert(s and type(s) == "string",
            string.format("ini assert error: get() - invalid param %s", s))
        assert(k and type(k) == "string",
            string.format("ini assert error: get() - invalid param %s", k))
    
        if self.props_[s] then
            return self.props_[s][k]
        else
            return nil
        end
    end
    
    function ini:update(s,k,nv)
        if not self.props_[s] then
            self.props_[s] = {}
        end
        local ov = self.props_[s][k]
        self.props_[s][k] = nv
        return ov
    end
    
    function ini:save_2_path(new_filepath)
        local old_filepath = self.filename_
        local content = convert.c2s(self.props_, convert.t.ini, unpack(self.extra_cfg_))
        if fu.write_content(new_filepath, content) then
            self.filename_ = new_filepath
            return old_filepath
        end
        return nil
    end
    
    function ini:save()
        local content = convert.c2s(self.props_, convert.t.ini, unpack(self.extra_cfg_))
        if fu.write_content(self.filename_, content) then
            return true
        end
        return false
    end
    
    return ini
    ini.lua
     1 -- 小岩<757011285@qq.com>
     2 -- 2015-5-25
     3 local fu        = require "fw.util.fileutil"
     4 local convert = require "fw.util.convert"
     5 local csv = class("csv")
     6 
     7 function csv:ctor(filename, ...)
     8     self.filename_ = filename
     9     self.extra_cfg_ = {...}
    10     self:init_with_file()
    11 end
    12 
    13 function csv:copy()
    14     return clone(self)
    15 end
    16 
    17 function csv:init_with_file()
    18     assert(self.filename_ and type(self.filename_) == "string", 
    19         string.format("ini assert error: init_with_file() - invalid param %s", self.filename_))
    20 
    21     local file_content = fu.get_string(self.filename_)
    22     self.props_ = convert.c2t(file_content, convert.t.csv, unpack(self.extra_cfg_))
    23 end
    24 
    25 function csv:get(n, k)
    26     if self.props_[n] then
    27         return self.props_[n][k]
    28     else
    29         return nil
    30     end
    31 end
    32 
    33 function csv:update(n, k, nv)
    34     if not self.props_[n] then
    35         return nil
    36     end
    37     local ov = self.props_[n][k]
    38     self.props_[n][k] = nv
    39     return ov
    40 end
    41 
    42 function csv:save_2_path(new_filepath)
    43     local old_filepath = self.filename_
    44     local content = convert.c2s(self.props_, convert.t.csv, unpack(self.extra_cfg_))
    45     if fu.write_content(new_filepath, content) then
    46         self.filename_ = new_filepath
    47         return old_filepath
    48     end
    49     return nil
    50 end
    51 
    52 function csv:save()
    53     local content = convert.c2s(self.props_, convert.t.csv, unpack(self.extra_cfg_))
    54     if fu.write_content(self.filename_, content) then
    55         return true
    56     end
    57     return false
    58 end
    59 
    60 return csv
    csv.lua

    我在每一个针对配置文件的操作oop实现table中都提供了从文件读取以及持久化到文件的方法.不过如果使用lua sytax方式的classic.那么在持久化的时候并不能如期的解析table,这也是当初我没有注意到的问题,不过后来我想了一下,如果是需要持久化的数据,那么我都会使用基本数据类型.所以这个不会影响我的使用.好的,另外一点需要注意的是,读取文件的接口我并没有使用lua的io接口,这是因为lua默认还是有环境变量的,不能够读取apk压缩包中的配置,所以我还是使用cc.fileutils中的接口.

    好的,早上总结了一下昨天完成的内容. 接下来考虑实现那一块先.

  • 相关阅读:
    线程正常终止pthread_exit,pthread_join,pthread_kill,pthread_cancel,sigwait,sigaddset
    线程的创建,pthread_create,pthread_self,pthread_once
    线程和进程的关系
    改变进程的优先级,nice,getpriority,setpriority
    setuid和setgid
    等待进程结束wait,waitpid
    执行新程序以及环境变量
    进程退出exit、_exit、abort
    VBA 判断单元格是否为公式,可用于数组
    ADODB 调用存储过程
  • 原文地址:https://www.cnblogs.com/respawn/p/4529964.html
Copyright © 2020-2023  润新知