Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
stage is a global, right? - Gideros Forum

stage is a global, right?

moopfmoopf Guru
edited March 2012 in General questions
So, stage is a global. In that case, if I'm running singleton classes for things such as audio control, config options etc. is adding them to stage the best way to go, as presumably I can then reference them with stage.myclass. Or is there a better way?

I'm still getting to grips with the performance and memory differences between locals and globals in Lua and working out the best way to access commonly used elements (not necessarily visual elements) - there seems to be a huge number of different ways to do the same thing in Lua, and I'm trying to get it clear in my head the relatives strengths and weaknesses of each one.

Dislikes: tytadas

+1 -1 (+0 / -1 ) Share on Facebook

Comments

  • Yes, stage is available in every file, so it is global.
  • Sorry yes, I know it is. I'm asking about the relative merits of using that as a container for other commonly used classes I want to use, adding them as elements of stage. Or if there is a "best practice" alternative in Lua.
  • atilimatilim Maintainer
    Hi @moopf,

    IMHO, If you're accessing a global variable many many times per frame, you should be careful about it. Otherwise you don't need to worry.

    To store the options of a game, I usually create an options.lua file with this content:
    Options = Core.class()
     
    function Options:init()
    	self:load()
    end
     
    function Options:load()
    	local t = table.load("|D|options.tbl")
     
    	if t ~= nil then
    		for k,v in pairs(t) do
    			self[k] = v
    		end	
    	else
    		self:setDefaults()
    		self:save()
    	end
    end
     
    function Options:save()
    	table.save(self, "|D|options.tbl")
    end
     
    function Options:setDefaults()
    	self.music = true
    	self.effects = true
    	-- etc...
    end
     
    options = Options.new()
    And then I access the global options table everywhere and if I change a field of it, I call options:save().

    (This code uses http://github.com/gideros/table.save to save/load a table and options.lua should be dependent to table.save-0.94.lua)

    Hope this helps

    Likes: chipster123

    +1 -1 (+1 / -0 ) Share on Facebook
  • andybarillaandybarilla Member
    edited March 2012
    I'm new to lua so I don't quite know all the inner workings of it yet but is there a difference between instantiating an options class like you are showing as opposed to instantiating it like:
    stage.options = Options.new()
  • alexzhengalexzheng Guru
    edited March 2012
    hi @atilim
    I have used this option in many of my games, not only the option data but also the level data.But recently I found it has a little problem when you add an option in update version.It may still load the old data,so I consider
    to add an version number to the table and check the version after load from table.
  • Hi @atilim, thanks for the reply. When you say "many times per frame" is there any kind of quantity in mind there?

    And on @andybarilla 's point, I wouldn't mind knowing if there's a difference in performance between having a global individually defined and having a local as a child of stage. Does one give better performance or memory usage than the other?
  • atilimatilim Maintainer
    edited March 2012
    @moopf Maybe I can say 10s. The time difference between accessing a local and a global variable is about ~%30.

    @moopf, @andybarilla I think there is no difference in terms of memory but accessing an individual global variable is a little bit faster.
  • Thanks @atilim, that gives me something to work with :)


  • To store the options of a game, I usually create an options.lua file with this content:
    Options = Core.class()
     
    function Options:init()
    	self:load()
    end
    >>> SNIP <<<
    Thanks for sharing that code - For my current project I've created my own simple Tween class and after looking at the "Classes in Gideros" example post on the Academy page, I couldn't decide what I was supposed to use a base class - in the end I used "EventDispatcher" as it seemed the most "base" of classes :)

    As you can see from the example below I don't need any event handling code, I just call the :update method once each "frame" and then poll :complete to see if the effect is complete, so I'm going to try removing EventDispatcher as the base class and see if it makes any diffference.
    Tween = Core.class(EventDispatcher)		-- most base class ???
     
    --[[
    "Simple" tween class - only handles linear interpolation but works well enough for fading things in / out, or use as a general timer.
     
    It's not "attached" to any object or table and doesn't effect any other objects "properties" that way the returned value from the :update() method can be used as required (ie can be used to fade out or cross fade between multiple objects, rather than having to attach a separate "tween" to each one!)
    --]]
    -- --------------------------------------
    -- Basic initialisation...
    -- length in frames, start value, end value, initial delay (in frames)
     
    function Tween:init( frames, sVal, eVal, delay )	
    	self.frames = frames
    	self.step = 0
    	self.start = sVal
    	self.delta = eVal - sVal
    	self.delay = delay or 0
    end
     
    -- --------------------------------------
    -- Update the tween (call once per frame)
     
    function Tween:update()
     
    	if self.delay > 0 then
    		self.delay = self.delay - 1; return self.start
    	end
     
    	if self.step < self.frames then self.step = self.step + 1 end
     
    	local ratio = self.step / self.frames
    	local result = self.start + (self.delta * ratio)	-- default to linear interpolation!
     
    	return result
    end
     
    -- --------------------------------------
    -- Returns true if the tween is complete!
     
    function Tween:complete()
     
    	if self.step == self.frames then return true end
    	return false
    end

    Sorry to go too far off topic here but...

    I'm also trying to work out how best to provide a core "utility" class that will hold small functions etc that I want to reuse from app to app and object to object and I'm wondering if this pattern might suffice.

    Interestingly when using Corona I looked quite heavily into using tables for objects and also the use of the require statement - I noticed that no real Gideros code seems to be using the require statement, even for the process of making a local reference to a global table (I'm assuming here that both my Tween class and the Atilim's original Options class are both global tables).

    My Lua knowledge is far less advanced than my C/C++ knowledge and so any advice with regards to creating a "table" of utility functions and any potential use of the require statement to localise references would be much appreciated.

    Lastly (with regards to the code above) I should probably mention that in general when developing I try to have as few "onEnterFrame" listeners as possible, preferring to have one that is called which in turn calls an objects :update() method, I find the code structure to be a lot easier and less prone to strange leaks and errors when listeners aren't removed correctly.

    Jon...



    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • atilimatilim Maintainer
    Hi,

    Currently we don't give support for require function, because every .lua file in the project is executed automatically. Supporting the require function and giving option to enable/disable the automatic execution of .lua files are in progress.

    Maybe you can populate your lua functions in a global "utility" table and then if you want to fast access you can assign them to a local variable (as in Lua's "math" and "io" tables).

  • gorkemgorkem Maintainer
    @atilim when do you think we can give this support? Submitting an issue would be nice I think, so it gets recorded in the roadmap.
  • atilimatilim Maintainer
    Yes, you're right. I've added this feature to the roadmap of 2012.2.2 http://bugs.giderosmobile.com/issues/55
  • To be honest - I've really understood the require function (or the module statement) anyway so if you don't currently support them and stuff works then I don't see it as an issue.

    In fact looking at the project and being able to set dependencies from one file to another (which I note affects the call order) seems a much better solution.

    Personally I *really* like the idea of forcing init.lua to be executed first and main.lua last - that way I can discipline myself to put any and all globals in init.lua and know that everything will be ready when needed, your OOP solution for Lua is by far the best I've seen.

    Kudos!

    Jon...

    Likes: atilim

    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
    +1 -1 (+1 / -0 ) Share on Facebook
Sign In or Register to comment.