forked from Lafolie/Jupiter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjupiter.lua
85 lines (77 loc) · 3.2 KB
/
jupiter.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
--write a (non-serial) table to a file. The filename should be a property of "data": data._fileName = "*.extn"
local jupiter = {saveDir = "save"}
jupiter.save = function(data)
assert(type(data) == "table", "Tables must be provided to saveFile!")
if not love.filesystem.getInfo(jupiter.saveDir) == "directory" then assert(love.filesystem.createDirectory(jupiter.saveDir), "Unable to create save directory in " .. love.filesystem.getSaveDirectory() .. "!") end --make the save folder if required
local file = love.filesystem.newFile(jupiter.saveDir .. "/" .. data._fileName)
file:open("w")
local function serial(table, scope)
scope = scope or ""
for k, v in pairs(table) do
if k ~= "_fileName" then
if type(v) == "table" then
serial(v, scope .. tostring(k) .. ".")
else
local x = file:write(scope .. k .. "=" .. tostring(v) .. "\n") --write value
if not x then return nil end
end
end
end
end
serial(data)
return true
end
--load a file. If no specific file is given it returns the latest save file
jupiter.load = function(name)
if not love.filesystem.getInfo(jupiter.saveDir) == "directory" then assert(love.filesystem.createDirectory(jupiter.saveDir), "Unable to create save directory in " .. love.filesystem.getSaveDirectory() .. "!") end
--load the latest save file if no file is given (useful for 'continue' option)
if not name then
local saveFiles = love.filesystem.getDirectoryItems(jupiter.saveDir)
local orderedFiles = {}
for k, file in ipairs(saveFiles) do
--ignore files such as .DS_Store
if not (file:sub(1, 1) == ".") and file:match("%.save$") then
table.insert(orderedFiles, {f = file, t = love.filesystem.getInfo(jupiter.saveDir .. "/" .. file).modtime or 0})
end
end
if # orderedFiles ~= 0 then
--sort the files in modified order
table.sort(orderedFiles, function(a, b) return a.t > b.t end)
name = orderedFiles[1].f
end
end
--don't do anything if there are no saves
if name then
if love.filesystem.getInfo(jupiter.saveDir .. "/" .. name) and love.filesystem.getInfo(jupiter.saveDir .. "/" .. name).type == "file" then
local saveFile = {} --data from the file
local pointer
--find tables
local function deserial(value)
pointer = saveFile
local scope, dotCount = value:gsub("%.", "%1")
for x = 1, dotCount do
local element = scope:match("^(..-)%.") --get the leftmost index
scope = scope:match("^" .. element .. "%.(.+)") --trim the current index for the next iteration
element = tonumber(element) and tonumber(element) or element
pointer[element] = not pointer[element] and {} or pointer[element] --create the table if needed
pointer = pointer[element] --set the pointer to the current level
end
return scope
end
--load the data
for l in love.filesystem.lines(jupiter.saveDir .. "/" .. name) do
local k, v = l:match("^(..-)=(.+)$")
if k and v then
local index = deserial(k)
if v ~= "nil" and v ~= "false" then --ignore nil values that may have been set by the player
index = tonumber(index) and tonumber(index) or index
pointer[index] = tonumber(v) and tonumber(v) or v
end
end
end
saveFile._fileName = name
return saveFile
end
end
end
return jupiter