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

Reading table from config

Started by ItsRodrick, 13 February 2015 - 07:40 PM
ItsRodrick #1
Posted 13 February 2015 - 08:40 PM
Hello. I'm making an Design API, and it will load themes, and makes titles or text based on the theme.

The API is: (Name: DesignAPI)
local x, y = term.getSize()

function loadTheme(path)
if type(path) ~= "string" then error("arg1 must be a string!") end
local file = fs.open(path,"r")
local data = file.readAll()
file:close()
return textutils.unserialize(data)
end

function addTitle(theme, title, align)
if theme.title.bgColor ~= nil then term.setBackgroundColor(theme.title.bgColor) end
if theme.title.txColor ~= nil then term.setTextColor(theme.title.txColor) end
if align == "center" then local textX = (#title-x)/2 end
if align == "left" or align == nil then local textX = 2 end
if align == "right" then local textX = x-#title end
if theme.title.height == 1 or theme.title.height == 2 then textY = 1 end
if theme.title.height == 3 then textY = 2 end
term.setCursorPos(textX, textY)
term.write(title)
end 

The program is


os.loadAPI("design")
theme = design.loadTheme("themes//default")
design.addTitle(theme,"Test Title")

The theme 'default' (located at themes/default) is:


{
  title = {
	bgColor = colors.lightBlue,
	txColor = colors.blue,
	height = 3,
	testText = "Hi"
  }
}

So, the problem is, that when I try to do design.addTitle it says "Attempt to index" at line 12, when trying to get info of the table.
Am I not saving the table correctly? Oh, and I'm manually doing the config.
Edited on 13 February 2015 - 07:50 PM
Quintuple Agent #2
Posted 13 February 2015 - 08:52 PM
I believe you should be doing
design.addTitle(theme,"Test Title")
instead of

design.addTitle(design,"Test Title")

nvm you fixed the post
Edited on 13 February 2015 - 07:53 PM
ItsRodrick #3
Posted 13 February 2015 - 08:56 PM
Yeah lol xD
I'm still trying a few things, then I saw that the var was wrong, and fixed in the program

But it still doesn't work. :(/>
Quintuple Agent #4
Posted 13 February 2015 - 09:01 PM
Ok, i believe you know the problem,
If you were to serialize any of the colors. it you change to its true value, because the colors. are just points to numbers. Try using the numbers that correspond to the colors within your theme file

lightBlue is 8
blue is 2048
Edited on 13 February 2015 - 08:02 PM
ItsRodrick #5
Posted 13 February 2015 - 09:06 PM
Yeah, it's working :)/>
Now I just need to do a converter from colors.<something> to the number, because if you are making a GUI, you won't look in the wiki for the numbers :P/>

Thanks!

But, seriously, is there any (easy and compact?) way to convert like colors.white to 1?
Edited on 13 February 2015 - 08:07 PM
Quintuple Agent #6
Posted 13 February 2015 - 09:12 PM
Well, could use the wiki or when you
  • writing it to file within a program
  • serializing it in a table
  • print/write to screen
All of those should return the variable as a number.

If you use the lua program you could also easly find out

ex: (when opening the terminal)
CraftOS
> lua
lua> colors.red
16384
lua>
Edited on 13 February 2015 - 08:14 PM
ItsRodrick #7
Posted 13 February 2015 - 09:12 PM
So, I load the file, unserialize it, serialize again, and unserialize again? Trying…
EDIT: Same thing as before

EDIT&sup2;: Saw you edited your post: Yeah, but I want to be able to do colors.white, and the api automatically converts it.
Edited on 13 February 2015 - 08:16 PM
Quintuple Agent #8
Posted 13 February 2015 - 09:18 PM
No, i mean if I have a program and i do something like this

testTable={"test",colors.white,"colors.red",colors.black}
file=fs.open("testFile","w")
file.write(textutils.serialize(testTable))
file.close()

If I were to open the file or unserialize it, the contents would be something like

{
"test",
1,
"colors.red",
32768,
}
Edited on 13 February 2015 - 08:19 PM
ItsRodrick #9
Posted 13 February 2015 - 09:27 PM
Yeah, I know, but the theme config would be written manually. Isn't there anyway during the loading process to convert colors.something to the number?
Quintuple Agent #10
Posted 13 February 2015 - 09:32 PM
Well, you could have a theme table like so

{
  title = {
		bgColor = "lightBlue",
		txColor = "blue",
		height = 3,
		testText = "Hi"
  }
}
then have in your code

cTable={
["white"]=colors.white,
["orange"]=colors.orange,
["magenta"]=colors.magenta,
["lightBlue"]=colors.lightBlue,
["yellow"]=colors.yellow,
["lime"]=colors.lime,
["pink"]=colors.pink,
["gray"]=colors.gray,
["lightGray"]=colors.lightGray,
["cyan"]=colors.cyan,
["purple"]=colors.purple,
["blue"]=colors.blue,
["brown"]=colors.brown,
["green"]=colors.green,
["red"]=colors.red,
["black"]=colors.black
}

then you would just need to do something like

setBackgroundColor(cTable[theme.title.bgColor])

Edit: Forgot comma's in table, fixed now.
Edited on 13 February 2015 - 08:34 PM
Lignum #11
Posted 13 February 2015 - 09:35 PM
then have in your code

cTable={
["white"]=colors.white
["orange"]=colors.orange
["magenta"]=colors.magenta
["lightBlue"]=colors.lightBlue
["yellow"]=colors.yellow
["lime"]=colors.lime
["pink"]=colors.pink
["gray"]=colors.gray
["lightGray"]=colors.lightGray
["cyan"]=colors.cyan
["purple"]=colors.purple
["blue"]=colors.blue
["brown"]=colors.brown
["green"]=colors.green
["red"]=colors.red
["black"]=colors.black
}

You don't need any of that, you've pretty much just redefined the colours table.
You can just do this:

colours["white"]

So…

setBackgroundColor(colors[theme.title.bgColor])
Quintuple Agent #12
Posted 13 February 2015 - 09:38 PM
oh, I am an idiot, I always forget that it can be accessed like a table. :P/>
Edited on 13 February 2015 - 08:40 PM
ItsRodrick #13
Posted 13 February 2015 - 09:41 PM
So, it would be
function loadTheme(path)
 if type(path) ~= "string" then error("arg1 must be a string!") end
 local file = fs.open(path,"r")
 local data = file.readAll()
 file:close()
 data={
  colors["white"],
  colors["orange"],
  colors["magenta"],
  colors["lightBlue"],
  colors["yellow"],
  colors["lime"],
  colors["pink"],
  colors["gray"],
  colors["lightGray"],
  colors["cyan"],
  colors["purple"],
  colors["blue"],
  colors["brown"],
  colors["green"],
  colors["red"],
  colors["black"]
 }
 return textutils.unserialize(data)
end

? I didn't understand this actually…
Quintuple Agent #14
Posted 13 February 2015 - 09:45 PM
No, it would be more like this

unction loadTheme(path)
if type(path) ~= "string" then error("arg1 must be a string!") end
local file = fs.open(path,"r")
local data = file.readAll()
file:close()
data=textutils.unserialize(data)
data.title.bgColor=colors[data.title.bgColor]
data.title.txColor=colors[data.title.txColor]
return data
end

This will also change the bg and txColor to the numbers so you don't have to do

setBackgroundColor(colors[theme.title.bgColor])
you can just do

setBackgroundColor(theme.title.bgColor)
Edited on 13 February 2015 - 08:46 PM
ItsRodrick #15
Posted 13 February 2015 - 09:51 PM
function loadTheme(path)
 if type(path) ~= "string" then error("arg1 must be a string!") end
 local file = fs.open(path,"r")
 local data = file.readAll()
 file:close()
 data=textutils.unserialize(data)
 data.title.bgColor=colors[data.title.bgColor]
 data.title.txColor=colors[data.title.txColor]
 return data
end

Attempt to index at line 7. :|
Quintuple Agent #16
Posted 13 February 2015 - 09:57 PM
What does your default theme file look like
ItsRodrick #17
Posted 13 February 2015 - 09:59 PM
{
  title = {
    bgColor = 128,
    txColor = 1,
    height = 3,
  },
}

While testing the converting thing, I just changed to "bgColor = colors.gray," and "txColor = colors.white,"
Quintuple Agent #18
Posted 13 February 2015 - 10:01 PM
no, when using the code now, it needs to be
bgColor="gray" not colors.gray
also remember the "gray" and others will need to be in quotes
ItsRodrick #19
Posted 13 February 2015 - 10:08 PM
Oh, ok, thanks! Working! =)

