This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Lithia's profile picture

Loading Variables?

Started by Lithia, 12 December 2012 - 12:25 PM
Lithia #1
Posted 12 December 2012 - 01:25 PM
Hey Pro's ^0^
ive been searching High and Low on the API's and forums for a type of Special API
Something that loads variables from a Text file
for example

lets say the api has

load.vars() --  Loads all variables from a Specific file
save.vars() -- Saves all set Variables to a Specific file
save.var() -- Saves a specific variable to a Specific file

so if i wanted to do something like a custom password door lock id do

pass = "5464" -- Default password if password var isnt set
passo = "5464o" -- Override password
load.vars("doorlock") -- Overwrites default password
while true do
redstone.setOutput("right", false)
term.clear()
term.setCursorPos(1, 1)
print("please enter password")
input = read("*")
if input == password then
  redstone.setOutput("right", true)
  sleep(5)
elseif input == passo then
  term.clear()
  print("please enter new password")
  input2 = read()
  save.var("data", "pass", input)
else
  print("Invalid input: " input)
end
end

and the Variables file would look like

passo = 5464
pass = 5464
creator = Lithia
ect ect

:3
CoolisTheName007 #2
Posted 12 December 2012 - 01:51 PM
Just because your avatar (FoE?):

There's this: http://www.computerc...uses-metatable/
Which can be improved; also os.loadAPI(…) where … is the path to the API, but I hope you know that?

I just noticed that I don't have any good API for saving stuff… the one above does not save to a specific file; say you want to leave a file in a disk and then let the turtle go away…I'll probably have something decent in a instant. Stay tuned.
BrolofTheViking #3
Posted 12 December 2012 - 01:55 PM
There's nothing I know of that will do it according to the name of the variable. What you need to use is the fs api, and save all the variables in a table. Computercraft can only write strings to files, so you would need to convert the integer variable to a string when you write it, and convert it back to an int when you read it.
This code is untested, but you should be able to do something along the lines of


--to write all variables. The write functions rewrites the entire file, so editing only one variable is not an option
--However, to change only one variable, you could have it read the file, change one member of the table, then rewrite the file
variables = [5464,5464,"Lithia")
file = fs.open(filepath,"w")
file.write(textutils.serialize(variables)
file.close()

--to retrieve the variables
file = fs.open(filepath,"r")
variables = textutils.unserialize(file.readAll())
file.close()

the major problem with this system is that you will have to have the program know which variable corresponds to which item in the table.
I used this type of method to write blueprints for buildings to be built with the operator table addon. They were massive and inefficient, but worked.
CoolisTheName007 #4
Posted 12 December 2012 - 02:08 PM
Will have to wait for tomorrow
Lithia #5
Posted 12 December 2012 - 04:07 PM
Thanks :3
CoolisTheName007 #6
Posted 13 December 2012 - 12:12 AM
Ok, I improved the one I posted about:
-better error reporting
-locals and separate metatable to speed up things and spend less memory;
-support for using Immibis serialize API, get it here: http://www.computercraft.info/forums2/index.php?/topic/302-api-proper-serialization/
and put it in a new folder APIS;
-suppport for people who prefer to do loadfile(…)() instead of using os.loadAPI, e.g. now returns the API table;
and here's the result, same usage as before, but now can handle about anything you need:

-- ================================================
-- Persistent variables
-- ================================================
env=getfenv()
local textutils=pcall(os.loadAPI('APIS/serialize')) or textutils
textutils.unserialize=textutils.unserialize or textutils.deserialize
local assert,error,rawget,fs,io,setmetatable=assert,error,rawget,fs,io,setmetatable
setmetatable(env,nil)
prefix='saved:'
local function getVariableFilename(tbl,name) 
	    if name:sub(1,1)=="_" then
   error(prefix.."Variable names cannot start with _",2)
  end
	    if name:find("[:/*|<>;%s]") then
   error(prefix.."Variable name contains illegal variable, you cannot use ://*|<>;%s",2)
  end
	    local filePath=rawget(tbl,"_PVarPath")
	    local fileName = fs.combine(filePath,name..".var")
	    if not fs.exists(filePath) then
		    fs.makeDir(filePath)
	    end
	    return fileName
end
meta={	   __index=function(tbl,name)
					    local vFile=getVariableFilename(tbl,name)
					    local f = io.open(vFile, "r")
					    if f then
							    local content = textutils.unserialize(f:read())
							    f:close()
							    return content
					    else
							    return nil
					    end
			    end,
			    __newindex=function(tbl,name,value)
					    local vFile=getVariableFilename(tbl,name)
	  if value then  
						    local f = io.open(vFile, "w")	  
						    assert(f,prefix.."could not open file "..vFile)
						    f:write(textutils.serialize(value))
						    f:close()
					    else
						    fs.delete(vFile)
					    end
			    end
	    }
function new(pathName)
local v={_PVarPath=pathName or "/vars/"}
setmetatable(v,meta)
return v
end
return env