redesign some piece of code

Started by
8 comments, last by fir 10 years, 7 months ago

(I wrote it in other topic in the context of topic why are global variables bad, but I would change the context of it and just ask how to redesign some piece of my code, so please let me post it here as a question of how to redesign it - maybe I will met some advices - though I am not sure if redesigning it is easy)

I got a global shared Sleep value (in miliseconds) which is used in the winapi dispatch messages loop

It is used yet in my some keyboard handlers module so Icould +- it from keayboard (to incrase/decrease fps and corresponding cpu usage)

I can not clearly decide where this variable should belong
to my keyboard handler module or to dispatch messages loop (?) I placed it yet in the third place in globals as far as I remember.

This 3 places is already a mess for me - it become yet worse becouse I had a system of including and excluding some game modules to my system and in such module sometimes I like to overvrite such Sleep value for debug purposes locally, set it 5 in one module to 15 in other I am working on (other way I would must find a global sleep initialisation and change it there so it it is yet worse)

As described above such global shared Sleep is an example of such global shared variable that brings a trouble (As I said before not all globals make such troble, some of them never do for me really and those troubles are more related to way of treating some globals not to all of them )

So how would someone resolve such (global shared) Sleep trouble ?

Advertisement

The amount of sleeping belongs with the sleeper, in your case the main loop that processes or ignores events.

Changing it with keyboard commands shouldn't be different from other commands: the keyboard handler can respect encapsulation and pass "sleep more" or "sleep less" messages to the engine (presumably calling the appropriate functions) without knowing the current amount of sleeping.

Omae Wa Mou Shindeiru

LorenzoGatti already said what I wanted to say after reading the question.

In general (in my opinion) you can have a look at who is reading the variables value and who is setting it. In this example it's clearly visible: the message dispatching loop reads the value so the loop loops in the preferred ratio and all other components (the input handler) are setting/adjusting the value. The input handler has to read the value though, but thats due to the lack of an "add" method so it's just a value setting. (This still is a very simple example and there may could come some more difficult cases...)
Since there is only 1 place where the variabels value matters this is the true place for the variable. The other places should be able to adjust it using the mentioned functions/methods "sleep more" and "sleep less", or "do it faster" and "slow down". If there are more components which needs exactly this value it would be more complicated to determine the right place...

LorenzoGatti already said what I wanted to say after reading the question.

In general (in my opinion) you can have a look at who is reading the variables value and who is setting it. In this example it's clearly visible: the message dispatching loop reads the value so the loop loops in the preferred ratio and all other components (the input handler) are setting/adjusting the value. The input handler has to read the value though, but thats due to the lack of an "add" method so it's just a value setting. (This still is a very simple example and there may could come some more difficult cases...)
Since there is only 1 place where the variabels value matters this is the true place for the variable. The other places should be able to adjust it using the mentioned functions/methods "sleep more" and "sleep less", or "do it faster" and "slow down". If there are more components which needs exactly this value it would be more complicated to determine the right place...

Its mainly +/- from some keyboard handling module and mainly used in the loop

. - but there began to appear some additional settings of it

(as I said when working with some modules i was overwriting its initialisation value this concrete module would like, [modules are in exclusive relation (at compile time) this is i can have 7 modules but only one is in use at a compile time but each one overwrite sleep at startup to value it is okay with that - so it is third reference (this overwriting is better I think then rewritting oryginal initialisation with hand every time I change module))]

then it was also read to display its value on the screen (hud) for debug purposes (fourth reference to sleep)

maybe with time it could be even referenced more

- So it became a small mess like a spider legs of references- just to reach such small int value

- and I am something like really not happy with that - searching if there is some way of clearing/redesign that

I tried to summarize this in an as general way as possible, but deciding where to put the properties depends on what you're trying to do.

The DebugSystem oder HUDManager or whatever you call the part for displaying doesn't contain a "loop sleep time" property.
Imagine you would not have to use the game loop and you still would have to draw the HUD and debug messages (e. g. a model viewer or dialog editor or whatever). There still would be a HUDManager and a DebugSystem.
Imagine you decided not to use any HUD in your game and it's done so the DebugSystem isn't necessary anymore. You still would have to use the loop and know the sleep time.
In this case and in my opinion it's obvious (after thinking about this) the sleep time is a property of the game loop thing.

