]> git.mxchange.org Git - flightgear.git/commitdiff
- undefine PUCLASS_LIST, as we have our own (old_warning--)
authormfranz <mfranz>
Tue, 16 May 2006 12:45:38 +0000 (12:45 +0000)
committermfranz <mfranz>
Tue, 16 May 2006 12:45:38 +0000 (12:45 +0000)
- PropertyObject: remove additional "values" member again
- don't create entry lists for <list>, <select>, and <combo> at dialog
  creation and delete them on dialog close, but let a separate class
  fgValueList handle this. The three widgets are now subclassed and the
  derived widget lets fgValueList manage the lists
- make <select> consistent with <list>. This breaks backwards
  compatibility, but not a single dialog in fgfs uses it and did so
  since ... forever. (Shoot me!)

Rationale: now that dialogs are a bit more dynamic than they used to be
(thanks to embedded Nasal), we have to delete and recreate entry lists
during dialog use. Deleting only at dialog closing doesn't cut it anymore.
Especially list widgets that are updated several times per second would
use up a lot of memory otherwise. The route-manager doesn't update that
often, but it did already leak. One TODO less.  :-)

src/GUI/dialog.cxx
src/GUI/dialog.hxx

index a33dde1cecc70431b87b2066c21798fb0a0b69a3..803346588dc561d72b99537864cbf26eca7e005d 100644 (file)
@@ -6,15 +6,12 @@
 
 #include <stdlib.h>            // atof()
 
-#include <plib/puAux.h>
-
 #include <Input/input.hxx>
 #include <Scripting/NasalSys.hxx>
 
 #include "dialog.hxx"
 #include "new_gui.hxx"
 
-#include "puList.hxx"
 #include "AirportList.hxx"
 #include "layout.hxx"
 
@@ -49,6 +46,7 @@ GUIInfo::~GUIInfo ()
     }
 }
 
