You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
4.4 KiB
179 lines
4.4 KiB
3 years ago
|
local progress = require 'progress'
|
||
|
|
||
|
local table_insert = table.insert
|
||
|
local table_sort = table.sort
|
||
|
local math_type = math.type
|
||
|
local table_concat = table.concat
|
||
|
local string_char = string.char
|
||
|
local type = type
|
||
|
local os_clock = os.clock
|
||
|
|
||
|
local w2l
|
||
|
local metadata
|
||
|
local remove_unuse_object
|
||
|
local ttype
|
||
|
local str
|
||
|
|
||
|
local function get_len(tbl)
|
||
|
local n = 0
|
||
|
for k in pairs(tbl) do
|
||
|
if type(k) == 'number' and k > n then
|
||
|
n = k
|
||
|
end
|
||
|
end
|
||
|
return n
|
||
|
end
|
||
|
|
||
|
local function format_value(tp, value)
|
||
|
if value == nil then
|
||
|
return 'nil'
|
||
|
end
|
||
|
if tp == 0 then
|
||
|
return ('%d'):format(value)
|
||
|
elseif tp == 1 or tp == 2 then
|
||
|
return ('%.4f'):format(value)
|
||
|
elseif tp == 3 then
|
||
|
value = w2l:editstring(value)
|
||
|
if value:match '[\n\r]' then
|
||
|
return ('[=[\r\n%s]=]'):format(value)
|
||
|
else
|
||
|
return ('%q'):format(value)
|
||
|
end
|
||
|
end
|
||
|
return 'nil'
|
||
|
end
|
||
|
|
||
|
local function write(format, ...)
|
||
|
str[#str+1] = format:format(...)
|
||
|
end
|
||
|
|
||
|
local function write_data(meta, data, lines)
|
||
|
local len
|
||
|
local key = meta.field
|
||
|
if type(data) == 'table' then
|
||
|
len = get_len(data)
|
||
|
if len == 0 then
|
||
|
return
|
||
|
end
|
||
|
end
|
||
|
if key:match '[^%w%_]' then
|
||
|
key = ('%q'):format(key)
|
||
|
end
|
||
|
if meta.displayname then
|
||
|
lines[#lines+1] = {'-- %s', w2l:editstring(meta.displayname):gsub('^%s*(.-)%s*$', '%1')}
|
||
|
end
|
||
|
if not len then
|
||
|
lines[#lines+1] = {'%s = %s', key, format_value(meta.type, data)}
|
||
|
return
|
||
|
end
|
||
|
if len <= 1 then
|
||
|
lines[#lines+1] = {'%s = %s', key, format_value(meta.type, data[1])}
|
||
|
return
|
||
|
end
|
||
|
|
||
|
local values = {}
|
||
|
local is_string
|
||
|
for i = 1, len do
|
||
|
if type(data[i]) == 'string' then
|
||
|
is_string = true
|
||
|
end
|
||
|
if len >= 10 then
|
||
|
values[i] = ('%d = %s'):format(i, format_value(meta.type, data[i]))
|
||
|
else
|
||
|
values[i] = format_value(meta.type, data[i])
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if is_string or len >= 10 then
|
||
|
lines[#lines+1] = {'%s = {\r\n%s,\r\n}', key, table_concat(values, ',\r\n')}
|
||
|
return
|
||
|
end
|
||
|
|
||
|
lines[#lines+1] = {'%s = {%s}', key, table_concat(values, ', ')}
|
||
|
end
|
||
|
|
||
|
local function write_obj(id, obj)
|
||
|
local metas = {}
|
||
|
local datas = {}
|
||
|
local haskey = {}
|
||
|
if metadata[obj._code] then
|
||
|
for key, meta in pairs(metadata[obj._code]) do
|
||
|
local data = obj[key]
|
||
|
if data then
|
||
|
metas[#metas+1] = meta
|
||
|
datas[meta] = data
|
||
|
end
|
||
|
haskey[key] = true
|
||
|
end
|
||
|
end
|
||
|
if metadata[ttype] then
|
||
|
for key, meta in pairs(metadata[ttype]) do
|
||
|
if not haskey[key] then
|
||
|
local data = obj[key]
|
||
|
if data then
|
||
|
metas[#metas+1] = meta
|
||
|
datas[meta] = data
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
table_sort(metas, function(meta1, meta2)
|
||
|
return meta1.field < meta2.field
|
||
|
end)
|
||
|
local lines = {}
|
||
|
for _, meta in ipairs(metas) do
|
||
|
write_data(meta, datas[meta], lines)
|
||
|
end
|
||
|
if #lines == 0 and id == obj._parent then
|
||
|
return
|
||
|
end
|
||
|
write('[%s]', id)
|
||
|
if obj._parent then
|
||
|
write('%s = %q', '_parent', obj._parent)
|
||
|
end
|
||
|
for i = 1, #lines do
|
||
|
write(table.unpack(lines[i]))
|
||
|
end
|
||
|
write ''
|
||
|
end
|
||
|
|
||
|
local function write_table(slk)
|
||
|
local list = {}
|
||
|
for id in pairs(slk) do
|
||
|
if not remove_unuse_object or obj._mark then
|
||
|
list[#list+1] = id
|
||
|
end
|
||
|
end
|
||
|
table_sort(list, function(a, b)
|
||
|
local is_origin_a = a == slk[a]._parent
|
||
|
local is_origin_b = b == slk[b]._parent
|
||
|
if is_origin_a and not is_origin_b then
|
||
|
return true
|
||
|
end
|
||
|
if not is_origin_a and is_origin_b then
|
||
|
return false
|
||
|
end
|
||
|
return a < b
|
||
|
end)
|
||
|
local clock = os_clock()
|
||
|
for i = 1, #list do
|
||
|
local obj = slk[list[i]]
|
||
|
write_obj(list[i], obj)
|
||
|
if os_clock() - clock >= 0.1 then
|
||
|
clock = os_clock()
|
||
|
message(('正在转换%s: [%s] (%d/%d)'):format(ttype, obj._id, i, #list))
|
||
|
progress(i / #list)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
return function (w2l_, type, slk)
|
||
|
w2l = w2l_
|
||
|
metadata = w2l:metadata()
|
||
|
remove_unuse_object = w2l.config.remove_unuse_object
|
||
|
ttype = type
|
||
|
str = {}
|
||
|
write_table(slk, type)
|
||
|
return table_concat(str, '\r\n')
|
||
|
end
|