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

Local table problem

Started by tinynja98, 01 February 2015 - 03:45 AM
tinynja98 #1
Posted 01 February 2015 - 04:45 AM
Hello,

I'm working on a chat program and i've encountered a problem where if i call the function editBoxText(task,boxTable,char) with the boxTable being s[cScreen][cBox], the function will change the values of the local table "boxTable" AND the table s[cScreen][cBox]. Is this normal? What i thought would happen is the function changing the values of the local table and not touching the table s[cScreen][cBox]. Thats why i put a "return boxTable" at the end of the function.

Basically, when i enter a letter via my keyboard, it starts the function charInput(), which runs the function editBoxText(), which edits the values of the table (position, text, horizontal position…) and then the charInput() function asks the printBox() function to print the box table that was returned by the function editBoxText.

Here's my code:

c[something] means "current[something]"
s means "screen"

Spoiler
function printBox(boxTable)
 if boxTable.shown == false then
  clearSection(boxTable.xPos,boxTable.yPos,boxTable.xPos+boxTable.xLength-1,boxTable.yPos+boxTable.yLength-1,s[cScreen].sProperties.BGColor)
 else
  if boxTable.name == cBox then
   term.setTextColor(boxTable.textHLColor) --pas besoin background color (clearSection le fait déjà)
   clearSection(boxTable.xPos,boxTable.yPos,boxTable.xPos+boxTable.xLength-1,boxTable.yPos+boxTable.yLength-1,boxTable.BGHLColor)
  else
   term.setTextColor(boxTable.textColor) --pas besoin background color (clearSection le fait déjà)
   clearSection(boxTable.xPos,boxTable.yPos,boxTable.xPos+boxTable.xLength-1,boxTable.yPos+boxTable.yLength-1,boxTable.BGColor)
  end
  local tempX,tempY = 0,0
  if boxTable.textPos then
   if string.sub(boxTable.textPos,1,1) == "U" then
	tempY = boxTable.yPos
   elseif string.sub(boxTable.textPos,1,1) == "M" then
	tempY = boxTable.yPos+(boxTable.yLength-1)/2
   elseif string.sub(boxTable.textPos,1,1) == "B" then
	tempY = boxTable.yPos+boxTable.yLength-1
   end
   if string.sub(boxTable.textPos,2,2) == "L" then
	tempX = boxTable.xPos
   elseif string.sub(boxTable.textPos,2,2) == "M" then
	tempX = boxTable.xPos+(boxTable.xLength-1)/2-#boxTable.value/2
   elseif string.sub(boxTable.textPos,2,2) == "R" then
	tempX = boxTable.xPos+boxTable.xLength-#boxTable.value
   end
  else
   tempX,tempY = boxTable.xPos,boxTable.yPos
  end
  term.setCursorPos(tempX,tempY)
  if boxTable.mode == "push" then
   term.write(formatBoxText(boxTable))
  else
   term.write(boxTable.value)
  end
 end
end

function formatBoxText(boxTable)
 local tempValue = ""
 if boxTable.mode == "push" then
  tempValue = string.sub(boxTable.value,boxTable.startPos,boxTable.xLength-1)
  return tempValue
 elseif boxTable.mode == "mlines" then
 end
end

function editBoxText(task,boxTable,char) --Done
 if task == "add" then
  boxTable.value = string.sub(boxTable.value,1,boxTable.cPos)..char..string.sub(boxTable.value,boxTable.cPos+1)
  term.setTextColor(colors.pink)
  print(textutils.serialize(s[cScreen][cBox])) --cPos = 0, cXPos = 1
  os.pullEvent()
  boxTable.cPos = boxTable.cPos + 1
  if boxTable.cXPos == boxTable.xLength-1 then
   boxTable.startPos = boxTable.startPos + 1
  else
   term.setTextColor(colors.brown)
   print(textutils.serialize(s[cScreen][cBox])) --cPos = 1, cXPos = 1
   os.pullEvent()
   boxTable.cXPos = boxTable.cXPos + 1
   term.setTextColor(colors.black)
   print(textutils.serialize(s[cScreen][cBox])) --cPos = 1, cXPos = 2
   os.pullEvent()
  end
 elseif task == "backDel" then
  if boxTable.cPos > 1 then
   boxTable.value = string.sub(boxTable.value,1,boxTable.cPos-2)..string.sub(boxTable.value,boxTable.cPos)
   boxTable.cPos = boxTable.cPos - 1
   if boxTable.cXPos == 1 then
	boxTable.startPos = boxTable.startPos - 1
   else
	boxTable.cXPos = boxTable.cXPos - 1
   end
  end
 elseif task == "del" then
  if boxTable.cPos ~= #boxTable.value then
   boxTable.value = string.sub(boxTable.value,1,boxTable.cPos-1)..string.sub(boxTable.value,boxTable.cPos+1)
  end
 end
 return boxTable
