Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Constants! — Gideros Forum

Constants!

techdojotechdojo Guru
edited July 2012 in Code snippets
Just thought I'd share this.
Coming from a C/C++ background it's easy to miss things like #define for constants - we all know how bad it is to use "magic numbers" in our code, especially if want to make it readable or track bugs down in six weeks time.

With this in mind I went looking for a simple way to create a table of "READ ONLY" variables (ie constants). Turns out it was easier than I thought - someone posted this example on the "beer" SDK forum so I cleaned it up and made it more Gideros friendly.

Put the following code somewhere in your init.lua file (but putting it in init you guarantee this code is run first (before any of your game code).
-- ------------------------------------------------------------------
-- Declare a global table of "constants" that can't be changed once set!
 
const = {}
local data = {} 
const_mt = {
	__newindex = function(a,b,c)
		if data[b] == nil then
			if type(c) == 'table' then	-- make that table readonly
				local proxy = {}
				local mt = {       -- create metatable
					__index = c,
					__newindex = function (t,k,v)
						error("Attempt to update read-only table '"..b.."' index '"..tostring(k).."' with '"..tostring(v).."'",2)
						--print("Attempt to update read-only table '"..b.."' index '"..tostring(k).."' with '"..tostring(v).."'")
					end
				}
				setmetatable(proxy, mt)
				data[b]=proxy
			else
				data[b]=c
			end
		else
			error("Illegal assignment to constant '"..tostring(b).."'",2)
			--print("illegal assignment to constant '"..tostring(b).."'")
		end
	end,
 
	__index = function(a,b) return data[b] end
}
setmetatable(const, const_mt)
Then to declare a "constant" all you have to do (in any file) is something like...
const.GLV_STATE_NOT_INIT  = 0
const.GLV_STATE_WAITING   = 1
const.GLV_STATE_DL_ERROR  = 2
const.GLV_STATE_DL_OK     = 3
 
const.GLV_STATE = {
	A = 1,
	B = 2,
	C = 3}
 
print(const.GLV_STATE.A)
You can read these values and use them as normal, however any attempts to change their value or redefine them will throw a runtime error.

NOTE : As in the examples above you can declare either single values or even tables of constants and have them so they can be edited - lua can be great sometimes! :)
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 (+4 / -0 )Share on Facebook