But you may also could still end up with at least 2 classes and both should contain a specific value, object, or list of values or objects. An example: every object within your game has a sprite and you need all sprites in the "DrawingStuffManager". In my opinion it's caused by a bad design and in this case the game objects should contain their sprites. When it comes to drawing the scene you could call the environments/levels/worlds "draw" Method which itself calls the game objects "draw" method so there is no need for a central sprite drawing class or it could be passed as parameter to the draw methods.

In general speaking: when trying to remove global variables you have to think about who is the true owner of this variables ("whose property is this?").

I tried to summarize this in an as general way as possible, but deciding where to put the properties depends on what you're trying to do.

The DebugSystem oder HUDManager or whatever you call

I call it something like Assistant / DebugAssistant but also had some trouble with it (It is how to manage it clearly).

I tried to summarize this in an as general way as possible, but deciding where to put the properties depends on what you're trying to do.

The DebugSystem oder HUDManager or whatever you call

the part for displaying doesn't contain a "loop sleep time" property.Imagine you would not have to use the game loop and you still would have to draw the HUD and debug messages (e. g. a model viewer or dialog editor or whatever). There still would be a HUDManager and a DebugSystem.
Imagine you decided not to use any HUD in your game and it's done so the DebugSystem isn't necessary anymore. You still would have to use the loop and know the sleep time.
In this case and in my opinion it's obvious (after thinking about this) the sleep time is a property of the game loop thing.

But you may also could still end up with at least 2 classes and both should contain a specific value, object, or list of values or objects. An example: every object within your game has a sprite and you need all sprites in the "DrawingStuffManager". In my opinion it's caused by a bad design and in this case the game objects should contain their sprites. When it comes to drawing the scene you could call the environments/levels/worlds "draw" Method which itself calls the game objects "draw" method so there is no need for a central sprite drawing class or it could be passed as parameter to the draw methods.

In general speaking: when trying to remove global variables you have to think about who is the true owner of this variables ("whose property is this?").

I agree that Sleep variable should probably belong to loop module, (this is window module)

The thing that worries me is that I need to spread a reference to it over a couple of modules

(it may be not clearly described reference it just my be acces through Sleep name from many parts of code - some 'transparent' references just like reaching the globals, but still they are references)

this is some kind of something like small reference explosion I would like to awoid.

step back and start with the fundamentals

what is sleep?

what does it do?

if its giving you implementation fits, ti may be an inherently ugly design choice.

instead of merely re-factoring, you might consider re-engineering.

"Everything becomes easy once you resort to customization."

Sometimes there is a different way.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

step back and start with the fundamentals

what is sleep?

what does it do?

if its giving you implementation fits, ti may be an inherently ugly design choice.

instead of merely re-factoring, you might consider re-engineering.

"Everything becomes easy once you resort to customization."

Sometimes there is a different way.

I got not much idea how to rediesign it - but as i said I see vaguely that there is some problem with that.

Recently i began to think If I could maybe write small api to IncreaseSleep DecreaseSleep GetSleep SetSleep (?) in the window module - it will change some point from the reference spider side to code flow - accessin api call such

as IncreaseDleep is more narrow reference than accessing variable, so it may be more clear in conceptual.

I also think that this trouble with such Sleep integer is maybe related to that fact that Sleep has no physical value - the physical value has sleep() call not Sleep value which is only some kind of a temporary value and accessing with that value from different spots is more just an opportunity to spoil the code than anything else

We got a code containing & references plane and code flow plane in the code, i prefer to see things on code flow plane because there are much simpler (this is more seeable) but i am getting lost yet in some places of it


I got a global shared Sleep value (in miliseconds) which is used in the winapi dispatch messages loop

how specifically?

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php


I got a global shared Sleep value (in miliseconds) which is used in the winapi dispatch messages loop

how specifically?

Got something like








 
WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR commandline_,int nCmdShow)
{
 hinstance = hInstance;
 commandline = commandline_;

 AppSetup();

 for(;;)
 {
  IdleLoop();
  if(!MessagePump()) break;
 }

 AppCloseUp();

 LOG("\nClosing app OK");
 return (int) msg.wParam;
}

and at the end of IdleLoop() I got








void IdleLoop()
{
 //........
 
 if(sleepVal>0) SleepEx(sleepVal, 1);
}

I am working on prototypes by now, heard about that that

sleep can be quantized sometimes and setting it by something like

  timeBeginPeriod(2000);

is not considered good because of some reason, but now i am working on prototypes only and do not bother much about it because it works ok , could improve it later in some other way. Would you improve it ?

This topic is closed to new replies.

Advertisement