end

function charInput(char)
 if s[cScreen][cBox].mode == "push" or s[cScreen][cBox].mode == "mlines" then
  editBoxText("add",s[cScreen][cBox],char)
  printBox(s[cScreen][cBox])
 end
end

do --startup
 --Possible properties: name,value,shown,cPos,startPos,cXPos,cYPos,mode,xPos,yPos,xLength,yLength,textPos,textColor,BGColor,textHLColor,BGHLColor,colors,values,link
 --modes:push/mlines/static/dynamic/link | textPos:UL/UM/UR/ML/MM/MR/BL/BM/BR | colors:table,dynamic only | link:W..screenName/OW..screenName(windows/onWindow)
 xSize,ySize = term.getSize()
 s = { --Besoin de table s pour faire s[cScreen] ([cScreen][cBox] marche pas)
  login = { "username", "password", "login", "showPass", "createAccount",
   sProperties = {textColor = colors.black, BGColor = colors.cyan},
   checkCredentials = {name = "checkCredentials", value = "Wrong username/password", shown = false, mode = "static", xPos = xSize/2-10.5, yPos = ySize/2+1, xLength = 23, yLength = 1, textColor = colors.red, BGColor = colors.cyan},
   username = {name = "username", value = "", cPos = 0, startPos = 0, cXPos = 1, mode = "push", xPos = xSize/2+1, yPos = ySize/2+4, xLength = 11, yLength = 1, textColor = colors.black, BGColor = colors.white, textHLColor = colors.black, BGHLColor = colors.yellow},
   password = {name = "password", value = "", cPos = 0, startPos = 0, cXPos = 1, mode = "push", xPos = xSize/2+1, yPos = ySize/2+6, xLength = 11, yLength = 1, textColor = colors.black, BGColor = colors.white, textHLColor = colors.black, BGHLColor = colors.yellow},
   login = {name = "login", value = "Login", mode = "static",xPos = xSize/2+15, yPos = ySize/2+4, xLength = 7, yLength = 3, textPos = "MM", textColor = colors.white, BGColor = colors.gray, textHLColor = colors.white, BGHLColor = colors.orange},
   showPass = {name = "showPass", value = "Hidden", mode = "dynamic", xPos = xSize/2-18.5, yPos = ySize/2+6, xLength = 6, yLength = 1, textPos = "MR", textColor = colors.red, BGColor = colors.cyan, textHLColor = colors.red, BGHLColor = colors.cyan, colors = {colors.red,colors.lime}, values = {"Hidden","Shown"}},
   createAccount = {name = "createAccount", value = "Create new account", mode = "link" ,xPos = xSize/2-7, yPos = ySize/2+8, xLength = 18, yLength = 1, textColor = colors.blue, BGColor = colors.cyan, textHLColor = colors.yellow, BGHLColor = colors.cyan, link = "WcreateAccount"}
  },
  createAccount = {
  }
 }
 cBox = false
 cScreen = false
 showScreen("login")
 --os.startTimer(0)
end

while true do
 local param1,param2,param3,param4,param5 = os.pullEvent()
 if param1 == "key" then
  keyPress(param2)
 end
 if param1 == "char" then
  charInput(param2)
 end
end

Thanks for your help!
Edited on 01 February 2015 - 03:56 AM
Bomb Bloke #2
Posted 01 February 2015 - 05:04 AM
The idea is that when you do this:

a = {}

… "a" isn't being set to "a table", but rather it's being set to a pointer to where ever the table is in memory.

Thus if you do:

a = {}
b = a
b[1] = "moo"
print(a[1])

… it'll say "moo", because "a" and "b" both lead to the same table.

Same goes for function and co-routine assignments.
tinynja98 #3
Posted 01 February 2015 - 05:12 AM
Alright thanks for the quick reply! I'll try to find a workaround by myself :)/>

Have a good one
Bomb Bloke #4
Posted 01 February 2015 - 08:54 AM
If you specifically "need" to clone a table, a "simple" way to do so is to serialise then unserialise it. Eg:

myNewTable = textutils.unserialize(textutils.serialize(myOldTable))

The other option is to iterate through the old table and copy everything in it to the new one, though things start getting slightly complex if there're tables in tables, etc.
tinynja98 #5
Posted 02 February 2015 - 12:17 AM
Thank you for the idea of serializing and unserializing the table. I haven't thought about that. But fyi, i just made the function edit the original table directly and it works perfect now.

Thanks again!