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
 |