why my value is nill? Dont understand what happen - lua

I have this.
components=require("components")
entity={}
--test---
function entity.test(x,y)
self ={}
self.id="test"
--self.position=components.position(x,y)
return self
end
return entity
In main i have this.
entities=require("entity")
function love.load()
test1=entities.test(100,200)
print(test1.id)
end
the output is ok, but, when I add another component .
components=require("components")
entity={}
--test---
function entity.test(x,y)
self ={}
self.id="test"
self.position=components.position(x,y)
return self
end
return entity
and make another print
entities=require("entity")
function love.load()
test1=entities.test(100,200)
print(test1.id)
print(test1.position.y)
end
I got first a nill valur, and then an error because field position is nill. What happen? Thanks in advance.
my component.lua
component = {}
--position--
function component.position(x,y)
self={}
self.x=x
self.y=y
return self
end
return component

You can fix the problem by declaring your variables local, e.g. local self = {}.
When you call entity.test, that function assigns a new table to the global self. It then calls components.position which assigns a whole new table to self, which never gets the position field.

Related

Writing function to check state's machine current state [Lua/Love2d]

I'm learning game development with LÖVE2D and Lua and lately I've been using a state machine class. I haven't coded the class myself, but I've went through the code and I think I pretty much got it, besides this one problem.
The thing is, I'm trying to prompt the class for its current state, just so I can use it inside an if, but no matter what, I cannot get it right.
Here's the relevant code of the class:
StateMachine = Class{}
function StateMachine:init(states)
self.empty = {
render = function() end,
update = function() end,
enter = function() end,
exit = function() end
}
self.states = states or {} -- [name] -> [function that returns states]
self.current = self.empty
end
function StateMachine:change(stateName, enterParams)
assert(self.states[stateName]) -- state must exist!
self.current:exit()
self.current = self.states[stateName]()
self.current:enter(enterParams)
end
What I'm basically trying to do is:
function StateMachine:is(stateName)
if self.current == self.states[stateName] then
-- this never executes
return true
end
return false
end
I've tried changing self.states[stateName] to other things to test it out and also tried printing stuff to the console to see why the comparison is never true. It seems self.current returns a pointer to a table and thus never matches whatever is on the other side of the comparison operator.
Thanks for your help!
self.current is set to the return value of self.states[stateName] in StateMachine:change
function StateMachine:change(stateName, enterParams)
...
self.current = self.states[stateName]() -- note the () indicating the call
This means, unless the return value is self, self.current will not be equal to the function or object self.states[stateName] that it is compared to in StateMachine:is
function StateMachine:is(stateName)
if self.current == self.states[stateName] then -- here we are comparing the function to the return value
I would suggest expanding your state object to have a :getName function that would return the stateName or to store the name in your StateMachine under a key such as currentStateName.
I had the exact same question & I'd like to add--perhaps some of the comments explain this in language I just didn't understand :D--but in the getCurrentState function I created I had to do this:
function StateMachine:getCurrentState()
variable = self.currentStateName
return variable
where ofc variable is just some placeholder. but I had to grab the reference that self.currentStateName was pointing to, otherwise the comparison always failed.

How to get __metatable function to be called?

My goal
Get getmetatable to return the return value of the function assigned to the __metatable field.
Code:
local x, m = {}, {__metatable = function() return nil end};
setmetatable(x, m);
io.write("Let's get the metatable:", tostring(getmetatable(x)), "\n");
But I'm getting the actual function rather than return.
So how do I get it to be called so I can get nil? So it seems like it has no metatable?
Just rewrite getmetatable to work the way you want it to ;)
do local getmetatable = getmetatable
function _G.getmetatable(tab)
local meta = getmetatable(tab)
if type(meta)=='function' then
return meta(tab)
else
return meta
end
end
end
Alternatively, you could just set __metatable to false. This would work for code written like if getmetatable(foo) then, but would break to code like if getmetatable(foo) == false. Arguably, the first is the one you should use, but there's likely someone out there doing the second one.
That'd also hint to the user that there is a metatable, it's just none of their busyness to mess with it.

wxlua self changing value?

