Page 1 of 1

Problem with scoping (different files)

Posted: Thu Jun 25, 2015 2:31 am
by FLÖRGEN
Hi, I have a Game class which features an interface:

Code: Select all

local Game = class("Game")
Game:include(Stateful)

local Menu = Game:addState("Menu")

function Menu:enteredState()
	self.interface = gui.Interface:new():loadFromFile("menu/main.lua")
end
And the menu being loaded from file looks like this:

Code: Select all

local INTERFACE = {}

INTERFACE.button	=	gui.Button:new("New Game", function()
						-- This function is the onClick event for the button
					end)

return INTERFACE
My issue is that I want the onClick event shown above to be able to access the Menu instance (the self part of self.interface line in the first code snippet) and call one of its methods. I'm not entirely sure how to do this due to the button (and its onClick function) being defined in a different file. Just a note, I don't have to do it this way if I must use another to do what I want to but I would still like to be able to load the interface from a file if possible. Thank you :)

Re: Problem with scoping (different files)

Posted: Thu Jun 25, 2015 6:01 am
by 0x72
One of the ways might be something like that (direct one to one relation between the interface and the menu):

Code: Select all

function Menu:enteredState()
   self.interface = gui.Interface:new(self):loadFromFile("menu/main.lua")
  -- gui.Interface:new(self, "menu/main.lua") ?
end

Code: Select all

local INTERFACE = class("INTERFACE") -- edited (I've wrote {} here, fixing for posterity)

INTERFACE:initialize(menu)
  -- self.menu = menu
  self.button = gui.Button:new("New Game", function()
    menu:enteredState()
  end)
end

return INTERFACE
not sure if it works - what gui and class lib do you use?

--- edit ----
actually you should be able to:

Code: Select all

INTERFACE:initialize(menu)
  self.button = gui.Button:new("New Game", menu:enteredState)
end

Re: Problem with scoping (different files)

Posted: Thu Jun 25, 2015 1:15 pm
by FLÖRGEN
Hm, it doesn't seem to be working (EDIT: It cannot index the parent) :/ I am using middleclass and loveframes (with the gui.Component:new() functions being an attempt to neaten the code). Perhaps this is not the best way to be doing this and there is a more elegant way? Anyhow, I uploaded a .love below:

Re: Problem with scoping (different files)

Posted: Thu Jun 25, 2015 7:23 pm
by 0x72
You have misspelled initialize in interface.lua - when you fix it, it'll work :)

Re: Problem with scoping (different files)

Posted: Fri Jun 26, 2015 1:05 am
by FLÖRGEN
Thank you so much :D I'm just wondering though, do you think there is a more elegant way to do this or would what I have be good enough?

Re: Problem with scoping (different files)

Posted: Fri Jun 26, 2015 7:27 am
by 0x72
First of all: It's simple now, I'd move forward.

But if you feel like working on menu today (instead of let's say - gameplay) then instead of menu object (self) you could pass game to the interface, or you could even make game a global variable[1]. The issue there is that you don't know if game is the only thing you might need and there (you actually could pass anything you need there now) and if game has a particular methods when in a particular state.

But, I personally like the idea of state passing everything that interface might need - it's easy to reasoning about the interface when it's related to the state (also parent might be renamed to like data in case you pass there anything else.

not sure if it's elegant but it's simple-and-working

You can also build proper, robust, callback driven event system - please don't go this way - it's a mess.

[1] some people hate global variables and they have good reasons for that, but for a game object I might make an exception :)