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

Window API help

Started by callawh, 16 January 2015 - 02:11 AM
callawh #1
Posted 16 January 2015 - 03:11 AM
I've been messing around with the window api lately. My program worked fine but it was a bit messy so I tried to split it up into my own personal little APIs. My problem is that I can't get the APIs to recognize the initial windows I created in the original program.

I created the window named bPage and loaded the box API

screenWidth, screenHeight = term.getSize()
bPage = window.create(term.current(), 1, 2, screenWidth, screenHeight - 1)
os.loadAPI("/Applications/BowserBrowser/api/box")

Later I try to create a box

if line == "BOX" then
local x = page.readLine()
local y = page.readLine()
local width = page.readLine()
local height = page.readLine()
color = page.readLine()
box.create(x,y,width,height,color)
end

Here is the box api

function create(xPos,yPos,boxWidth,boxHeight,boxColor)	   -- creates box at x/y and width/height/color
boxColor = boxColor - 0								  -- convert string to number
bPage.setBackgroundColor(boxColor)
for i = 1, boxHeight do								  -- creates box height
  bPage.setCursorPos(xPos,yPos)
  for j = 1, boxWidth do							   -- creates box width
   bPage.write(" ")
  end
  yPos = yPos + 1									  -- sets width to next line
end
end

Also the error I get is:
box:3: attempt to index ? (a nill value)
Bomb Bloke #2
Posted 16 January 2015 - 06:14 AM
When an API is loaded, it gets its own environment table, separate to the one your regular scripts run in (both of which are separate to _G, though both regular scripts as well as APIs have access to _G). Once the API's code has been run, any variables sitting in its environment table (eg, the ones pointing to the functions you defined in the API) get dumped into a table named after that API, that goes into _G, and you can access them from there. (Eg, if you have a function called "create" in an API called "box", then you end up with a table called "box" and can refer to the function in it via box.create).

This means that APIs and scripts cannot share "global" variables in the way that scripts and other scripts can share them. This isn't hard to work around, though - just add functionality to your API that allows your script to pass a window object to it.

For example, you could do something like this:

local bPage = window.create(<whatever>)
os.loadAPI("/Applications/BowserBrowser/api/box")
box.create(bPage,x,y,width,height,color)

function create(bPage,xPos,yPos,boxWidth,boxHeight,boxColor)
  boxColor = tonumber(boxColor) or 0  -- If boxColor can be represented as a number, set it to that number, otherwise set it to 0.
  bPage.setBackgroundColor(boxColor)
  .
  .
  .

Or, you could do something like this:

local bPage = window.create(<whatever>)
os.loadAPI("/Applications/BowserBrowser/api/box")
box.setWindow(pPage)
box.create(x,y,width,height,color)

local bPage

function setWindow(newWindow)
  bPage = newWindow
end

function create(xPos,yPos,boxWidth,boxHeight,boxColor)
  boxColor = tonumber(boxColor) or 0  -- If boxColor can be represented as a number, set it to that number, otherwise set it to 0.
  bPage.setBackgroundColor(boxColor)
  .
  .
  .

The reason these methods work is that window objects are really just tables, and variables you "store tables in" don't actually end up holding a copy of the table - instead they end up holding a pointer to where the actual table exists in RAM (think of it like a shortcut icon, or an alias. Same thing goes for variables you use for functions and co-routines, by the way). You can copy that pointer into other variables, and those variables will all end up leading to the one original table. For eg:

local a = {}
local b = a
a[1] = "fish"
print(b[1])  --> fish
callawh #3
Posted 16 January 2015 - 10:19 PM
Thanks for the help!