(We are currently getting a lot of aborts in the condition code when
running MP. I don't expect this to fix it, but a bug is a bug.)
(reviewed by Fred, who also fixed *my* bugs :-)
add optional arg to SGPropertyNode::addChangeListener that triggers
the listener function call initially. This is useful for cases where
a freshly installed listener wants to treat the current property
value as changed from 'unknown' to the actual value right away.
Examples can be found in the Nasal incarnation setlistener(),
where we have for example this (in $FG_ROOT/Nasal/gui.nas):
INIT = func {
...
setlistener("/sim/rendering/fps-display", fpsDisplay);
if (getprop("/sim/rendering/fps-display")) {
fgcommand("dialog-show", props.Node.new({"dialog-name": "fps"}));
}
}
That is: we first attach a listener that cares for changes to the FPS
display switch, but then we have to manually open the dialog initially.
That's a duplication of code and could be as simple as this
(INIT part only):
INIT = func {
...
setlistener("/sim/rendering/fps-display", fpsDisplay, 1);
}
That is: the optional third arg makes fpsDisplay be called initially,
and then again with every write action. My first solution was in the
Nasal code only, but Andy (rightfully) says that this should rather
be in sg.
The attached patch makes remove_child() available as removeChild(pos, keep).
That's consistent with getChild. Only renamed remove_child to removeChild and
added a check for validity of the pos argument.
removeChildren() will be used in input.cxx, and a lot in the upcoming
dynamic new_gui dialogs, which are aiming at replacing the hard-coded
dialogs. I'll discuss them on the list once the infrastructure is
in place. (The <hide> gui property was one part of it.)
This one, removes some virtual qualifiers at a private member class of
SGPropertyNode. These virtual qualifiers are really useless and stop the
compiler from inlineing these functions. I gain a single frame with my
favourite aircraft per second!
I have done a valgrind run in flightgear. Just start it up and close it at the
fist change I had about half an hour later.
property-leak.diff:
A leak in the property system which I could even notice in top.
texture-leak.diff:
minor one, but fixed is fixed ...
- check for isTied() and refcount has to be made *before* we go into
recursion, so as to pertain subtrees of refcounted nodes, even if there
are no refcounted/tied nodes *in* this tree
- return value inverted, because it's more logical to say
removeChildren() == true --> everything removed; false --> failed
- further cleanup
- introduce removeChildren() and removeChildren(name) to remove all children
or all with a given name
- let removeChild() and removeChildren() also remove child trees, and let them
return a "dirty" boolean that indicates if one or more subnodes had to be
kept because of refcounting (removeChild returned a SGPropertyNode_ptr before)
- make alias/unalias increase/decrease the refcounter
- don't remove refcounted or tied nodes
This patch makes the SGPropertyNode_ptr actually useful. Until today, they did
proper refcounting (except for aliases), but no other part did check this counter.
But SGPropertyNode_ptr aren't only useful for the first time, they are now
highly recommended for every place that relies on a node address, and wants
to "lock" it (so that removeChild(ren) will never try to remove them). This
is not guaranteed for SGPropertyNode* (and never was). Of course, that's not
an imminent problem, as only four places currently use removeChild(ren) and
these are careful to only remove their own data.
Vivian pointed out that a redefined Ctrl-U key binding didn't work
correctly. I found out that this is, because the definition in
$FG_ROOT/keyboard.xml sets <value type="bool"> for binding[1],
and ... [better sit down first!] ... and assigning <value type="double">
in a *-set.xml file doesn't *really* set "double" as new type!
Instead, the boolean is kept, and a double sqeezed into it. In other
words: once tainted as bool, you can throw all doubles in the universe
on a property node, and all it will accept is 0 and 1. Without warning!
BTW: I changed the patch: I was overly cautious: clear_value() does already
care for ties and for setting NONE, so we just need to make that public as
clearValue(), and use that. Makes the patch a bit more verbose, though. :-/
My recent fix for the load/save fgfs.sav feature was a bit too ambitious.
While aliases lead to abortion before, I tried to copy them properly,
although this wasn't a requirement. Unfortunately, this seems to have
worked for absolute aliases only, not for relative ones, and hence broke
several panel instruments. The attached patch backs most of the previous
patch out again, and goes a simpler route: just ignore aliases.
fgLoadFlight() loads a property file ("fgfs.sav") to a new property tree,
and then copies that over to the main tree. copyProperties() didn't know
how to handle type SGPropertyNode::ALIAS and hence threw an exception that
made fgfs abort.
The attached patch adds support for ALIAS to copyProperties(): aliased
nodes are created in the target tree if necessary, and then linked like in
the source tree. It seemed useful to add an optional argument to
props.[ch]xx/getType() that would indeed return the property type "ALIAS"
for aliased nodes, and not the type of the node that it refers to. The patch
also fixes a bug in writeNode() that caused extra lines after alias entries.
If there's resistance to the change to getType() (David?) I can easily use
isAlias(). This just makes copyProperties() a tad uglier, but I can live with
it. It's useful for scanning a tree, though, if an alias node can be treated
exactly like all other nodes, without automatic redirection.
I just discovered this : state() is not valid when _level==0,
because it is doing:
{ return _state_stack[_state_stack.size() - 1]; }
and is returning a wrong index fetch ( 0 - 1 ) == -1
Moreover, st is not used when _level==0 so the line can be moved
to a safer place.
to const/no-const variants of the prop->getNode() method, the 2nd bool
argument was getting promoted to an int so it would match a method with
a const SGPropertyNode * as the first argument. But that made
it match the wrong version of prop->getNode() and things were failing.
Yikes! This is one I could have stared at for days to figure out so I'm
glad I caught on to the problem. :-)
- Split out the condition code from fgfs/src/Main/fg_props and put it
in it's own source file in simgear/props/
- Created a scene subdirectory for scenery, model, and material property
related code.
- Moved location.[ch]xx into simgear/scene/model/
- The location and condition code had dependencies on flightgear's global
state (all the globals-> stuff, the flightgear property tree, etc.) SimGear
code can't depend on it so that data has to be passed as parameters to the
functions/methods/constructors.