Accessing all the metatables created in a table

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
nikneym
Citizen
Posts: 56
Joined: Sat Mar 09, 2013 1:22 pm
Contact:

Accessing all the metatables created in a table

Post by nikneym »

Same question above! I was trying to implement Daniel Shiffman's simple p5.js particle system (https://www.youtube.com/watch?v=UcdigVaIYAk) and had this question. My code looks like this:

particle.lua

Code: Select all

local particle = {}
particle.__index = particle

function particle.new(x, y)
	local self = setmetatable({
		x = x,
		y = y,
		vx = math.random(-1, 1),
		vy = math.random(-5, -1),
		alpha = 255,
	}, particle)

	return self
end

function particle.update(self)
	self.x = self.x + self.vx
	self.y = self.y + self.vy

	self.alpha = self.alpha - 10
end

function particle.draw(self)
	love.graphics.setColor(255, 40, 40, self.alpha)
	love.graphics.circle("fill", self.x, self.y, 10)
end

return particle
main.lua

Code: Select all

local particle = require("particle")

local particles = {}

function love.update(dt)
	table.insert(particles, particle.new(love.mouse.getPosition()))

	for i, v in ipairs(particles) do
		v:update()

		if v.alpha < 0 then
			table.remove(particles, i)
		end
	end
end

function love.draw()
	for i, v in ipairs(particles) do
		v:draw()
	end
end
It basically works in a way I want but I want to do for loops (at love.draw and love.update events) inside of the particle script. What I'm trying to do is basically getting all the created metatables inside of the one table and accessing its data and change or etc. Is it possible? I see getmetatable function in a search but couldn't understand much.
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: Accessing all the metatables created in a table

Post by pgimeno »

You seem confused about a few things.

The only file that knows what particles are used, is main.lua, because that's where the `particles` table is. If you want to loop inside particle.lua, you need to move the table to that file, or even better, create a new file called particleSystem to manage particles, and place the table there.

The particles inside the array are not metatables. They are all tables and all of them have the same metatable, the `particle` table.

Deleting particles the way you're deleting them has a problem: you may skip checking some. To avoid that, iterate backwards instead of using ipairs.

That is, instead of doing this:

Code: Select all

	for i, v in ipairs(particles) do
		--rest of your code
do this:

Code: Select all

	for i = #particles, 1, -1 do
		local v = particles[i]
		--rest of your code
User avatar
nikneym
Citizen
Posts: 56
Joined: Sat Mar 09, 2013 1:22 pm
Contact:

Re: Accessing all the metatables created in a table

Post by nikneym »

pgimeno wrote: Sat Jun 06, 2020 1:48 pm The particles inside the array are not metatables. They are all tables and all of them have the same metatable, the `particle` table.
I understand it now. I thought lua creates inner tables to that one main table and didn't know what we create is actually a seperate table. Thank you so much. I'm such a fool :P I should understand when I tried to get item number of the particle table, which always returns 0 no matter how much particles I create. So, in that way getmetatable is only here for get the variables inside of a metatable am I right?
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: Accessing all the metatables created in a table

Post by pgimeno »

nikneym wrote: Sat Jun 06, 2020 4:53 pm I understand it now. I thought lua creates inner tables to that one main table and didn't know what we create is actually a seperate table. Thank you so much. I'm such a fool :P I should understand when I tried to get item number of the particle table, which always returns 0 no matter how much particles I create. So, in that way getmetatable is only here for get the variables inside of a metatable am I right?
getmetatable is used to get the metatable that was set for an object. The usefulness of it depends on how you're using the metatables. One example where it's useful is to get the parent of a class, if you're using that kind of OOP.

In the code fragments you've provided, getmetatable doesn't seem useful. Each individual particle instance will have its metatable set to the `particle` table, which acts like a class, and you know this in advance. You don't set the metatable of any other object.

Note that the length (#) operator only applies to tables with integer numeric indices like your `particles` table (which is used as array), not to tables with string indices like the fields of the `particle` table (which is used as class) or the instances of that class, the individual particles. It will return 0 if there are no integer indices. Note also that the result is only guaranteed to make sense if the indices start at 1 and are consecutive.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 219 guests