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

Object Oriented: object tables global

Started by Corona, 06 March 2016 - 02:22 PM
Corona #1
Posted 06 March 2016 - 03:22 PM
Hello community!

I started a little project to familiarize myself with Object oriented Programming in Lua (again).
Now I've encountered a problem, which I cannot solve or know the cause to;

Below you have the code for my api,

now in the testcode, if I create two different new objects, and assign a table value to them (eg ObjectName.flags.visible = true), it sets this value for all other objects. If I do the same thing for "testValue" though, it behaves corectly.

API:

--Global Frame object, contains all the important information of the frame
--the key "content" is meant to contain anything from text to functions. Have to think that through though.
Frame = {pos = {x = 1, y = 1}, size = { x = 5, y = 5}, flags = {visible = false}, content = {}, style = {borderCol = colors.white, backgroundCol = colors.black} , enabled = { fcc = false, fcs = false, fcu = false }, testValue = 1}
--Creates the frame and gives it a unique UUID. This is helpful, trust me.
function Frame:craft( frame )
  frame = frame or {}
  setmetatable( frame, self )
  self.__index = self
  frame._UUID = math.random( 0, 100000 );
  if self.enabled.fcc then
	fcc.frameControl:registerFrame( self )
  end
  return frame
end
function Frame:enableModule( moduleName )
  if not _G.moduleName then
	os.loadAPI( moduleName )
  end
  self.enabled.moduleName = true
end
function Frame:disableModule( moduleName )
  self.enabled.moduleName = false
end
function Frame:setPosition( x, y )
  self.pos.x, self.pos.y = x, y
end
function Frame:setSize( xSize, ySize )
  self.size.x, self.size.y = xSize, ySize
end
function Frame:setFlag( flag, value )
  self.flags[flag] = value
end
function Frame:getFlag( flag )
  if not flag then
	return self.flags
  end
  return self.flags[flag]
end
function Frame:show()
  self.flags.visible = true
end

Testcode:

os.loadAPI("lib/fc")
local testFrame = fc.Frame:craft()
local testFrame2 = fc.Frame:craft()
testFrame:setFlag("test","value")
testFrame.testValue = 5
print(testFrame:getFlag("test"))
print(testFrame2:getFlag("test"))
print(testFrame.testValue)
print(testFrame2.testValue)
testFrame:show()
print(testFrame:getFlag("visible"))
print(testFrame2:getFlag("visible"))

Output:
value
value
5
1
true
true

Does anyone know a solution?

Thank you in advance!
Coro.
Edited on 06 March 2016 - 04:26 PM
SquidDev #2
Posted 06 March 2016 - 05:59 PM
The trouble is that the flags variable (and all table values) is shared across instances. If you move your initialisers into the :craft method, everything should work:


Frame = {}
--Creates the frame and gives it a unique UUID. This is helpful, trust me.
function Frame:craft( frame )
  frame = frame or {}
  frame.pos = {x = 1, y = 1}
  frame.size =  { x = 5, y = 5}
  frame.flags = { visible = false }
  -- etc..
  return frame
end
Edited on 06 March 2016 - 04:59 PM
Corona #3
Posted 06 March 2016 - 06:01 PM
This is really damn helpful! I'll try it right away! (:

I hope I did everything correctly and voted you up (If this helps anything)
And thank you again!