Comments

  • nice! I'm missing something like #define too, and my solution is mcpp http://www.guava7.com/2012/c-preprocessor-everywhere/

    however, I also use lua "constant" too ;)
  • @Rickyngk - That's a cool little tool - thanks for sharing the link.
    That's a perfect solution to hide all the little quirks that you often need when swapping from iOS to Android or iPhone to iPad.

    It would be cool if the preprocessor could actually get built into Gideros studio!
    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
  • @techdojo Nice share, I think I might be putting this to use soon. :)
    ThumbHurt Games / FB: ThumbHurt Games / FB: Eli/Teranth | Skype: teranth37
  • @techdojo

    nice, nice, nice ! :)

    thanks!
    TNT ENGiNE for Gideors Studio - Particle Engine, Virtual Pad, Animator Studio, Collision Engine - DOWNLOAD NOW !!! IT'S FREE!!! -
    www.tntengine.com
  • ar2rsawseenar2rsawseen Maintainer
    @GregBUG now you are exaggerating. It is nice, but not 3x3 times nice. Just nice, or 3xnice would have done the trick :)
  • @ar2rsawseen and @all
    sorry but it was not intentionally... really (i'm not a spammer)
    but when i clicked over "Post Comment" button in my preceding post the site says me "String could not be parsed as xml" ??? and do a triple post! ?

    and blocked me (as a spammer for 600 secs) :((
    a forum bug ?

    @gorkem: please delete my triple post!

    sorry. :((

    here is a screen...
    Schermata 07-2456129 alle 23.51.33.png
    708 x 173 - 28K
    TNT ENGiNE for Gideors Studio - Particle Engine, Virtual Pad, Animator Studio, Collision Engine - DOWNLOAD NOW !!! IT'S FREE!!! -
    www.tntengine.com
  • @GregBUG I have run into the same issue the last week or so, I was wondering if the forum had a bug as well. I get the same error message, and it often doesn't seem to post, if I hit the button again, sometimes it posts twice. Usually if I get that error, I copy my text and refresh the page and find that I already posted the text :( Weird stuff
    ThumbHurt Games / FB: ThumbHurt Games / FB: Eli/Teranth | Skype: teranth37
  • ar2rsawseenar2rsawseen Maintainer
    edited July 2012
    @GregBUG, don't worry, I'm just kidding. I had same issue yesterday. I simply wait for error message and reload the page, and check if post is posted. And usually it is.
    Since it uses AJAX to post, it probably sends info to server, and can't correctly parse server's xml response, but post is still posted to forum.

    It was probably a server maintenance or something like that.

    And don't delete your tripple post, or mine post won't make sense :)
  • gorkemgorkem Maintainer
    @ar2rsawseen deleting all @gregbug's posts and yours would make sense, but then I have to delete this and the previous post to make sense too, ohhh..

    Not sure about this forum issue. If you happen to bump into it more frequently, just let me know and I'll try to find a solution to it, by at least moving to a newer version (which I do not want in fact - "if it works, do not touch it")

    Likes: ar2rsawseen

    +1 -1 (+1 / -0 )Share on Facebook
  • @techdojo first my compliments for your code it's really useful,
    Maybe asking too much, do you have the solution apply this function for different tables?
    I proved to adapt your code without success:
    init.lua
     
    function createConstantVariable(const)
    	const = {}
    	local data = {} 
    	const_mt = {
    		__newindex = function(a,b,c)
    			if data[b] == nil then
    				if type(c) == 'table' then	-- make that table readonly
    					local proxy = {}
    					local mt = {       -- create metatable
    						__index = c,
    						__newindex = function (t,k,v)
    							error("Attempt to update read-only table '"..b.."' index '"..tostring(k).."' with '"..tostring(v).."'",2)
    							--print("Attempt to update read-only table '"..b.."' index '"..tostring(k).."' with '"..tostring(v).."'")
    						end
    					}
    					setmetatable(proxy, mt)
    					data[b]=proxy
    				else
    					data[b]=c
    				end
    			else
    				error("Illegal assignment to constant '"..tostring(b).."'",2)
    				--print("illegal assignment to constant '"..tostring(b).."'")
    			end
    		end,
     
    		__index = function(a,b) return data[b] end
    	}
    	setmetatable(const, const_mt)
    end
    in main.lua
    local MyEventList ={}
    createConstantVariable(MyEventList)
    MyEventList.ON_REPEAT ='onrepeat'	
    print(MyEventList.ON_REPEAT)
    MyEventList.ON_REPEAT = 'onrepeat_changed'
    print(MyEventList.ON_REPEAT)
  • ar2rsawseenar2rsawseen Maintainer
    @gaboritaly if you define const that way, then it's scope is only inside this function. But is should be a global object. Something like that could work:
    function createConstTable()
    	local const = {}
    	local data = {} 
    	local const_mt = {
    		__newindex = function(a,b,c)
    			if data[b] == nil then
    				if type(c) == 'table' then	-- make that table readonly
    					local proxy = {}
    					local mt = {       -- create metatable
    						__index = c,
    						__newindex = function (t,k,v)
    							error("Attempt to update read-only table '"..b.."' index '"..tostring(k).."' with '"..tostring(v).."'",2)
    							--print("Attempt to update read-only table '"..b.."' index '"..tostring(k).."' with '"..tostring(v).."'")
    						end
    					}
    					setmetatable(proxy, mt)
    					data[b]=proxy
    				else
    					data[b]=c
    				end
    			else
    				error("Illegal assignment to constant '"..tostring(b).."'",2)
    				--print("illegal assignment to constant '"..tostring(b).."'")
    			end
    		end,
     
    		__index = function(a,b) return data[b] end
    	}
    	setmetatable(const, const_mt)
    	return const
    end
    And could be used like that:
    myConstTable = createConstTable()
    Didn't test it though, all theoretically :D
  • wow great job thanks to be able to use something like #define.
  • @ar2rsawseen thanks a lot for the fast respond.
    I have this error
    attempt to call global 'createConstantVariable' (a nil value)
    stack traceback:
    Gideros has a error list when I can see what do you mean some errors ?

    Thanks a lot
  • @gaboritaly most likely you are trying to create a Constant Table before the code @ar2rsawseen provided has been included in your program.

    Did you put that function in init.lua before all the other code? (Or in a file you have set as a dependency of your main loading file?)

    I can't really tell more without seeing the actual context you are using the code in, but my guess is you need to make sure the function is defined before the code you are calling it in--which is usually why you get the error you mentioned.

    I would love to see an error list to, but most of the errors I have seen are LUA errors, and thus sort of generic themselves.
    ThumbHurt Games / FB: ThumbHurt Games / FB: Eli/Teranth | Skype: teranth37
  • ar2rsawseenar2rsawseen Maintainer
    @gaboritaly
    sorry, I renamed function,
    your function was called "createConstantVariable(const)"
    I didn't see it and named mine createConstTable, so if you have removed your function definition, you are still trying to call it somewhere in the code
  • Thank you guys, I didn't realized @ar2rsawseen renamed the function name :-O
    Now work really well!!! :)>-
Sign In or Register to comment.