So seems by now everything is working as perfect! Thanks guys!
Dragon53535 #20
Posted 14 February 2015 - 12:15 AM
No, it would be more like this

unction loadTheme(path)
if type(path) ~= "string" then error("arg1 must be a string!") end
local file = fs.open(path,"r")
local data = file.readAll()
file:close()
data=textutils.unserialize(data)
data.title.bgColor=colors[data.title.bgColor]
data.title.txColor=colors[data.title.txColor]
return data
end

To add onto this as it will mess up otherwise if you send it numbers.
I'll add some error checking, or just keeping the numbers.

function loadTheme(path)
  if type(path) ~= "string" then error("arg1 must be a string!") end
  local file = fs.open(path,"r")
  local data = file.readAll()
  file:close()
  data=textutils.unserialize(data)
  data.title.bgColor=(colors[data.title.bgColor) and colors[data.title.bgColor] or (tonumber(data.title.bgColor)) and tonumber(data.title.bgColor) or
  error("Invalid background color",2)
  --#I'm using a trick that makes the line above act like an if statement while I set a variable
  --#First that's happening is i'm making sure that it exists in the colors table such as colors["gray"],
  --#second is i'm seeing if it's a number, which means that someone put 2048 for blue, We're also making sure it's as 2048 and not "2048"
  --#and then finally, if it's not in the table, or a number, then we need to tell them ourselves by erroring.
  data.title.txColor=(colors[data.title.txColor]) and colors[data.title.txColor] or (tonumber(data.title.txColor)) and tonumber(data.title.txColor) or
  error("Invalid text color",2)
  return data
end


Those errors being on other lines are fine btw. In case you thought otherwise


I also somehow quoted myself, whoops
Edited on 13 February 2015 - 11:16 PM