Advertisement
King0fGamesYami

autosaving tables

Oct 5th, 2014
593
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.93 KB | None | 0 0
  1. local function serializeImpl( t, tTracking, sIndent )
  2.     local sType = type(t)
  3.     if sType == "table" then
  4.         t = getmetatable( t ).origin
  5.         if tTracking[t] ~= nil then
  6.             error( "Cannot serialize table with recursive entries", 0 )
  7.         end
  8.         tTracking[t] = true
  9.  
  10.         if next(t) == nil then
  11.             -- Empty tables are simple
  12.             return "{}"
  13.         else
  14.             -- Other tables take more work
  15.             local sResult = "{\n"
  16.             local sSubIndent = sIndent .. "  "
  17.             local tSeen = {}
  18.             for k,v in ipairs(t) do
  19.                 tSeen[k] = true
  20.                 sResult = sResult .. sSubIndent .. serializeImpl( v, tTracking, sSubIndent ) .. ",\n"
  21.             end
  22.             for k,v in pairs(t) do
  23.                 if not tSeen[k] then
  24.                     local sEntry
  25.                     if type(k) == "string" and string.match( k, "^[%a_][%a%d_]*$" ) then
  26.                         sEntry = k .. " = " .. serializeImpl( v, tTracking, sSubIndent ) .. ",\n"
  27.                     else
  28.                         sEntry = "[ " .. serializeImpl( k, tTracking, sSubIndent ) .. " ] = " .. serializeImpl( v, tTracking, sSubIndent ) .. ",\n"
  29.                     end
  30.                     sResult = sResult .. sSubIndent .. sEntry
  31.                 end
  32.             end
  33.             sResult = sResult .. sIndent .. "}"
  34.             return sResult
  35.         end
  36.        
  37.     elseif sType == "string" then
  38.         return string.format( "%q", t )
  39.    
  40.     elseif sType == "number" or sType == "boolean" or sType == "nil" then
  41.         return tostring(t)
  42.        
  43.     else
  44.         error( "Cannot serialize type "..sType, 0 )
  45.        
  46.     end
  47. end
  48.  
  49. local function serialize( t )
  50.     local tTracking = {}
  51.     return serializeImpl( t, tTracking, "" )
  52. end
  53.  
  54. local function makeInternalSaving( tbl, save )
  55.     for k, v in pairs( tbl ) do
  56.         if type( v ) == "table" then
  57.             tbl[ k ] = makeInternalSaving( v )
  58.         end
  59.     end
  60.     return setmetatable( {}, {
  61.         __index = tbl,
  62.         __newindex = function( self, key, value )
  63.             if type( value ) == "table" then
  64.                 tbl[ key ] = makeInternalSaving( value, save )
  65.             else
  66.                 tbl[ key ] = value
  67.             end
  68.             save()
  69.         end,
  70.         __len = function() return #tbl end,
  71.         __metatable = { origin = tbl },
  72.         } )
  73. end
  74.  
  75. function makeAutoSaving( tbl, file )
  76.     for k, v in pairs( tbl ) do
  77.         if type( v ) == "table" then
  78.             tbl[ k ] = makeInternalSaving( v )
  79.         end
  80.     end
  81.     local savable = {}
  82.     local function save()
  83.         local f = fs.open( file, "w" )
  84.         f.write( serialize( savable ) )
  85.         f.close()
  86.     end
  87.     return setmetatable( savable, {
  88.         __index = tbl,
  89.         __newindex = function( self, key, value )
  90.             if type( value ) == "table" then
  91.                 tbl[ key ] = makeInternalSaving( value, save )
  92.             else
  93.                 tbl[ key ] = value
  94.             end
  95.             save()
  96.         end,
  97.         __len = function( ... ) return #tbl end,
  98.         __metatable = { origin = tbl },
  99.         __call = function() return tbl end,
  100.     } )
  101. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement