Howdy.
I'm trying to learn metatables and I would like a really simple breakdown on how reassigning functions work.
Like, there is another topic in this forum about changing the love:setFilter property and returning the imageData to something.
Could someone break that down or tell me what a metatable really does?
Thanks.
Metatables: The Darkest Magic
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Re: Metatables: The Darkest Magic
I think you'll have to rephrase your question, I have no idea what that means.
Do you recognise when the world won't stop for you? Or when the days don't care what you've got to do? When the weight's too tough to lift up, what do you? Don't let them choose for you, that's on you.
Re: Metatables: The Darkest Magic
Can someone give me a tutorial on metatables?
Re: Metatables: The Darkest Magic
You can find a very good online book on Lua here: http://www.lua.org/pil/index.html
Scroll down, the first edition is free to read.
Chapter 13 deals with metatables. However I recommend to read the chapters before as well, as usually the chapters build upon each other.
Scroll down, the first edition is free to read.
Chapter 13 deals with metatables. However I recommend to read the chapters before as well, as usually the chapters build upon each other.
Check out my blog on gamedev
Re: Metatables: The Darkest Magic
You can change love:setFilter (or the appropriate function) without metatables.
For example, this will print an output in the console whenever you create an image.
Now for metatables:
setmetatable(tab, tab) is the function.
It returns a metatable, but it also makes the first argument a metatable. This makes it possible to put metatables on _G (which cannot be changed, and is a global variable holding all other variables) or set a variable to be a metatable directly.
Here is my fonts pseudolib:
If you read through my fonts code, the first instance of __index has fname, which is the font name (fonts["fontname.extension"])
fonts["fontname.extension"] returns a table, so you could essentially store the font in your script and get any size you want by this code:
Now if you were to call fonts["myfont.ttf"][60], it's the same as this:
testfont = fonts["myfont.ttf"]
testfont_60 = testfont[60]
print( testfont_60 == fonts["myfont.ttf][60] )
-- > true
the second metatable checks if the font was already created and return the font that was already created (same filename and size checked)
if it wasn't already created, then check if there is already a font but with a different size, if there isn't already a font with that filename (regardless of the size), then create a font table for that filename inside the LOCAL fonts table (not the global fonts table).
create the new font instead the globalfonttable[filename][size]
return the new font
hope you like my tut
For example, this will print an output in the console whenever you create an image.
Code: Select all
love.image._newImage = love.image.newImage
function love.image.newImage(filename, ...)
local obj = love.image._newImage(filename, ...)
print( "Created an image, the filename may be: " .. tostring(filename) )
return obj
end
Now for metatables:
setmetatable(tab, tab) is the function.
It returns a metatable, but it also makes the first argument a metatable. This makes it possible to put metatables on _G (which cannot be changed, and is a global variable holding all other variables) or set a variable to be a metatable directly.
Here is my fonts pseudolib:
Code: Select all
-- This code has been created by qaisjp and is part of Little Sticky Destroyer.
local fonts = {}
return setmetatable({}, {
__index = function(_, fname)
return setmetatable({}, {
__index = function(_, k)
if fonts[fname] and fonts[fname][k] then
return fonts[fname][k]
else
if not fonts[fname] then
fonts[fname] = {}
end
fonts[fname][k] = love.graphics.newFont("fonts/"..fname, k)
return fonts[fname][k]
end
end
})
end
})
[code]
Basically, all you have to do is this:
fonts = require("fonts") (or whatever you named the file)
This'll return a metatable, as you can see the first argument is an empty table (not a variable) so for the metatable to take an effect I have to store it.
My library will allow you to directly get fonts instead of creating fonts, like so:
love.graphics.setFont(fonts["DarkMagic.ttf"][60])
This'll create a font the first time that table is called and store it for safe keeping, this makes it possible to call it every frame without any inefficiency (once the font was created, it wont be created again but the old font will be returned)
The second argument is a table containing Metatable Events [url=http://lua-users.org/wiki/MetatableEvents][link][/url]
The table contains functions, but with a specific index (name of the key); I will explain __index table key.
setmetatable(_G, {
__index = function(t, k)
end
})
The above code essentially makes global variables stop working. Every table without a metatable actually has this as the __index:
__index = function(t, k)
return rawget(t, k)
end
(actually the value of __index == rawget but you get my jist)
rawget has two arguments, table and key. it returns the value of a table with that key, ignoring metatable events. Since __index is called whenever you are trying to receive a variable ( that is, hello = love; because love is a global variable and all global variables are in the _G table ), trying to get the value wont have any effect unless you add it inside your __index.
This code will output the key and value of everything you try to get. Try it at http://lua.org/demo.html
[code]
setmetatable(_G, { __index = function(t, k)
print(tostring(t) .. " ; " .. tostring(k))
return rawget(t, k)
end})
-- there is a metatable for when setting, our code wont have any effect when setting.
hello_str, world_str = "hi", "universe"
-- this will make it ouput
abc, def = hello_str, world_str
-- should get an output!
fonts["fontname.extension"] returns a table, so you could essentially store the font in your script and get any size you want by this code:
Code: Select all
TestFont = fonts["TestFont.ttf"]
function love.draw()
love.graphics.setFont(TestFont[30])
love.graphics.printf("testcenter", 0, 0, 800, "center")
love.graphics.setFont(TestFont[60])
love.graphics.printf("testcenter big", 0, 90, 800, "center")
end
testfont = fonts["myfont.ttf"]
testfont_60 = testfont[60]
print( testfont_60 == fonts["myfont.ttf][60] )
-- > true
the second metatable checks if the font was already created and return the font that was already created (same filename and size checked)
if it wasn't already created, then check if there is already a font but with a different size, if there isn't already a font with that filename (regardless of the size), then create a font table for that filename inside the LOCAL fonts table (not the global fonts table).
create the new font instead the globalfonttable[filename][size]
return the new font
hope you like my tut
Lua is not an acronym.
- Roland_Yonaba
- Inner party member
- Posts: 1563
- Joined: Tue Jun 21, 2011 6:08 pm
- Location: Ouagadougou (Burkina Faso)
- Contact:
Re: Metatables: The Darkest Magic
Well, don't go with the false assumption that to change the behaviour of any Lua function packed in a table, you'll have to use metatables.Raylin wrote:Howdy.
I'm trying to learn metatables and I would like a really simple breakdown on how reassigning functions work.
Like, there is another topic in this forum about changing the love:setFilter property and returning the imageData to something.
Could someone break that down or tell me what a metatable really does?
Thanks.
As Qaisjp said, just override this function. It works like a charm.
Now, if you do want to learn metatables for *another* purpose, here is a very friendly tutorial, written by BlackBulletIV.
Re: Metatables: The Darkest Magic
Could someone please enlighten me as to what the hell love:setFilter is?
Do you recognise when the world won't stop for you? Or when the days don't care what you've got to do? When the weight's too tough to lift up, what do you? Don't let them choose for you, that's on you.
- Roland_Yonaba
- Inner party member
- Posts: 1563
- Joined: Tue Jun 21, 2011 6:08 pm
- Location: Ouagadougou (Burkina Faso)
- Contact:
Re: Metatables: The Darkest Magic
Maybe he wanted to mention Image:setFilter
Who is online
Users browsing this forum: Bing [Bot] and 4 guests