Posted 13 July 2013 - 06:58 PM
Hello pros,
I was creating my program, making clickable buttons. They worked perfectly as expected. It was done by creating a table called "button" and implementing in it some functions to handle buttons. Buttons are created and saved in the same table ("button") called "buttons":
This worked as expected, so I wanted to check what will the code do if there is no buttons in the "buttons" table, so I tried to draw buttons from the "butt2" table:
So, my question is that:
Why is it behaving like that? Maybe "setmetatable()" method is making table "buttons" public to every other instance (wrong word, don't remember other words) of "button" table?
Here are the codes (just run it in CC, they don't error):
Working:
Not Working:
I was creating my program, making clickable buttons. They worked perfectly as expected. It was done by creating a table called "button" and implementing in it some functions to handle buttons. Buttons are created and saved in the same table ("button") called "buttons":
local button = {
buttons = {},
add = function (self, and other variables)
--blah, blah
end,
remove = function (same stuff)
--another function
end,
--More functions...
}
Now, I didn't want all of my buttons to be in button.buttons table, so I wrote this:
local butt1 = setmetatable({}, {__index = button})
local butt2 = setmetatable({}, {__index = button})
butt1:add("blah, blah", arguments...)
butt1:draw()
This worked as expected, so I wanted to check what will the code do if there is no buttons in the "buttons" table, so I tried to draw buttons from the "butt2" table:
butt2:draw()
And it did draw a button, the one that I created in the "butt1" table. So I was searching how to fix it and I found it. I deleted the "buttons" table from "button" table:
local button = {
--removed the "buttons = {}," line
add = function (self, and other variables)
--blah, blah
end,
remove = function (same stuff)
--another function
end,
--More functions...
}
and defined that table in the setmetatable method:
local butt1 = setmetatable({buttons = {}}, {__index = button})
local butt2 = setmetatable({buttons = {}}, {__index = button})
and then "butt2:draw()" didn't draw any buttons (as it should be).So, my question is that:
Why is it behaving like that? Maybe "setmetatable()" method is making table "buttons" public to every other instance (wrong word, don't remember other words) of "button" table?
Here are the codes (just run it in CC, they don't error):
Working:
Spoiler
local version = "0.1a"
local button = {
add = function (self, id, x, y, text, w, h, tColor, bColor, offsetX, offsetY, enabledButtons)
table.insert(self.buttons, {id = id, x = x, y = y, w = w or text and #text or 1, h = h or 1, text = text, tc = tColor or colors.white, bc = bColor or colors.black, ox = offsetX or 0, oy = offsetY or 0, b = enabledButtons or {true, true, true}})
return true
end,
remove = function (self, id)
for i, b in pairs(self.buttons) do
if b.id == id then
table.remove(self.buttons, i)
return true
end
end
return false
end,
click = function (self, but, x, y)
for i, b in pairs(self.buttons) do
if b.x <= x and b.x + b.w - 1 >= x then
if b.y <= y and b.y + b.h - 1 >= y then
if b.b[but] then
return b.id
end
end
end
end
end,
draw = function (self)
for i, b in pairs(self.buttons) do
term.setBackgroundColor(b.bc)
term.setTextColor(b.tc)
for w = 0, b.w - 1 do
for h = 0, b.h - 1 do
term.setCursorPos(b.x + w, b.y + h)
term.write(" ")
end
end
term.setCursorPos(b.x + b.ox, b.y + b.oy)
term.write(b.text:sub(1, b.w - b.ox))
end
end,
exists = function (self, id)
for i, b in pairs(self.buttons) do
if b.id == id then
return true
end
end
return false
end,
list = function (self)
local butt = {}
for i, but in pairs(self.buttons) do
table.insert(butt, but.id)
end
return unpack(butt)
end
}
local function newButtons ()
return setmetatable({buttons = {}}, {__index = button})
end
local butt1 = newButtons()
local butt2 = newButtons()
butt1:add("new", 1, 1, "New Button", 10, nil, nil, nil, 2)
butt1:draw()
print()
sleep(1)
print("list of butt2: ", butt2:list())
print("list of butt1: ", butt1:list())
print("list of butt2: ", butt2:list())
print("Press any key to continue")
os.pullEvent()
term.clear()
butt2:draw()
print()
print("list of butt2: ", butt2:list())
sleep(1)
print("\"new\" exists in butt2: ", butt2:exists("new"))
print("butt1 == butt2: ", butt1 == butt2)
Not Working:
Spoiler
local version = "0.1a"
local button = {
buttons = {},
add = function (self, id, x, y, text, w, h, tColor, bColor, offsetX, offsetY, enabledButtons)
table.insert(self.buttons, {id = id, x = x, y = y, w = w or text and #text or 1, h = h or 1, text = text, tc = tColor or colors.white, bc = bColor or colors.black, ox = offsetX or 0, oy = offsetY or 0, b = enabledButtons or {true, true, true}})
return true
end,
remove = function (self, id)
for i, b in pairs(self.buttons) do
if b.id == id then
table.remove(self.buttons, i)
return true
end
end
return false
end,
click = function (self, but, x, y)
for i, b in pairs(self.buttons) do
if b.x <= x and b.x + b.w - 1 >= x then
if b.y <= y and b.y + b.h - 1 >= y then
if b.b[but] then
return b.id
end
end
end
end
end,
draw = function (self)
for i, b in pairs(self.buttons) do
term.setBackgroundColor(b.bc)
term.setTextColor(b.tc)
for w = 0, b.w - 1 do
for h = 0, b.h - 1 do
term.setCursorPos(b.x + w, b.y + h)
term.write(" ")
end
end
term.setCursorPos(b.x + b.ox, b.y + b.oy)
term.write(b.text:sub(1, b.w - b.ox))
end
end,
exists = function (self, id)
for i, b in pairs(self.buttons) do
if b.id == id then
return true
end
end
return false
end,
list = function (self)
local butt = {}
for i, but in pairs(self.buttons) do
table.insert(butt, but.id)
end
return unpack(butt)
end
}
local function newButtons ()
return setmetatable({}, {__index = button})
end
local butt1 = newButtons()
local butt2 = newButtons()
butt1:add("new", 1, 1, "New Button", 10, nil, nil, nil, 2)
butt1:draw()
print()
sleep(1)
print("list of butt2: ", butt2:list())
print("list of butt1: ", butt1:list())
print("list of butt2: ", butt2:list())
print("Press any key to continue")
os.pullEvent()
term.clear()
butt2:draw()
print()
print("list of butt2: ", butt2:list())
sleep(1)
print("\"new\" exists in butt2: ", butt2:exists("new"))
print("butt1 == butt2: ", butt1 == butt2)