Skip to content

Commit e5d1a00

Browse files
author
Marcus E. W. Germano, IV
committed
Added state persistence methods
* Added `eturtle.saveState` and `eturtle.loadState` to manage position, bearing, and equipment state persistence * Removed setting for state file and added path parameter instead.
1 parent 2699dda commit e5d1a00

File tree

1 file changed

+117
-6
lines changed

1 file changed

+117
-6
lines changed

eturtle.lua

Lines changed: 117 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
local expect = require("cc.expect")
2+
local pretty = require("cc.pretty")
23

3-
local function roundToNearestInterval(value, interval)
4+
local function roundNearestInterval(value, interval)
45
local valueDown, valueUp = math.floor(value / interval) * interval, math.ceil(value / interval) * interval
56
local differenceDown, differenceUp = value - valueDown, valueUp - value
67
if differenceDown < differenceUp then
@@ -41,9 +42,6 @@ local eturtle = {} do
4142
eturtle.NORTH = 1.0 * math.pi
4243
eturtle.EAST = 1.5 * math.pi
4344

44-
--[[ Settings ]]--
45-
settings.define("eturtle.statefile", {description = "The path in which to store the turtle's state.", default = ".turtle", type = "string"})
46-
4745
--[[ Calibration and Configuration Methods ]]--
4846
local function equipWirelessModem()
4947
debugPrint("searching for wireless modem...")
@@ -190,7 +188,7 @@ local eturtle = {} do
190188
if manualBearing == nil then manualBearing = eturtle.SOUTH end
191189
expect(1, manualBearing, "number")
192190
expect.range(manualBearing, 0.0 * math.pi, 2.0 * math.pi)
193-
manualBearing = roundToNearestInterval(manualBearing, 0.5 * math.pi)
191+
manualBearing = roundNearestInterval(manualBearing, 0.5 * math.pi)
194192
end
195193

196194
local currentSlot = turtle.getSelectedSlot()
@@ -292,7 +290,12 @@ local eturtle = {} do
292290
if manualEquipment == nil then manualEquipment = {} end
293291

294292
debugPrint("calibrating turtle...")
295-
return eturtle.calibratePosition(manualPosition.x, manualPosition.y, manualPosition.z), eturtle.calibrateBearing(manualBearing), eturtle.calibrateEquipment(equipment.left, equipment.right)
293+
294+
local positionCalibrationSuccess = eturtle.calibratePosition(manualPosition.x, manualPosition.y, manualPosition.z)
295+
local bearingCalibrationSuccess = eturtle.calibrateBearing(manualBearing)
296+
local equipmentCalibrationSuccess = eturtle.calibrateEquipment()
297+
298+
return positionCalibrationSuccess and bearingCalibrationSuccess and equipmentCalibrationSuccess, positionCalibrationSuccess, bearingCalibrationSuccess, equipmentCalibrationSuccess
296299
end
297300

298301
function eturtle.enableDebugging(printHook, errorHook)
@@ -344,4 +347,112 @@ local eturtle = {} do
344347
end
345348
return turtle.getFuelLimit()
346349
end
350+
351+
--[[ Persistence Methods ]]--
352+
function eturtle.saveState(path)
353+
do
354+
expect(1, path, "string")
355+
end
356+
357+
debugPrint("saving turtle state...")
358+
359+
if position == nil then
360+
debugError("position has not been calibrated")
361+
return false
362+
end
363+
364+
if bearing == nil then
365+
debugError("bearing has not been calibrated")
366+
return false
367+
end
368+
369+
if equipment == nil then
370+
debugError("equipment has not been calibrated")
371+
return false
372+
end
373+
374+
debugPrint("opening state file for writing...")
375+
local file, fileError = fs.open(path, "wb")
376+
if file then
377+
local signatureBytes = "ETS"
378+
file.write(signatureBytes)
379+
debugPrint("wrote file signature (%s)", signatureBytes)
380+
381+
local positionBytes = string.pack("lll", position.x, position.y, position.z)
382+
file.write(positionBytes)
383+
debugPrint("wrote position bytes (<%d,%d,%d> -> %s)", position.x, position.y, position.z, pretty.pretty(positionBytes))
384+
385+
local bearingBytes = string.pack("d", bearing)
386+
file.write(bearingBytes)
387+
debugPrint("wrote bearing bytes (%f -> %s)", bearing, pretty.pretty(bearingBytes))
388+
389+
local equipmentBytes = string.pack("s1s1", equipment.left or "", equipment.right or "")
390+
file.write(equipmentBytes)
391+
debugPrint("wrote equipment bytes (%s,%s -> %s)", equipment.left or "<nothing>", equipment.right or "<nothing>", pretty.pretty(equipmentBytes))
392+
393+
file.flush()
394+
file.close()
395+
debugPrint("wrote to disk")
396+
return true
397+
end
398+
399+
debugError("could not open state file for writing (%s)", fileError)
400+
return false
401+
end
402+
403+
function eturtle.loadState(path)
404+
do
405+
expect(1, path, "string")
406+
end
407+
408+
debugPrint("loading turtle state...")
409+
410+
debugPrint("opening state file for reading...")
411+
local file, fileError = fs.open(path, "rb")
412+
if file then
413+
local signatureBytes = file.read(3)
414+
if signatureBytes == "ETS" then
415+
debugPrint("file signature matched")
416+
417+
local positionBytes = file.read(string.packsize("lll"))
418+
position = vector.new(string.unpack("lll", positionBytes))
419+
debugPrint("read position bytes (%s -> <%d,%d,%d>)", pretty.pretty(positionBytes), position.x, position.y, position.z)
420+
421+
local bearingBytes = file.read(string.packsize("d"))
422+
bearing = string.unpack("d", bearingBytes)
423+
debugPrint("read bearing bytes (%s -> %f)", pretty.pretty(bearingBytes), bearing)
424+
425+
local equipmentBytes = "" do
426+
equipment = {}
427+
428+
local leftEquipmentBytesCount = file.read()
429+
if leftEquipmentBytesCount > 0 then
430+
local leftEquipment = file.read(leftEquipmentBytesCount)
431+
equipment.left = leftEquipment
432+
equipmentBytes = equipmentBytes .. string.pack("s1", leftEquipment)
433+
else
434+
equipmentBytes = equipmentBytes .. "\000"
435+
end
436+
437+
local rightEquipmentBytesCount = file.read()
438+
if rightEquipmentBytesCount > 0 then
439+
local rightEquipment = file.read(rightEquipmentBytesCount)
440+
equipment.right = rightEquipment
441+
equipmentBytes = equipmentBytes .. string.pack("s1", rightEquipment)
442+
else
443+
equipmentBytes = equipmentBytes .. "\000"
444+
end
445+
end
446+
debugPrint("read equipment bytes (%s -> %s,%s)", pretty.pretty(equipmentBytes), equipment.left or "<nothing>", equipment.right or "nothing")
447+
448+
return true
449+
end
450+
451+
debugError("state file did not match signature (%s ~= ETS)", pretty.pretty(signatureBytes), )
452+
return false
453+
end
454+
455+
debugError("could not open state file for reading (%s)", fileError)
456+
return false
457+
end
347458
end return eturtle

0 commit comments

Comments
 (0)