about summary refs log blame commit diff stats
path: root/file.lua
blob: c305869ea2c7e8fd850d80809c898e82299983be (plain) (tree)























































































                                                                                                                                                                             
-- 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