Advertisement

My programming style

Started by April 26, 2013 05:47 AM
42 comments, last by jpetrie 11 years, 6 months ago
I think abbreviations are good as long as there are no name conflicts. After all, deque is an abbreviation. And the whole sockaddr struct is made of cryptic abbrevations. In my code I reuse the same abbreviations in dozens of functions and when they conflict (like player, powerline, pipeline) I use something a bit longer like pow, pipe. And it's perfectly readable. I got tired of writing so many utility functions that reuse the same variables that I started using single letter names. I reserve the full names ('player', 'unit', 'entity' etc.) for the associated integer ID index into the array.

hwx and hwz are the half-length of the bounding box on the x and z axises. checkPass is needed to specify if we want to check for collisions with pass-through units. I made labourers and trucks pass-through to speed up pathfinding where collision checks have to be done at each step of the path. I want to check for collisions with pass-through units though when they are spawned around the building that produced them. isUnit is needed because the function is also called when selecting a location to construct new buildings. Both checkPass and isUnit have to be true for it to check for collisions with pass-through units. thisU and "ignore" are needed because the function is used in pathfinding and the target might be the location of another unit, when attacking or when going to drive a truck.

I declare variables outside of loops because I have a superstition that the CPU will waste extra cycles reallocating the variable on each iteration of the loop.

The full code can be found at https://github.com/polyf/corpstates

I use the 'CClassName' convention because GameTutorials.com used it.

I declare variables outside of loops because I have a superstition that the CPU will waste extra cycles reallocating the variable on each iteration of the loop.

Even if this was the case - it isn't - allocating a variable on the stack essentially consists of incrementing the stack pointer. It costs nothing.

Write your code for other people, not for the computer. It's the compiler's job to make your stuff run fast and you can optimize later if it's not doing a good job. But superstitions like these are often unfounded and lead to unusual idioms which can make the code difficult to follow.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

Advertisement


void UpdateAI()
{
  for(int i = 0; i < PlayerList.size(); ++i)
  {
    if(!PlayerList.IsAlive || !PlayerList.IsAi) {
      continue;
    }
    UpdateAI(PlayerList);
  }
}
 
void UpdateAI(TPlayer& aiPlayer);

why the continue? Why the checks with ! ??? Why not the proper for (auto& player : playerList) ? And even better, if we really need to have a function that updates only one player (and I really feel we don't) why are the rules to call it expressed OUTSIDE? It should be as simple as calling a std::for_each(begin(playerList), end(playerList), UpdateAI) and then do the simple rule check INSIDE that if (player.IsActive && player.IsAI) { do your things} .. this opens the door to parallelism.. on Windows replace std:: with parallel:: and you're multithread.. and it's 3 lines of code! .. no dumb "!" to mess up your logic, no continue to early exit a loop.. it doesnt make sense at ALL! I code what I DO when a certain condition is met, thinking "right I don't do something and continue the loop if a couple of not conditions are true" is really on the edge of insanity.. it really is.

Should I continue? pun intended tongue.png ... do we need an UpdateAI ? do we need a IsAI? Chances are that there is also an Update somewhere for !IsAI players.. what ever happened to polymorphism???? A Player (please no CPlayer sad.png ) class with a virtual Update method and a PlayerAI class that overrides that Update..

for (auto player : playerList) player->Update();

It's 1 line of code!

Stefano Casillo
TWITTER: [twitter]KunosStefano[/twitter]
AssettoCorsa - netKar PRO - Kunos Simulazioni

I use the 'CClassName' convention because GameTutorials.com used it.

Holy Jeezbus! People still use that site?! I thought it died after the 90s!

Beginner in Game Development?  Read here. And read here.

 

kunos, what you wrote was too complex for me. And if I use polymorphism and make a PlayerAI class I can't have it in the same global array.

Holy Jeezbus! People still use that site?! I thought it died after the 90s!


That's where I learned how to use Quake 3 BSP maps. Don't know any other good sources.
Advertisement

kunos, what you wrote was too complex for me. And if I use polymorphism and make a PlayerAI class I can't have it in the same global array.

You shouldn't be using arrays of objects in the first place - use an array of pointers to objects (or better yet a vector of pointers). And it probably shouldn't be a global array, either.

If I use an array/vector of pointers how do I hold pointers of different inherited classes? And, yes, it HAS to be global. That's just plain retarded.

If I use an array/vector of pointers how do I hold pointers of different inherited classes?

By using pointers to their common base class. Take a look here and here to get a better understanding of inheritance and polymorphism.

I declare variables outside of loops because I have a superstition that the CPU will waste extra cycles reallocating the variable on each iteration of the loop.

This is something you need to get out of your head real fast. Instead of superstition you need to make decisions based on fact, and use tools available to you to inform yourself about what that fact is. In this case, reading documentation, viewing disassembly and running benchmarks would soon enough tell you the truth.

Right now you're voodoo-optimizing, you're pre-emptively optimizing, you're trying to second-guess the compiler, you're assuming that the C++ you write is going to generate a line-for-line equivalent when compiled, and it's not even based on anything more solid than "superstition". That can only lead to worse and worse habits over time, so cure yourself of it now before it does real damage to you.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement