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 ()
|
FGMenuBar::~FGMenuBar ()
|
||||||
{
|
{
|
||||||
hide();
|
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
|
// Delete all those bindings
|
||||||
map<string,vector<FGBinding *> >::iterator it;
|
map<string,vector<FGBinding *> >::iterator it;
|
||||||
|
@ -340,10 +357,10 @@ FGMenuBar::make_menu (SGPropertyNode_ptr node)
|
||||||
const char * name = strdup(node->getStringValue("label"));
|
const char * name = strdup(node->getStringValue("label"));
|
||||||
vector<SGPropertyNode_ptr> item_nodes = node->getChildren("item");
|
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];
|
char ** items = make_char_array(array_size);
|
||||||
puCallback * callbacks = new puCallback[array_size];
|
puCallback * callbacks = make_callback_array(array_size);
|
||||||
|
|
||||||
for (int i = 0, j = item_nodes.size() - 1;
|
for (int i = 0, j = item_nodes.size() - 1;
|
||||||
i < item_nodes.size();
|
i < item_nodes.size();
|
||||||
|
@ -361,9 +378,6 @@ FGMenuBar::make_menu (SGPropertyNode_ptr node)
|
||||||
_bindings[items[j]].push_back(new FGBinding(binding_nodes[k]));
|
_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);
|
_menuBar->add_submenu(name, items, callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,4 +399,24 @@ FGMenuBar::make_menubar ()
|
||||||
_menuBar->hide();
|
_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
|
// end of menubar.cxx
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// menubar.hxx - XML-configured menu bar.
|
||||||
|
|
||||||
#ifndef __MENUBAR_HXX
|
#ifndef __MENUBAR_HXX
|
||||||
#define __MENUBAR_HXX 1
|
#define __MENUBAR_HXX 1
|
||||||
|
|
||||||
|
@ -23,6 +25,14 @@ class FGBinding;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XML-configured PUI menu bar.
|
* 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
|
class FGMenuBar
|
||||||
{
|
{
|
||||||
|
@ -77,12 +87,29 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
// Make a single menu.
|
||||||
void make_menu (SGPropertyNode_ptr node);
|
void make_menu (SGPropertyNode_ptr node);
|
||||||
|
|
||||||
|
// Make the top-level menubar.
|
||||||
void make_menubar ();
|
void make_menubar ();
|
||||||
|
|
||||||
|
// Is the menu visible?
|
||||||
bool _visible;
|
bool _visible;
|
||||||
|
|
||||||
|
// The top-level menubar itself.
|
||||||
puMenuBar * _menuBar;
|
puMenuBar * _menuBar;
|
||||||
|
|
||||||
|
// A map of bindings for the menubar.
|
||||||
map<string,vector<FGBinding *> > _bindings;
|
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
|
#endif // __MENUBAR_HXX
|
||||||
|
|
Loading…
Add table
Reference in a new issue