Use of Globals

BlitzMax Forums/BlitzMax Beginners Area/Use of Globals

pc_tek(Posted 2011) [#1]
I have seen many topics on the use of Globals, and the general law is NOT to use them where possible.

If that is the case how can I use a graphics font within 2 or more functions without declaring the graphic as a Global? Wouldn't that mean loading the graphic at the start of each function?


ima747(Posted 2011) [#2]
You could pass the graphic into the functions... or if the "functions" are actually methods of an object, the object could store the graphic in a field...

Globals are slower than fields or locals, not usually a big problem however. Generally globals should be avoided because if something is a global the general rule of thumb is the problem is likely your structure that requires it to be global in the first place...

You may well end up with globals in the real world, but again, the fewer you have you're more likely to have "better" structure. Better meaning more portable, easier to debug, easier to track program flow, likely more optimized and therefore more likely faster etc.

Here's a possibly applicable conceptual example related to a font:
Program loads
Game is told to start playing
Game loads level and resources (map, graphics, sounds, font etc.) and stores them in a "current level" object which (for laziness might be global, but optimally should be within the context of the current game loop, or handed to the current game loop)
Function is called that needs a font, so the font from the level resources object is handed to that function. The advantage here is that you can take that function and pop it into another game 6 months from now and all you have to do it hand it a font and whatever other input it needs and huza, re-used code, hours saved, etc.

Hope that helps


Czar Flavius(Posted 2011) [#3]
Something like fonts I would use as globals. Ignore the angry mob, it's just not worth setting up a whole font management system just to have a couple of fonts to choose from. If you're making a text editor with billions of fonts that would be a different story.

Globals are slower than locals, but I think fields are slower than globals, to put the perfomance "penalty" into perspective. Globals are slower because the compiler must check their value every time you read from them, in case something somewhere else has modified them (as they are globals). The compiler can optimize out many reads of locals when their value doesn't change as it knows nothing unexpected will happen to them. Fields fall into the former catagory, as your object could be referenced (and changed by) things outside of the function. Plus, there is an extra pointer dereference to access the field.


Htbaa(Posted 2011) [#4]
An alternative to the Globals for assets is a Asset Loader with some sort of Cache. That way you can eliminate Globals for assets.

But if the game has limited assets, I wouldn't even bother and just stick to Globals. But that's me.


CS_TBL(Posted 2011) [#5]
The problem with globals are two-fold: namespace and huge issues when all of a sudden you still want multiple instances of that global - and often enough you don't yet know this when you've just typed your first 500 lines o' code.

If you are sure that a certain something is used only once in your whole program, and it has a really unique name, then you could use a global. Something like PI is a global too. If you have a name like 'gamefont'.. well, I can't imagine some other place where I'd need this word for something else, so something like this would be ok.

It would be bad if you have Player:timage as a global. First: player may be a word you want to use for something else too (preferably as an object that contains your timage among other things!), in another context. And secondly: all of a sudden you've decided to make a two-player mode, separate viewports next to each other and your player all of a sudden needs to become an array of two. Happy Search&Replace&PullYourHairshOut then.

Personally I'd create a global object containing all these global variables. That way only this object instance is the only global in your namespace. The rest is carefully tucked away in it. Like:

----

Type Gameglobals
Field gamefont=LoadFont(..)
Field refreshrate=30
Field graphicswidth=640
Field graphicsheight=480
Field graphicsmode=1 ' 0 windowed, 1 fullscreen
' etc,
End Type

Global MyGameGlobals:Gameglobals=New Gameglobals

----

Every object and function anywhere in your game can access these Fields, while the only global you've wasted is MyGameGlobals.. the chance of a namespace collision is probably zero dot zero.

Last edited 2011


ima747(Posted 2011) [#6]
to re-address this, I often end up with fonts as globals OR a global font manager object (that handles loading caching, drawing etc.) but I do this out of lazyness (real world vs. "optimal"... time is a factor that gets ignored when planning an optimal development path...).

If you have a single font, and you draw it from multiple places, and it will never change, it's just your game font then I would *usually* slap it in a global and move on... but if there's a chance you will want to change font, or use multiple fonts, or you're talking about something less generic like an entity graphic, etc. etc. then you will save a lot of heart ache by planning out a better system...

So real world, only talking about a (singular) font, I would probably go with a global to save time. But just about anything else needs more thought and planning so try not to make it a habit... or maybe use this as a first pass towards better planning and see if you can find a way to NOT use a global so when you really need to not use a global you know what you're doing...


Czar Flavius(Posted 2011) [#7]
Here is a good idea. Have a global TMap called fonts_library, and store your fonts with a string key for their name. Then you can access them anywhere easily, and add as many new fonts as you like, with only one global name.


pc_tek(Posted 2011) [#8]
So...to recap, Globals slow down compilation time? But not runtime?


H&K(Posted 2011) [#9]
If you use them, use them. Better not to. But programming the why you can is better than not programming the way you cannot.

If that is the case how can I use a graphics font within 2 or more functions without declaring the graphic as a Global? Wouldn't that mean loading the graphic at the start of each function?

This is not a "Answer that is always right", but...
If I have two functions that need access to the same variable, and said variable only exists once. I would make the Functions member functions of a type, and the "Variable" a global field of that type

Oh, and runtime is possibley going to be slower.

Last edited 2011


Czar Flavius(Posted 2011) [#10]
They don't slow down compilation time. They negligibly slow down run-time. When I said "the compiler must check this, that.." what I meant was, the code that the compiler generates must do this, that.


pc_tek(Posted 2011) [#11]
Magic word...Neglibly. Thanks for the information guys.