Here is the somewhat off-topic portion of the CVS Commit Info thread, that is now it's own thread. Let's try to keep this on-topic; it's fairly important.
While I was [making recent changes], I made some notes that everyone should read about problems I found in the existing code:
I removed the redundant DestroyChild() calls in the dtor of FleetWindow. GG::Wnds do this automatically.
I changed this :
Code:
< //de-initialize
< if(m_orders)
< delete(m_orders);
< m_orders = 0;
<
to this:
Code:
> delete m_orders;
There are several things wrong with the above code:
1) The comment is redundant; you don't need to tell someone that deleting stuff in a destructor is "de-initialization", it's obvious. Also, the term "de-initialize" is awkward.
2) Checking for non-null m_orders does nothing. Deleting a null pointer is a no-op.
3) This is the destructor. No one will ever access m_orders again, since this entire object is being destroyed. So the m_orders = 0 assignment is redundant.
I completely rewrote GalaxySetupWnd. Notable problems with it were:
1) It defined internal enums that mirrored enums elsewhere for galaxy size and shape. This could create hard-to-find version problems between the different enums.
2) Two constants "GALAXY_TYPES" and "TYPE_ROW_HEIGHT" were created as static members of this class. Unless there is a real need to expose these outside of the class (such as to subclasses or the public), these should be local variables in an anonymous namespace in the implementation file.
3) The types of the pointers in the class were not forward declared. This:
Code:
< #ifndef _GGWnd_h_
< #include "GGWnd.h"
< #endif
<
< #ifndef _GGEdit_h_
< #include "GGEdit.h"
< #endif
<
< #ifndef _GGButton_h_
< #include "GGButton.h"
< #endif
<
< #ifndef _GGStaticGraphic_h_
< #include "GGStaticGraphic.h"
< #endif
became this:
Code:
> #ifndef _ClientUniverse_h_
> #include "../universe/ClientUniverse.h"
> #endif
25a15,23
> namespace GG {
> class RadioButtonGroup;
> class StaticGraphic;
> class Texture;
> }
> class CUIButton;
> class CUIEdit;
> class CUIStateButton;
This allows the compiler to skip all the code in the #included files untill it reaches the .cpp file, where they are actually included. This reduces header dependencies and greatly reduces compile time.
4) The XMLEncode() method did not detach the children for which the class maintains explicit pointers. Then the method XMLEncode()ed each such child. But since these children were still attached, they were written to the XML file twice: once as children of GG::Wnd, and once as data members of GalaxySetupWnd.
Commented-out code has been left all over the place. Demo code as well. Please don't leave this stuff lying around for other people to have to read. Use #if 0 ... #endif to remove code that you might want to reactivate later, or for code that only you want to demo for yourself. Better yet, make a local copy for yourself and don't use the repository for scratch paper.
A Universe search predicate IsSystem() was defined locally in a couple of different .cpp files. One of them was called ServerIsSystem(), probably because it conflicted with the IsSystem() declared elsewhere. The way to make something truly local to the .cpp file it is in is to put it in an anonymous namespace:
Code:
namespace {
void foo() {}
}
this is equivalent to:
Code:
namespace UNIQUE_IDENTIFIER {
void foo() {}
}
using namespace UNIQUE_IDENTIFIER;
that is, it allows the definition of a namespace that is accessible only within the current file, since the unique identifier is omitted and the namespace is therefore unavailable by name in other files. Better yet, IsSystem() and other prediacates belong in a separate compilation unit. I have created a Predicates.h file for this purpose. If you add any non-trivial prediactes declare them there and define them in Predicates.cpp (which you'll have to create).
In SystemIcon, there was a GG::Texture pointer that held a heap-allocated texture loaded from file. This means that if there were 100 red dwarfs, there were 100 copies of the red dwarf texture taking up space. GG has a Texture manager to deal with this. SystemIcon now uses GG::App::GetTexture() to get
copies of its Textures.
I found a member variable in ServerApp called m_temp. Let's not and say we did, ok?
This was in ClientUniverse.h:
Code:
< #define HOMEWORLD_PROXIMITY_LIMIT_V_SMALL_UNI 3
< #define HOMEWORLD_PROXIMITY_LIMIT_SMALL_UNI 4
< #define HOMEWORLD_PROXIMITY_LIMIT_MEDIUM_UNI 5
< #define HOMEWORLD_PROXIMITY_LIMIT_LARGE_UNI 5
< #define HOMEWORLD_PROXIMITY_LIMIT_V_LARGE_UNI 5
< #define HOMEWORLD_PROXIMITY_LIMIT_ENORMOUS_UNI 6
I almost cried. How about not #defining things that could just as easily been declared const int.
ClientUniverse.cpp was every
other
line! Please be careful not to commit files like this. Do a cvs diff on EVERY file before you commit it, so you can write a good description of the changes in the commit, and so you can spot gaffes like this. I do this, even when I'm committing 39 files like I am tonight.
In MapWnd's constructor, there was a line that said something like const ClientUniverse cu = BLAH. This does two things that are morally wrong. One, it copies a huge object for no reason, since it is catching the object in an object and not a reference. Two, when the object cu goes out of scope at the end of the constructor, it is destroyed, just like any automatic object would be at the end of any function. Except that this object contains several hundred pointers to the same number of objects, and it has a destructor that cleans them up when the object is destroyed. So once I populated the Universe, creating a MapWnd in which to view it
DESTROYED ITS CONTENTS! I have spent the better part of 2 days trying to find this bug. This is the problem with leaving hastily written demo code in the repository for others to trip over.
I don't want anyone to get excited by this post. I'm a little frustrated, but I'm not trying to attack anyone (names have been omitted to protect the guilty). I'm posting this like this so that maybe people can see what is wrong and fix it, either in their code already committed, or in code they write later.