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

Help: api_button:10: index expected, got number

Started by Cavious, 24 June 2014 - 11:44 PM
Cavious #1
Posted 25 June 2014 - 01:44 AM
What is happening
I keep getting this error, and I have no clue what I am doing wrong. I've looked at it for several days and even rewrote the entire function(chat function in run.lua). I've commented out the line that accesses api_button, when it calls .createButton(), everything else runs smooth. Worse, is I do this in my mainMenu() function and it works. I've included my pastebin, encase the issue is more then the functions I've added. I apologize upfront for any improper formating, or crappy functionality, I was in the process of rewriting the entire run.lua file, when I ran into this issue.

Error

api_button:10: index expected, got number

api_button.lua

--[[
FILENAME: api_button.lua(API)
AUTHOR: Donald R. Valverde (Cavious)
VERSION: 1.0-ALPHA
--]]
local button = {}
function createButton(list, id, text, fontColor, backgroundColor, xPos, yPos, funct)
button[id] = {}
button[id]["text"] = text
button[id]["fontColor"] = fontColor
button[id]["backgroundColor"] = backgroundColor
button[id]["xPos"] = xPos
button[id]["yPos"] = yPos
button[id]["funct"] = funct

table.insert(list, button[id])
end
function removeButton(list, id)
table.remove(list, id)
end
function drawButtons(output, list)
for i = 1, #list do
  output.setCursorPos(list[i].xPos, list[i].yPos)
  output.setTextColor(list[i].fontColor)
  output.setBackgroundColor(list[i].backgroundColor)
  output.write(list[i].text)
end
end
function drawButton(output, list, i)
output.setCursorPos(list[i].xPos, list[i].yPos)
output.setTextColor(list[i].fontColor)
output.setBackgroundColor(list[i].backgroundColor)
output.write(list[i].text)
end
function runButtonEvent(output, buttonList, activeButtonColor, inactiveButtonColor, event_type)
state = true

while(state) do
  event, button, xPos, yPos = os.pullEvent(event_type)

  for i = 1, #buttonList do
   if(yPos == buttonList[i].yPos and xPos >= buttonList[i].xPos and xPos < (buttonList[i].text:len() + buttonList[i].xPos)) then
	buttonList[i].backgroundColor = activeButtonColor
	api_button.drawButton(output, buttonList, i)
	os.sleep(0.5)
	buttonList[i].backgroundColor = inactiveButtonColor
	api_button.drawButton(output, buttonList, i)
	os.sleep(0.5)
	buttonList[i].funct()
	state = false
   end
  end
end
end

run.lua(Chat Function)

function chat()
local buttonList = {}

local image = paintutils.loadImage("gb_os/img/image_chat")
paintutils.drawImage(image, 1, 1)

local image = paintutils.loadImage("gb_os/img/image_chat_end")
paintutils.drawImage(image, 25, 1)

api_button.createButton(buttonList, "btn_back", "Back", colors.white, colors.orange, 2, 18, mainMenu)

api_button.drawButtons(term, buttonList)

state = true

while(state) do

  local event = {os.pullEvent()}
  if(event[1] == "mouse_click") then
   local xPos = event[3]
   local yPos = event[4]
   for i = 1, #buttonList do
	if(yPos == buttonList[i].yPos and xPos >= buttonList[i].xPos and xPos < (buttonList[i].text:len() + buttonList[i].xPos)) then
	 buttonList[i].backgroundColor = colors.lime
	 api_button.drawButton(term, buttonList, i)
	 os.sleep(0.5)
	 buttonList[i].backgroundColor = colors.green
	 api_button.drawButton(term, buttonList, i)
	 os.sleep(0.5)
	 buttonList[i].funct()
	 if(buttonList[i].id == "btn_back") then
	  state = false
	  position_y = 2
	 end
	end
   end
  end
  if(event[1] == "key") then
   if(event[2] == 28) then
	local input = chatBoxClick()
	sendToScreen(input)
	--sendToServer(input)
   end
  end
end
end

Pastebin Links:
run.lua
api_button.lua

Thank you in advance,

Donald R. Vaverde (Cavious)
Bomb Bloke #2
Posted 25 June 2014 - 03:14 AM
Line 45 of api_button overwrites the table pointer in "button" with the results of your pulled event.

It's erroring out because you're then trying to index into a number. Beats me why it doesn't say "table expected", but that's what it means, anyway.
flaghacker #3
Posted 25 June 2014 - 06:15 AM
Are you sure? To me it looks like you haven't loaded the API, and loading it won't work either, see http://www.computercraft.info/forums2/index.php?/topic/19383-loading-api-help/page__view__getnewpost.
Bomb Bloke #4
Posted 25 June 2014 - 07:05 AM
There's an inference to be made about that.
Cavious #5
Posted 26 June 2014 - 02:27 AM
Thanks guys, I'll look into the table issue.

flaghacker, if you look at the Pastbin file, it includes the os.loadAPI() function. I just shortened the version on the forums.
Cavious #6
Posted 26 June 2014 - 02:37 AM
Bomb Bloke, the interesting thing is that function within api_button works. I used it in my mainMenu() of the run.lua. However, the exact same inference of the copy within chat() doesn't work. Which is weird because before I added the runButtonEvent(), it worked perfectly fine. However you're right it doesn't reference that pointer. What is the best method to fix this? I've messed around with a few ideas but they all come to the same conclusion, an error.

Would I be better off rewriting the function completely?

Also I noticed only the line in chat() within run.lua does this. The api_button.creatButton(). Otherwise surprisingly enough it works. I literally copied and pasted the exact same lines from the MainMenu() and all those buttons worked and registered. It's the strangest thing.

Again thanks for all the help.
Bomb Bloke #7
Posted 26 June 2014 - 03:58 AM
All you need to do is stop messing with the original "button" pointer when you hunt for events.

The really simple way to do this is by declaring the variables you use to capture event data as local to the while block they're in (which you should've been doing anyway):

local event, button, xPos, yPos = os.pullEvent(event_type)

… but really, doubling up on variable names is bad practise, as it makes your code confusing to read. I'd've used either "mouseButton" or "_" on that line, as opposed to "button".

Edit:

Actually, your localisation of variables throughout is just plain bad - I guess you're not understanding scope as of yet. Perhaps have a read of this document.
Edited on 26 June 2014 - 02:01 AM
flaghacker #8
Posted 26 June 2014 - 06:43 AM
In the main program there's this line:

os.loadAPI("gb_os/api/api_button")
But the OP says that the API file it's called "api_button.lua".
See the extension?

The error message and the line indicate that the function called at line 10 doesn't exists, and that line is the first time an API function is used.

Have a look at the link I posted earlier.
Bomb Bloke #9
Posted 26 June 2014 - 07:11 AM
It's simply the case that the name in the file is not the name of the file. If the issue was in the loading of the API due to its title, then the error message wouldn't point to a line inside that API - it'd point to a line in the script which attempts to load it.

Sure, Cavious has misrepresented how the files are labeled, but that's not the problem here.
flaghacker #10
Posted 26 June 2014 - 09:59 AM
Ow now I see! I thought that the error was in the main script, and there line 10 is the first call to the API. I'm sorry for the disinformation.