I'm trying to draw some stuff using wxlua.
ExampleClass = {}
function ExampleClass:New(someWxPanel)
local obj = {}
setmetatable(obj, self)
self.__index = self
self.m_panel = someWxPanel
return obj
end
function ExampleClass:OnPaint()
local dc = wx.wxPaintDC(self.m_panel)
--paint some stuff
end
local example = ExampleClass(somePanel)
somePanel:Connect(wx.wxEVT_PAINT, example.OnPaint)
I get the following error message:
wxLua: Unable to call an unknown method 'm_panels' on a 'wxPaintEvent' type.
While in any other function I define as Example:SomeFunction() self points to my Example instance and I can perfectly access its members here self is a wxPaintEvent?
How did this happen? Does the Connect somehow change self? How can I access my members now?
Appreciate any help!
When you register example.OnPaint as the event handler in somePanel:Connect(wx.wxEVT_PAINT, example.OnPaint), it always gets the event as the first parameter, but your method expects the object (self) passed as the first parameter, hence the error you get. You need to replace the registration with something like this:
somePanel:Connect(wx.wxEVT_PAINT, function(event) example:OnPaint(event) end)

How does setmetatable() work and why the metatable is needed in the linked list in lua

I'm learning how Lua's metatables work in OOP, and I am confused of the code I read from the object orientation tutorial on lua-users wiki. Could someone helps to explain the following questions? Thanks.
Question 1:
The wiki's explanation: Here we add a metatable to the class table that has the __call metamethod, which is triggered when a value is called like a function. We make it call the class's constructor, so you don't need the .new when creating instances.
(1)How does the __call get called in the example so the constructor is called?
(2)Does "cls" refer to "MyClass?"
setmetatable(MyClass, {
__call = function (cls, ...)
return cls.new(...)
end,
})
Question 2:
What does {} from the following code refer to?
function MyClass.new(init)
local self = setmetatable({}, MyClass)
self.value = init
return self
end
**Here is the Complete code:
local MyClass = {}
MyClass.__index = MyClass
setmetatable(MyClass, {
__call = function (cls, ...)
return cls.new(...)
end,
})
function MyClass.new(init)
local self = setmetatable({}, MyClass)
self.value = init
return self
end
function MyClass:set_value(newval)
self.value = newval
end
function MyClass:get_value()
return self.value
end
local instance = MyClass(5)
-- do stuff with instance...
Question 1:
setmetatable(MyClass, {
__call = function (cls, ...)
return cls.new(...)
end,
})
This sets MyClass's metatable to a table which defines the __call metamethod. Because of that, you can 'call' MyClass (newObj = MyClass(<args>)). In the metamethod, cls refers to the table that is called, in this case it refers to MyClass.
Question 2:
function MyClass.new(init)
local self = setmetatable({}, MyClass)
self.value = init
return self
end
{} is syntax for a table literal, which creates a new table (an empty one in this case). The MyClass table is set as the metatable for a new table. Then this new table is assigned to self.
More about metatables can be found here: https://www.google.com/?gws_rd=ssl#q=lua+metatables as suggested by Anderson Green in the comments.

accessing lua self member got nil

I was trying to access a member of 'self', see following:
function BasePlayer:blah()
--do blah
end
function BasePlayer:ctor(tape) --constructor.
self.tape = tape --'tape' is a lua table, and assigned to 'self.tape'.
dump(self.tape) --i can dump table 'self.tape',obviously it's not nil.
self.coreLogic = function(dt) --callback function called every frame.
echoInfo("%s",self) --prints self 'userdata: 0x11640d20'.
echoInfo("%s",self.tape) -- Here is my question: why self.tape is nil??
self:blah() --even function too??
end
end
So my question is, in my callback function 'coreLogic', why 'self.tape' is nil but self is
vaild?
And functions can't be called either.
I'm really confused:S
When you define a function using the :, the implicit parameter is created on its own. When you are defining the function coreLogic, you'd need to pass it as the first argument:
self.coreLogic = function( self, dt )
and that would be the same as:
function self:coreLogic(dt)
self in itself doesn't exist.
Basically,
function BasePlayer:blah()
is same as writing:
function BasePlayer.blah( BasePlayer )

Resources