+
 \f
 /**
  * Key handler.
@@ -360,13 +358,6 @@ FGDialog::~FGDialog ()
     puDeleteObject(_object);
 
     unsigned int i;
-                                // Delete all the arrays we made
-                                // and were forced to keep around
-                                // because PUI won't do its own
-                                // memory management.
-    for (i = 0; i < _char_arrays.size(); i++)
-        destroy_char_array(_char_arrays[i]);
-
                                 // Delete all the info objects we
                                 // were forced to keep around because
                                 // PUI cannot delete its own user data.
@@ -393,10 +384,10 @@ FGDialog::updateValues (const char * objectName)
             continue;
 
         puObject *obj = _propertyObjects[i]->object;
-        SGPropertyNode *values = _propertyObjects[i]->values;
-        if (obj->getType() & PUCLASS_LIST && values)
-            ((puList *)obj)->newList(value_list(values));
-        else
+        if (obj->getType() & PUCLASS_LIST) {
+            fgList *pl = static_cast<fgList *>(obj);
+            pl->update();
+        else
             copy_to_pui(_propertyObjects[i]->node, obj);
     }
 }
@@ -551,9 +542,8 @@ FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
         return obj;
 
     } else if (type == "list") {
-        char ** entries = value_list(props);
         int slider_width = props->getIntValue("slider", 20);
-        puList * obj = new puList(x, y, x + width, y + height, entries, slider_width);
+        fgList * obj = new fgList(x, y, x + width, y + height, props, slider_width);
         if (presetSize)
             obj->setSize(width, height);
         setupObject(obj, props);
@@ -622,8 +612,7 @@ FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
         return obj;
 
     } else if (type == "combo") {
-        char ** entries = value_list(props);
-        puaComboBox * obj = new puaComboBox(x, y, x + width, y + height, entries,
+        fgComboBox * obj = new fgComboBox(x, y, x + width, y + height, props,
                            props->getBoolValue("editable", false));
         setupObject(obj, props);
 #ifdef PUCOL_EDITFIELD  // plib > 0.8.4
@@ -672,19 +661,7 @@ FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
         return obj;
 
     } else if (type == "select") {
-        vector<SGPropertyNode_ptr> value_nodes;
-        SGPropertyNode * selection_node =
-                fgGetNode(props->getChild("selection")->getStringValue(), true);
-
-        for (int q = 0; q < selection_node->nChildren(); q++)
-            value_nodes.push_back(selection_node->getChild(q));
-
-        char ** entries = make_char_array(value_nodes.size());
-        for (unsigned int i = 0; i < value_nodes.size(); i++)
-            entries[i] = strdup((char *)value_nodes[i]->getName());
-
-        puaSelectBox * obj =
-            new puaSelectBox(x, y, x + width, y + height, entries);
+        fgSelectBox * obj = new fgSelectBox(x, y, x + width, y + height, props);
         setupObject(obj, props);
 #ifdef PUCOL_EDITFIELD  // plib > 0.8.4
         setColor(obj, props, EDITFIELD);
@@ -728,8 +705,7 @@ FGDialog::setupObject (puObject * object, SGPropertyNode * props)
         SGPropertyNode_ptr node = fgGetNode(propname, true);
         copy_to_pui(node, object);
 
-        SGPropertyNode * values = type == "list" ? props : 0;
-        PropertyObject* po = new PropertyObject(name, object, node, values);
+        PropertyObject* po = new PropertyObject(name, object, node);
         _propertyObjects.push_back(po);
         if(props->getBoolValue("live"))
             _liveObjects.push_back(po);
@@ -934,50 +910,74 @@ FGDialog::getKeyCode(const char *str)
     return key;
 }
 
-char **
-FGDialog::value_list (const SGPropertyNode *props)
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGDialog::PropertyObject.
+////////////////////////////////////////////////////////////////////////
+
+FGDialog::PropertyObject::PropertyObject (const char * n,
+                                           puObject * o,
+                                           SGPropertyNode_ptr p)
+    : name(n),
+      object(o),
+      node(p)
 {
-    vector<SGPropertyNode_ptr> value_nodes = props->getChildren("value");
-    char ** entries = make_char_array(value_nodes.size());
-    for (unsigned int i = 0; i < value_nodes.size(); i++)
-        entries[i] = strdup((char *)value_nodes[i]->getStringValue());
-    return entries;
 }
 
-char **
-FGDialog::make_char_array (int size)
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of fgList and derived pui widgets
+////////////////////////////////////////////////////////////////////////
+
+
+fgValueList::fgValueList(SGPropertyNode *p) :
+    _props(p)
 {
-    char ** list = new char*[size+1];
-    for (int i = 0; i <= size; i++)
-        list[i] = 0;
-    _char_arrays.push_back(list);
-    return list;
+    make_list();
 }
 
 void
-FGDialog::destroy_char_array (char ** array)
+fgValueList::update()
 {
-    for (int i = 0; array[i] != 0; i++)
-        if (array[i])
-            free(array[i]);// added with strdup
-    delete[] array;
+    destroy_list();
+    make_list();
 }
 
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of FGDialog::PropertyObject.
-////////////////////////////////////////////////////////////////////////
+fgValueList::~fgValueList()
+{
+    destroy_list();
+}
 
-FGDialog::PropertyObject::PropertyObject (const char * n,
-                                           puObject * o,
-                                           SGPropertyNode_ptr p,
-                                           SGPropertyNode_ptr v)
-    : name(n),
-      object(o),
-      node(p),
-      values(v)
+void
+fgValueList::make_list()
+{
+    vector<SGPropertyNode_ptr> value_nodes = _props->getChildren("value");
+    _list = new char *[value_nodes.size() + 1];
+    unsigned int i;
+    for (i = 0; i < value_nodes.size(); i++)
+        _list[i] = strdup((char *)value_nodes[i]->getStringValue());
+    _list[i] = 0;
+}
+
+void
+fgValueList::destroy_list()
 {
+    for (int i = 0; _list[i] != 0; i++)
+        if (_list[i])
+            free(_list[i]);
+    delete[] _list;
 }
 
 
+
+void
+fgList::update()
+{
+    fgValueList::update();
+    newList(_list);
+}
+
 // end of dialog.cxx
index 65c010395f069d25d5ca03e306300f86fd398cb1..f30f3cf22da7d627ee1666bedb8767a1783d27ff 100644 (file)
@@ -7,13 +7,16 @@
 # error This library requires C++
 #endif
 
-#include <plib/pu.h>
+#include <plib/puAux.h>
 #include <plib/sg.h>
 
 #include <simgear/compiler.h>  // for SG_USING_STD
 #include <simgear/props/props.hxx>
 #include <simgear/misc/sg_path.hxx>
 
+#undef PUCLASS_LIST
+#include "puList.hxx"
+
 #include <vector>
 SG_USING_STD(vector);
 
@@ -141,30 +144,18 @@ private:
     // PUI provides no way for userdata to be deleted automatically
     // with a GUI object, so we have to keep track of all the special
     // data we allocated and then free it manually when the dialog
-    // closes. "values" is a node with "value" children and only used
-    // by the <list> widget.
+    // closes.
     vector<void *> _info;
     struct PropertyObject {
         PropertyObject (const char * name,
                         puObject * object,
-                        SGPropertyNode_ptr node,
-                        SGPropertyNode_ptr values = 0);
+                        SGPropertyNode_ptr node);
         string name;
         puObject * object;
         SGPropertyNode_ptr node;
-        SGPropertyNode_ptr values;
     };
     vector<PropertyObject *> _propertyObjects;
     vector<PropertyObject *> _liveObjects;
-
-    // PUI doesn't copy arrays, so we have to allocate string arrays
-    // and then keep pointers so that we can delete them when the
-    // dialog closes. value_list() builds such a list from "value"
-    // children.
-    char ** make_char_array (int size);
-    char ** value_list(const SGPropertyNode * prop);
-    void destroy_char_array (char **array);
-    vector<char **> _char_arrays;
 };
 
 //
@@ -191,4 +182,40 @@ private:
     int _dX, _dY;
 };
 
+
+class fgValueList {
+public:
+    fgValueList(SGPropertyNode *p);
+    virtual ~fgValueList();
+    virtual void update();
+
+protected:
+    char **_list;
+
+private:
+    void make_list();
+    void destroy_list();
+    SGPropertyNode_ptr _props;
+};
+
+
+class fgList : public fgValueList, public puList {
+public:
+    fgList(int x1, int y1, int x2, int y2, SGPropertyNode *p, int sw) :
+        fgValueList(p), puList(x1, y1, x2, y2, _list, sw) {}
+    virtual void update();
+};
+
+class fgComboBox : public fgValueList, public puaComboBox {
+public:
+    fgComboBox(int x1, int y1, int x2, int y2, SGPropertyNode *p, bool editable) :
+        fgValueList(p), puaComboBox(x1, y1, x2, y2, _list, editable) {}
+};
+
+class fgSelectBox : public fgValueList, public puaSelectBox {
+public:
+    fgSelectBox(int x1, int y1, int x2, int y2, SGPropertyNode *p) :
+        fgValueList(p), puaSelectBox(x1, y1, x2, y2, _list) {}
+};
+
 #endif // __DIALOG_HXX