about summary refs log tree commit diff stats
path: root/file.lua
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2022-05-17 21:18:17 -0700
committerKartik K. Agaram <vc@akkartik.com>2022-05-17 21:34:55 -0700
commitde495ae0f1574ee1f0fb803ff05c77aaf04f13fc (patch)
tree9fc98b05410ac66763d390703b5ff8b78eba6f68 /file.lua
parent91ce333ae0f617ef4eb6638faf66bbe159f25a0d (diff)
downloadlines.love-de495ae0f1574ee1f0fb803ff05c77aaf04f13fc.tar.gz
several more modules
This is probably not ideal; let's see how it goes..
Diffstat (limited to 'file.lua')
-rw-r--r--file.lua88
1 files changed, 88 insertions, 0 deletions
diff --git a/file.lua b/file.lua
new file mode 100644
index 0000000..c305869
--- /dev/null
+++ b/file.lua
@@ -0,0 +1,88 @@
+-- primitives for saving to file and loading from file
+Drawing = require 'drawing'
+
+function load_from_disk(filename)
+  local infile = io.open(filename)
+  local result = load_from_file(infile)
+  if infile then infile:close() end
+  return result
+end
+
+function load_from_file(infile)
+  local result = {}
+  if infile then
+    local infile_next_line = infile:lines()  -- works with both Lua files and LÖVE Files (https://www.love2d.org/wiki/File)
+    while true do
+      local line = infile_next_line()
+      if line == nil then break end
+      if line == '```lines' then  -- inflexible with whitespace since these files are always autogenerated
+        table.insert(result, load_drawing(infile_next_line))
+      else
+        table.insert(result, {mode='text', data=line})
+      end
+    end
+  end
+  if #result == 0 then
+    table.insert(result, {mode='text', data=''})
+  end
+  return result
+end
+
+function save_to_disk(lines, filename)
+  local outfile = io.open(filename, 'w')
+  for _,line in ipairs(lines) do
+    if line.mode == 'drawing' then
+      store_drawing(outfile, line)
+    else
+      outfile:write(line.data..'\n')
+    end
+  end
+  outfile:close()
+end
+
+json = require 'json'
+function load_drawing(infile_next_line)
+  local drawing = {mode='drawing', h=256/2, points={}, shapes={}, pending={}}
+  while true do
+    local line = infile_next_line()
+    assert(line)
+    if line == '```' then break end
+    local shape = json.decode(line)
+    if shape.mode == 'line' or shape.mode == 'manhattan' then
+      shape.p1 = Drawing.insert_point(drawing.points, shape.p1.x, shape.p1.y)
+      shape.p2 = Drawing.insert_point(drawing.points, shape.p2.x, shape.p2.y)
+    elseif shape.mode == 'polygon' then
+      for i,p in ipairs(shape.vertices) do
+        shape.vertices[i] = Drawing.insert_point(drawing.points, p.x,p.y)
+      end
+    elseif shape.mode == 'circle' or shape.mode == 'arc' then
+      shape.center = Drawing.insert_point(drawing.points, shape.center.x,shape.center.y)
+    end
+    table.insert(drawing.shapes, shape)
+  end
+  return drawing
+end
+
+function store_drawing(outfile, drawing)
+  outfile:write('```lines\n')
+  for _,shape in ipairs(drawing.shapes) do
+    if shape.mode == 'freehand' then
+      outfile:write(json.encode(shape)..'\n')
+    elseif shape.mode == 'line' or shape.mode == 'manhattan' then
+      local line = json.encode({mode=shape.mode, p1=drawing.points[shape.p1], p2=drawing.points[shape.p2]})
+      outfile:write(line..'\n')
+    elseif shape.mode == 'polygon' then
+      local obj = {mode=shape.mode, vertices={}}
+      for _,p in ipairs(shape.vertices) do
+        table.insert(obj.vertices, drawing.points[p])
+      end
+      local line = json.encode(obj)
+      outfile:write(line..'\n')
+    elseif shape.mode == 'circle' then
+      outfile:write(json.encode({mode=shape.mode, center=drawing.points[shape.center], radius=shape.radius})..'\n')
+    elseif shape.mode == 'arc' then
+      outfile:write(json.encode({mode=shape.mode, center=drawing.points[shape.center], radius=shape.radius, start_angle=shape.start_angle, end_angle=shape.end_angle})..'\n')
+    end
+  end
+  outfile:write('```\n')
+end