Style/Structuring question: One vs. multiple global objects

Deewiant deewiant.doesnotlike.spam at
Mon Jul 2 06:59:23 PDT 2007

Henning Hasemann wrote:
> Deewiant <deewiant.doesnotlike.spam at> schrieb (Sun, 01 Jul 2007 
> 19:09:12 +0300):
>> I'd start with making sure "lots of modules need game" == false, to the 
>> point that no modules need game. IMHO if you have a kind of "god object" 
>> (or module, I don't write objects for such things), nobody should know 
>> about its existence. Just like real-life religion. ;-)
> Interesting strategy. But that would mean things like the main character had 
> to  be accessible in other ways, or?


struct GodObject {
	MainCharacter dude;

	void gameLoop() {

You get the idea. MainCharacter would be in its own module so if something needs
its definition, it can import that module, but the "dude" variable itself would
always be passed from GodObject.

>> If you're really that paranoid about globals (I see no reason to be), try 
>> to make something which contains only the external interfaces to your 
>> object and put it in a separate module.
> What exactly do you mean with external interface? The point is: the "game" 
> class would need to know about scenes, characters and so on. So it had to 
> import the proper modules. And, for example lots of modules deal somehow with
>  the current scene or the current main character so they had to import 
> game... Maybe you could give a simple code example of your strategy?

See above. Pass around the current main character if you have a "struct/class
Game", or define it as a global in maincharacter.d if you're willing to use globals.

>> A possible problem with the above is that you may end up with several very 
>> short modules which only contain a few globals. When it looks like this is 
>> happening, and I can't find a justifiable way of merging them, I tend to 
>> just create a "globals.d".
> That globals.d then would look like the following, describing the same 
> problem as game.d:
> import mylib.scene; import mylib.viewport; import mylib.character; //...
> // globals mylib.scene.Scene currentScene; mylib.viewport.Viewport viewport;
>  mylib.character.Character mainCharacter;

This is why I'd put such definitions in the modules their types are defined in,
in this case. Generally, it's the kind of types that don't need to import
anything else from the project are the ones that'd end up in a globals.d.

>> - Store Entity in Tile, and store x- and y-coordinates in Entity. They can 
>> then be used by modules higher up in the hierarchy to pull the Tile out 
>> from an array, or Map object, or whatever.
> You mean:
> class Tile {
> // ...
>  class Entity {
>   int x,y;
>  }
> }
> ? I guess you mean something different, but atm I just dont get it...

I mean:

class Tile {
	Entity standingOnThis;
Tile[] tiles;

// in other module...

class Entity {
	int x, y;

Then, with the above, we can do:

void getTileOfEntity(Entity e) {
	return tiles[e.y * MAP_WIDTH + e.x]; // or whatever

The downside is that you need some sort of "utility module" which imports both
Tile and Entity and defines getTileOfEntity. That, or put it in the same module
as Tile, which isn't exactly logical.

>> Hopefully this helps.
> Today at least a little. But I think if I sleep over it and look at it 
> tomorrow again it'll help more ;-)
> Thanks so far! Henning

Not a problem. If you can think of something, feel free to enlighten me, too.
I'd really like a general-purpose solution which doesn't involve all the kinds
of hacks we have to resort to now.

Remove ".doesnotlike.spam" from the mail address.

More information about the Digitalmars-d-learn mailing list