Running inherited function with self as parameter.

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
littlegaming
Prole
Posts: 6
Joined: Fri Mar 04, 2016 9:19 am
Contact:

Running inherited function with self as parameter.

Post by littlegaming »

I'm trying to make a simple Gui library for a new project and I'm trying to make each object loop through its children and their update and draw functions.

This is Jammi.lua:

Code: Select all

local Jammi = {}
Jammi.children = {}

function Jammi:new(o)
	o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end

function Jammi:addchild(o)
	self.children[#self.children+1] = o
end

function Jammi.draw(thing)
	for i, child in ipairs(thing.children) do
		child:draw()
	end
end
function Jammi.update(thing, dt)
	for i, child in ipairs(thing.children) do
		child:update(dt)
	end
end

Jammi.Box = Jammi:new()

function Jammi.Box:draw()
	love.graphics.setColor(self.r or 255, self.g or 255, self.b or 255)
	love.graphics.rectangle(
		self.drawtype or "fill", 
		self.x or 0, 
		self.y or 0, 
		self.width or 20, 
		self.height or 20,
		self.rx or 0,
		self.ry or self.rx,
		self.segments or nil
	)
	Jammi.draw(self)
end

function Jammi.Box:update(dt)
	Jammi.update(self)
end

Jammi.Text = Jammi:new()

function Jammi.Text:draw()
	love.graphics.setColor(self.r or 255, self.g or 255, self.b or 255, self.a or 255)
	love.graphics.printf(
		self.text,
		self.x or 0,
		self.y or 0,
		self.wraplimit or love.graphics.getWidth(),
		self.alignmode or "left",
		self.angle or 0,
		self.sx or 1,
		self.sy or self.sx,
		ox or 0,
		oy or 0,
		kx or 0,
		ky or 0
	)
	Jammi.draw(self)
end

Jammi.Button = Jammi:new()
Jammi.Button.Held = false

function Jammi.Button:draw()
	love.graphics.setColor(self.Box.r or 255, self.Box.g or 255, self.Box.b or 255, self.Box.a or 255)
	love.graphics.rectangle(
		self.Box.drawtype or "fill", 
		self.Box.x or self.x, 
		self.Box.y or self.y, 
		self.Box.width or self.width, 
		self.Box.height or self.height,
		self.Box.rx or 0,
		self.Box.ry or self.rx,
		self.Box.segments or nil
	)
	love.graphics.setColor(self.Text.r or 255, self.Text.g or 255, self.Text.b or 255, self.Text.a or 255)
	love.graphics.printf(
		self.Text.text or "",
		self.Text.x or self.x,
		self.Text.y or self.y,
		self.Text.wraplimit or self.width,
		self.alignmode or "center"
	)
	Jammi.draw(self)
end

function Jammi.Button:update(dt)
	if (self.x < love.mouse.getX()+1 and love.mouse.getX() < self.x+self.width and self.y < love.mouse.getY()+1 and love.mouse.getY() < self.y+self.height) then
		if love.mouse.isDown(1) then
			if self.Held and not self.canHold then
				return
			end
			if self.onClick then self.onClick() end
			self.Held = true
			return
		end
	end
	self.Held = false
	Jammi.update(self, dt)
end

return Jammi
And main.lua:

Code: Select all

local Jammi = require("/Jammi")
local Gui = Jammi:new()
Gui:addchild(Jammi.Box:new({x=20, y=20, width=180, height=400}))


function love.update(dt)
	Gui.update(Gui, dt)
end

function love.draw()
	Gui.draw(Gui)
end
And this is the output:

Code: Select all

Error: /Jammi.lua:21: stack overflow
stack traceback:
	/Jammi.lua:21: in function 'update'
	/Jammi.lua:44: in function 'update'
	/Jammi.lua:22: in function 'update'
	/Jammi.lua:44: in function 'update'
	/Jammi.lua:22: in function 'update'
	/Jammi.lua:44: in function 'update'
	/Jammi.lua:22: in function 'update'
	/Jammi.lua:44: in function 'update'
	/Jammi.lua:22: in function 'update'
	...
	/Jammi.lua:44: in function 'update'
	/Jammi.lua:22: in function 'update'
	/Jammi.lua:44: in function 'update'
	/Jammi.lua:22: in function 'update'
	/Jammi.lua:44: in function 'update'
	/Jammi.lua:22: in function 'update'
	main.lua:7: in function 'update'
	[string "boot.lua"]:464: in function <[string "boot.lua"]:436>
	[C]: in function 'xpcall'
I know why it's spitting out stack overflow, but I can't think of how to correct it. From what I know this should be looping through every object's children and their children running their methods along the way. Any suggestions on how to optimise anything else is welcome too.
Attachments
Jammi.love
(1.75 KiB) Downloaded 116 times
My Website
It's a W.I.P
User avatar
Tjakka5
Party member
Posts: 243
Joined: Thu Dec 26, 2013 12:17 pm

Re: Running inherited function with self as parameter.

Post by Tjakka5 »

Simply changing

Code: Select all

function Jammi:new(o)
	o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end
to

Code: Select all

function Jammi:new(o)
	o = o or {}
	o.children = {}
    setmetatable(o, self)
    self.__index = self
    return o
end
should fix it.

However, there's quite a few other things that don't seem quite right about your implementation. Maybe you should have another look at how classes are implemented exactly, to avoid further confusion.
User avatar
zorg
Party member
Posts: 3444
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Running inherited function with self as parameter.

Post by zorg »

And do check how the : colon syntax works exactly, you might not be doing what you want with that either.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
littlegaming
Prole
Posts: 6
Joined: Fri Mar 04, 2016 9:19 am
Contact:

Re: Running inherited function with self as parameter.

Post by littlegaming »

Ah, I see what I did now, thank you.
My Website
It's a W.I.P
Post Reply

Who is online

Users browsing this forum: No registered users and 84 guests