Here are some changes that gave me a significant frame rate increase of about 10 fps with random objects disabled. The interesting thing is that these changes aren't in the main loop but are in tile loader. My guess is that I've reduced the memory footprint just enough to reduce CPU cache misses, though I have no hard evidence of this.
Initially I modified all SGBinObject member functions to pass/return by reference instead of by-value. This gives little or no speed up but allows for some optimizations in fgBinObjLoad(). It is these changes that reduce the number of memory allocations. Needless copying of vectors, and vectors of vectors, can be very memory intensive, especially if they are large.
Anyway I would be interested to see if you get similar results. I would emphasize that the frame rate increase only occurs with random objects disabled. I lose about 10-15 fps on my GF2MX 32MB with random objects, probably a fill-rate limitation or texture memory thing.
not honoured after the first call. This isn't all that efficient, and
the return type probably should change to string eventually, but this
fix avoids changing the headers for now.
result, so after the first call for any node, it simply tests and
returns a pointer. This also fixes the problem of buffer conflicts
with make_string.
Added SGPropertyNode::hasChild(const char * name, int index = 0) to
provide a syntactically-cleaner way to test for the existence of a
child node, i.e.
for (int i = 0; i < 9; i++) {
if (node->hasChild("foo", i))
foo[i] = node->getChild("foo", i)->getDoubleValue();
}
While investigating, I found that SGPropertyNode::getPath returns a
(char *) pointer to the character data of a string on its stack,
i.e. to undefined memory after it returns. I remember someone was
changing strings to char* for efficiency. Perhaps this bug was
introduced then. I'll include a patch for it with my eventual patch
for the above, unless someone beats me to it. I don't think it
affects any existing callers: they all want a string anyway.
Initialise a "possibly uninitialised" variable (which was already
functionally correct).
[Note from DPM: this patch will be blown away if we ever update to a
newer version of Expat.]
Remove a hack that originally worked around a buffer overflow
elsewhere in the file. The buffer overflow was fixed long ago, but
the hack was not removed.
I have modified the SGPropertyNode interface to support node removal
and address the issues you mention yesterday.
I added the SGPropertyNode_ptr class that is a smart pointer that
increment and decrement a counter in SGPropertyNode. The _children
vector is changed to a vector<SGPropertyNode_ptr> in order for the
node to hold a reference to its children. I also added a
_removedChildren vector of the same type. When removeChild is called
with the keep parameter set to true, the reference is removed from
_children and inserted in _removedChildren, and the attribute REMOVED
is set. When getChild is called with create set to true, the _children
vector is searched, then the _removedChildren and then a new node is
created. If a resurrected node is returned, the REMOVED bit is cleared.
The static const int LAST_USED_ATTRIBUTE is also added.
The footprint of this patch is light. SGPropertyNode is one int
longer in size, SGPropertyNode_ptr is one pointer large without
virtual functions. Some functions can be inlined if your current
policy change.
The FlightGear patch is to take account the change in the getChildren
function that now returns a vector<SGPropertyNode_ptr>. If the
removeChild functionnality is to be added in FlightGear, all those
SGPropertyNode * floating around should be changed to
SGPropertyNode_ptr.
Here's a first cut at SGSocket reimplemented using plib.net. I've
maintained the same TCP server behaviour, that is only one client
connection at a time. I don't think it is possible within the current
framework to handle simultaneous clients.
I've also added two simple test programs, tcp_client and tcp_server.
Here is a total rewrite of the strutils package. I've reimplemented the
trimleft(), trimright() and trim() functions as lstrip(), rstrip() and
strip() respectively. Additionally I've added a split() function that
behaves like its perl/python equivalent. Just the thing for splitting
comma separated option strings or space separated telnet commands and
arguments. I've also enclosed the whole thing in a namespace
simgear::strutils. Since I seem to be the only one who uses these
functions, SimGear and FlightGear compile without change.
PS It is no coincidence that the new function names bear an uncanny
resemblance to the python functions of the same name.
Tbis is a first patch in a series to clean up SimGear by removing
warning messages. Most of them are straight forwared, but in pops.hxx
the compile complaints about "type qualifier is meaningless on return
type". I think it's up to you to decide if you want that part applied.