local function covert2LuaString(str) return string.toLuaString(str); end; local function getGlobalValueName(func) for k, v in pairs(_G) do if v == func then return k; end end return nil; end; local function eval2FuncString(exp, isInteger) if exp == "" then return "emptyFunction"; end; local bNeedLoadEnv = true; local x_n = 0; for i = 1, 20 do if string.find(exp, "x" .. i) then x_n = i; end end local paramString = ""; for i = 1, x_n do if i == 1 then paramString = paramString .. "x" .. i; else paramString = paramString .. ", x" .. i; end end local expString; if x_n == 0 then bNeedLoadEnv = isInteger; if tonumber(exp) then expString = "(" .. exp .. ")"; else --expString = "(\"" .. exp .. "\")"; if isInteger then return "toInterEval(" .. covert2LuaString(exp) .. ")"; else return "toEval(" .. covert2LuaString(exp) .. ")"; end end else expString = "(" .. exp .. ")"; end; if isInteger then expString = "Math.ceil" .. expString; end local ret; if bNeedLoadEnv then local envString = ""; for i , v in pairs(ServerScriptEnv) do envString = envString .. "local " .. i .. " = ServerScriptEnv." .. i .. "; "; end ret = string.format("function(%s)%s local ret = %s; return ret; end", paramString, envString, expString); else ret = string.format("function(%s) return %s; end", paramString, expString); end; return ret; end; -- 解析配置文件的一行数据 local function buildConfigString(skill, desc) local str = ""; for k, v in pairsByKeys(skill) do local keyString; if type(k) == "number" then keyString = tostring(k); else keyString = "\"" .. tostring(k) .. "\""; end; local valueType = type(v); if valueType == "number" then str = str .. string.format("[%s] = %s;\n", keyString, tostring(v)); elseif valueType == "string" then str = str .. string.format("[%s] = %s;\n", keyString, covert2LuaString(v)); elseif valueType == "boolean" then str = str .. string.format("[%s] = %s;\n", keyString, tostring(v)); elseif valueType == "table" then if type(v.exp) == "string" then local func = desc.Mapping[k]; local funcString; if func == toEval then funcString = eval2FuncString(v.exp, false); elseif func == toInterEval then funcString = eval2FuncString(v.exp, true); else error("暂时不支持的函数类型 " .. tostring(getGlobalValueName(func))); end; str = str .. string.format("[%s] = %s;\n", keyString, funcString); --[[ local func = desc.Mapping[k]; local funcString = getGlobalValueName(func); if not funcString then error("无法识别的转换函数"); end local luaString = covert2LuaString(v.exp); str = str .. string.format("[%s] = %s(%s);\n", keyString, funcString, luaString); ]] else str = str .. string.format("[%s] = \n{\n", keyString); str = str .. buildConfigString(v, desc); str = str .. "\n};\n"; end; elseif valueType == "userdata" then if tolua.type(v) == "CCPoint" then str = str .. string.format("[%s] = ccp(%s, %s);\n", keyString, tostring(v.x), tostring(v.y)); elseif tolua.type(v) == "ccColor3B" then str = str .. string.format("[%s] = ccc3(%d, %d, %d);\n", keyString, v.r, v.g, v.b); end elseif valueType == "function" then print("发现一个函数需要处理"); local funcString = getGlobalValueName(v); assert(funcString, "指向的函数不在_G内"); str = str .. string.format("[%s] = %s;\n", keyString, funcString); else error("无法识别的类型 " .. keyString .. " 类型为" .. valueType); end end return str; end; -- 解析一个配置文件 function saveLuaXMLConfig(config, configDesc, filename) print("序列化配置" , filename) local file = io.open(filename, "wb"); if file then file:write([[local t = {};]] .. '\n'); local defSecKey = configDesc.DefaultSecondKey; if defSecKey then local keyString; if type(defSecKey) == "number" then keyString = tostring(defSecKey); else keyString = "\"" .. tostring(defSecKey) .. "\""; end; local str = [[ local function secDefaultData(self, key) if key == "get" then return function(s , kk) return rawget(s , kk); end end local value = rawget(self, key); if value then return value; else print("找不到配置[" .. "%s" .. "]键为[" ..tostring(key) .. "]的值,将使用默认键[" .. %s .. "]代替"); return rawget(self, %s); end; end ]]; str = string.format(str, configDesc.XMLFile, keyString, keyString); file:write(str); end; for KeyName, skill in pairsByKeys(config) do if type(skill) == "table" then local keyString; if type(KeyName) == "number" then keyString = "t[" .. KeyName .. "]"; else keyString = "t[\"" .. KeyName .. "\"]"; end; file:write(keyString .. " = \n{\n"); local str = buildConfigString(skill, configDesc, true); file:write(str); file:write("\n};\n"); if defSecKey then str = string.format([[setmetatable(%s, {__index = secDefaultData});]] .. "\n", keyString); file:write(str); end; elseif type(skill) == "function" then print(filename, KeyName); print("发现一个函数需要处理"); if type(KeyName) == "number" then file:write("t[" .. KeyName .. "] = "); else file:write("t[\"" .. KeyName .. "\"] = "); end; local funcString = getGlobalValueName(skill); assert(funcString, "指向的函数不在_G内"); local str = string.format("%s;\n", funcString); file:write(str); else error("无法识别的类型 " .. KeyName .. " 类型为" .. type(skill)); end; end local defaultKey = configDesc.DefaultKey; if defaultKey then local keyString; if type(defaultKey) == "number" then keyString = tostring(defaultKey); else keyString = "\"" .. tostring(defaultKey) .. "\""; end; local str = string.format([[ local method = { }; local function defaultData(self, key) if method[key] then return method[key]; end; local value = rawget(self, key); if value then return value; else print("找不到配置[" .. "%s" .. "]键为[" ..tostring(key) .. "]的值,将使用默认键[" .. %s .. "]代替"); return rawget(self, %s); end end; function method:get(key) return rawget(t , key); end; ]], configDesc.XMLFile, keyString, keyString); file:write(str); file:write("\n"); file:write([[setmetatable(t, {__index = defaultData});]]); file:write("\n"); else local str =[[ local method = { }; local function defaultData(self, key) if method[key] then return method[key]; end; end; function method:get(key) return rawget(t , key); end; ]]; file:write(str); file:write("\n"); file:write([[setmetatable(t, {__index = defaultData});]]); file:write("\n"); end file:write([[return t;]]); file:close(); end; end; function loadLuaXMLConfig(filename , configDesc) if configDesc.postload then table.insert(g_allXMLPostload , configDesc.postload) end print("读取lua配置" , filename) local data = cc.FileUtils:getInstance():readData(filename); local uncompressData = lzma.uncompress(data); local n,r = loadstring(uncompressData); if n == nil then error("载入文件" .. tostring(filename) .. "时出错" .. r); end local luaCfg = n(); local mt = getmetatable(luaCfg); if mt then local oldIndex = mt.__index; mt.__index = function(self, key) if key == "LuaFile" then return filename; elseif key == "XmlFile" then print("configDesc.XMLFile" , configDesc.XMLFile); return configDesc.XMLFile; end return oldIndex(self , key); end end return luaCfg; end;