Fix memory leaks (PUI doesn't make copies of lists, so we have to make
our own copies and keep pointers to them).
This commit is contained in:
parent
4dc28f11f4
commit
123931834f
2 changed files with 68 additions and 7 deletions
|
@ -279,7 +279,24 @@ FGMenuBar::FGMenuBar ()
|
|||
FGMenuBar::~FGMenuBar ()
|
||||
{
|
||||
hide();
|
||||
delete _menuBar; // FIXME: check if PUI owns the pointer
|
||||
puDeleteObject(_menuBar);
|
||||
|
||||
int i;
|
||||
|
||||
// Delete all the character arrays
|
||||
// we were forced to keep around for
|
||||
// plib.
|
||||
for (i = 0; i < _char_arrays.size(); i++) {
|
||||
for (int j = 0; _char_arrays[i][j] != 0; j++)
|
||||
free(_char_arrays[i][j]); // added with strdup
|
||||
delete _char_arrays[i];
|
||||
}
|
||||
|
||||
// Delete all the callback arrays
|
||||
// we were forced to keep around for
|
||||
// plib.
|
||||
for (i = 0; i < _callback_arrays.size(); i++)
|
||||
delete _callback_arrays[i];
|
||||
|
||||
// Delete all those bindings
|
||||
map<string,vector<FGBinding *> >::iterator it;
|
||||
|
@ -340,10 +357,10 @@ FGMenuBar::make_menu (SGPropertyNode_ptr node)
|
|||
const char * name = strdup(node->getStringValue("label"));
|
||||
vector<SGPropertyNode_ptr> item_nodes = node->getChildren("item");
|
||||
|
||||
int array_size = item_nodes.size() + 1;
|
||||
int array_size = item_nodes.size();
|
||||
|
||||
char ** items = new char*[array_size];
|
||||
puCallback * callbacks = new puCallback[array_size];
|
||||
char ** items = make_char_array(array_size);
|
||||
puCallback * callbacks = make_callback_array(array_size);
|
||||
|
||||
for (int i = 0, j = item_nodes.size() - 1;
|
||||
i < item_nodes.size();
|
||||
|
@ -361,9 +378,6 @@ FGMenuBar::make_menu (SGPropertyNode_ptr node)
|
|||
_bindings[items[j]].push_back(new FGBinding(binding_nodes[k]));
|
||||
}
|
||||
|
||||
items[item_nodes.size()] = 0;
|
||||
callbacks[item_nodes.size()] = 0;
|
||||
|
||||
_menuBar->add_submenu(name, items, callbacks);
|
||||
}
|
||||
|
||||
|
@ -385,4 +399,24 @@ FGMenuBar::make_menubar ()
|
|||
_menuBar->hide();
|
||||
}
|
||||
|
||||
char **
|
||||
FGMenuBar::make_char_array (int size)
|
||||
{
|
||||
char ** list = new char*[size+1];
|
||||
for (int i = 0; i <= size; i++)
|
||||
list[i] = 0;
|
||||
_char_arrays.push_back(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
puCallback *
|
||||
FGMenuBar::make_callback_array (int size)
|
||||
{
|
||||
puCallback * list = new puCallback[size+1];
|
||||
for (int i = 0; i <= size; i++)
|
||||
list[i] = 0;
|
||||
_callback_arrays.push_back(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
// end of menubar.cxx
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// menubar.hxx - XML-configured menu bar.
|
||||
|
||||
#ifndef __MENUBAR_HXX
|
||||
#define __MENUBAR_HXX 1
|
||||
|
||||
|
@ -23,6 +25,14 @@ class FGBinding;
|
|||
|
||||
/**
|
||||
* XML-configured PUI menu bar.
|
||||
*
|
||||
* This class creates a menu bar from a tree of XML properties. These
|
||||
* properties are not part of the main FlightGear property tree, but
|
||||
* are read from a separate file ($FG_ROOT/gui/menubar.xml).
|
||||
*
|
||||
* WARNING: because PUI provides no easy way to attach user data to a
|
||||
* menu item, all menu item strings must be unique; otherwise, this
|
||||
* class will always use the first binding with any given name.
|
||||
*/
|
||||
class FGMenuBar
|
||||
{
|
||||
|
@ -77,12 +87,29 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
// Make a single menu.
|
||||
void make_menu (SGPropertyNode_ptr node);
|
||||
|
||||
// Make the top-level menubar.
|
||||
void make_menubar ();
|
||||
|
||||
// Is the menu visible?
|
||||
bool _visible;
|
||||
|
||||
// The top-level menubar itself.
|
||||
puMenuBar * _menuBar;
|
||||
|
||||
// A map of bindings for the menubar.
|
||||
map<string,vector<FGBinding *> > _bindings;
|
||||
|
||||
// These are hoops that we have to jump through because PUI doesn't
|
||||
// do memory management for lists. We have to allocate the arrays,
|
||||
// hang onto pointers, and then delete them when the menubar is
|
||||
// freed.
|
||||
char ** make_char_array (int size);
|
||||
puCallback * make_callback_array (int size);
|
||||
vector<char **> _char_arrays;
|
||||
vector<puCallback *> _callback_arrays;
|
||||
};
|
||||
|
||||
#endif // __MENUBAR_HXX
|
||||
|
|
Loading…
Reference in a new issue