forked from endernon/PGRData
262 lines
No EOL
7.5 KiB
Lua
262 lines
No EOL
7.5 KiB
Lua
local tostring = tostring
|
||
local load = load
|
||
local type = type
|
||
local ipairs = ipairs
|
||
local pairs = pairs
|
||
local string = string
|
||
local table = table
|
||
|
||
local stringDump = string.dump
|
||
local stringGmatch = string.gmatch
|
||
local tableUnpack = table.unpack
|
||
local tableInsert = table.insert
|
||
local tableSort = table.sort
|
||
local tableConcat = table.concat
|
||
|
||
|
||
XSaveTool = XSaveTool or {}
|
||
XSaveTool.LocalCache = {}
|
||
|
||
local StrCache = {} --字符串缓存
|
||
local ClearCacheTime = 5 * 60 -- 清除缓存时间
|
||
local LuaDataHeader = "LuaData:"
|
||
|
||
|
||
--region ------------------obj -> string start-------------------
|
||
local function fret(...)
|
||
local args = { ... }
|
||
return function()
|
||
return tableUnpack(args)
|
||
end
|
||
end
|
||
|
||
local function updateStrCache(key, value, now)
|
||
StrCache[key] = {
|
||
Value = value,
|
||
UpdateTime = now
|
||
}
|
||
|
||
for k, v in pairs(StrCache) do
|
||
if now - v.UpdateTime >= ClearCacheTime then
|
||
StrCache[k] = nil
|
||
end
|
||
end
|
||
end
|
||
|
||
local function getStrFromCache(key, newFunc)
|
||
local temp = StrCache[key]
|
||
local now = XTime.GetServerNowTimestamp()
|
||
if temp then
|
||
temp.UpdateTime = now
|
||
return temp.Value
|
||
end
|
||
local result = newFunc()
|
||
updateStrCache(key, result, now)
|
||
return result
|
||
end
|
||
|
||
local function getLuaDataKey(key)
|
||
local temp = StrCache[key]
|
||
if temp then
|
||
return getStrFromCache(key)
|
||
end
|
||
local newFunc = function()
|
||
return string.format("%s%s", LuaDataHeader, key)
|
||
end
|
||
return getStrFromCache(key, newFunc)
|
||
end
|
||
|
||
local function NilStringify(val, needSort, cache)
|
||
return "nil"
|
||
end
|
||
|
||
local function BoolStringify(val, needSort, cache)
|
||
return tostring(val)
|
||
end
|
||
|
||
local function NumStringify(val, needSort, cache)
|
||
return tostring(val)
|
||
end
|
||
|
||
local function FuncStringify(val, needSort, cache)
|
||
return string.format("function(...) return load(%s)(...) end", XSaveTool.Stringify(stringDump(val), needSort, cache))
|
||
end
|
||
|
||
local function StrStringify(val, needSort, cache)
|
||
local temp = StrCache[val]
|
||
if temp then
|
||
return getStrFromCache(val)
|
||
end
|
||
local newFunc = function()
|
||
local s = "\""
|
||
for c in stringGmatch(val, ".") do
|
||
s = string.format("%s\\%s", s, c:byte())
|
||
end
|
||
return string.format("%s\"", s)
|
||
end
|
||
return getStrFromCache(val, newFunc)
|
||
end
|
||
|
||
local function TbStringify(val, needSort, cache)
|
||
cache = cache or {}
|
||
if cache[val] then
|
||
XLog.Error("loop Stringify")
|
||
return
|
||
end
|
||
cache[val] = true
|
||
local members = {}
|
||
if needSort then
|
||
local keys = {}
|
||
for k, _ in pairs(val) do
|
||
tableInsert(keys, k)
|
||
end
|
||
tableSort(keys)
|
||
for _, v in ipairs(keys) do
|
||
tableInsert(members, "[" .. XSaveTool.Stringify(v, needSort, cache) .. "]=" .. XSaveTool.Stringify(val[v], needSort, cache))
|
||
end
|
||
else
|
||
for k, v in pairs(val) do
|
||
tableInsert(members, "[" .. XSaveTool.Stringify(k, needSort, cache) .. "]=" .. XSaveTool.Stringify(v, needSort, cache))
|
||
end
|
||
end
|
||
return string.format("{%s}", tableConcat(members, ","))
|
||
end
|
||
|
||
local StringifyFuncMap = {
|
||
["nil"] = NilStringify,
|
||
["boolean"] = BoolStringify,
|
||
["number"] = NumStringify,
|
||
["function"] = FuncStringify,
|
||
["string"] = StrStringify,
|
||
["table"] = TbStringify,
|
||
}
|
||
--endregion------------------obj -> string finish------------------
|
||
|
||
--==============================--
|
||
--desc: 数据字符串化
|
||
--@val: 需要封装成字符串的数据
|
||
--@needSort: 是否需要排序
|
||
--@cache: 缓存处理,table引用死锁判断
|
||
--@return 封装好的字符串
|
||
--==============================--
|
||
function XSaveTool.StringifyOld(val, needSort, cache)
|
||
cache = cache or {}
|
||
|
||
return (({
|
||
["nil"] = fret "nil",
|
||
["boolean"] = fret(tostring(val)),
|
||
["number"] = fret(val),
|
||
["function"] = function()
|
||
return "function(...)" ..
|
||
"return load(" ..
|
||
XSaveTool.StringifyOld(stringDump(val), needSort, cache) ..
|
||
")(...)" ..
|
||
"end"
|
||
end,
|
||
["string"] = function()
|
||
local s = "\""
|
||
for c in stringGmatch(val, ".") do
|
||
s = s .. "\\" .. c:byte()
|
||
end
|
||
return s .. "\""
|
||
end,
|
||
["table"] = function()
|
||
if cache[val] then
|
||
XLog.Error("loop Stringify")
|
||
return
|
||
end
|
||
cache[val] = true
|
||
local members = {}
|
||
if needSort then
|
||
local keys = {}
|
||
for k, _ in pairs(val) do
|
||
tableInsert(keys, k)
|
||
end
|
||
tableSort(keys)
|
||
for _, v in ipairs(keys) do
|
||
tableInsert(members, "[" .. XSaveTool.StringifyOld(v, needSort, cache) .. "]=" .. XSaveTool.StringifyOld(val[v], needSort, cache))
|
||
end
|
||
else
|
||
for k, v in pairs(val) do
|
||
tableInsert(members, "[" .. XSaveTool.StringifyOld(k, needSort, cache) .. "]=" .. XSaveTool.StringifyOld(v, needSort, cache))
|
||
end
|
||
end
|
||
return "{" .. tableConcat(members, ",") .. "}"
|
||
end,
|
||
})[type(val)] or function()
|
||
XLog.Error("cannot Stringify type:" .. type(val), 2)
|
||
end)()
|
||
end
|
||
|
||
function XSaveTool.Stringify(val, needSort, cache)
|
||
local func = StringifyFuncMap[type(val)]
|
||
if not func then
|
||
XLog.Error("cannot Stringify type:" .. type(val), 2)
|
||
end
|
||
return func(val, needSort, cache)
|
||
end
|
||
|
||
--==============================--
|
||
--desc: 本地数据持久化
|
||
--@key: 存储key
|
||
--@value: 存储值
|
||
--==============================--
|
||
function XSaveTool.SaveData(key, value)
|
||
local k = XSaveTool.Stringify(key, true)
|
||
if value == false then
|
||
XSaveTool.LocalCache[k] = nil
|
||
else
|
||
XSaveTool.LocalCache[k] = value or XSaveTool.LocalCache[k]
|
||
end
|
||
CS.UnityEngine.PlayerPrefs.SetString(getLuaDataKey(k), XSaveTool.Stringify(XSaveTool.LocalCache[k]))
|
||
CS.UnityEngine.PlayerPrefs.Save()
|
||
end
|
||
|
||
--==============================--
|
||
--desc: 持久化数据删除
|
||
--@key: 数据key
|
||
--==============================--
|
||
function XSaveTool.RemoveData(key)
|
||
local k = XSaveTool.Stringify(key, true)
|
||
XSaveTool.LocalCache[k] = nil
|
||
CS.UnityEngine.PlayerPrefs.DeleteKey(getLuaDataKey(k))
|
||
end
|
||
|
||
--==============================--
|
||
--desc: 获取持久化数据
|
||
--@key: 存储key
|
||
--@return 存储值
|
||
--==============================--
|
||
function XSaveTool.GetData(key)
|
||
local k = XSaveTool.Stringify(key, true)
|
||
if XSaveTool.LocalCache[k] then
|
||
return XSaveTool.LocalCache[k]
|
||
end
|
||
|
||
local str = CS.UnityEngine.PlayerPrefs.GetString(getLuaDataKey(k))
|
||
if str and str ~= "" then
|
||
local obj = load("return " .. str)()
|
||
XSaveTool.LocalCache[k] = obj
|
||
return obj
|
||
end
|
||
|
||
return nil
|
||
end
|
||
|
||
--==============================--
|
||
--desc: 移除所有持久化数据(调试)
|
||
--==============================--
|
||
function XSaveTool.RemoveAll()
|
||
local enable1 = XDataCenter.GuideManager.CheckFuncDisable()
|
||
local enable2 = XDataCenter.CommunicationManager.CheckFuncDisable()
|
||
local enable3 = XDataCenter.FunctionEventManager.CheckFuncDisable()
|
||
local enable4 = XRpc.CheckLuaNetLogEnable()
|
||
|
||
XSaveTool.LocalCache = {}
|
||
CS.UnityEngine.PlayerPrefs.DeleteAll()
|
||
|
||
XDataCenter.GuideManager.ChangeFuncDisable(enable1)
|
||
XDataCenter.CommunicationManager.ChangeFuncDisable(enable2)
|
||
XDataCenter.FunctionEventManager.ChangeFuncDisable(enable3)
|
||
XRpc.SetLuaNetLogEnable(enable4)
|
||
end |