]> git.mxchange.org Git - flightgear.git/commitdiff
Reset: panel-node cleans up listener.
authorJames Turner <zakalawe@mac.com>
Sun, 10 Nov 2013 20:32:00 +0000 (12:32 -0800)
committerJames Turner <zakalawe@mac.com>
Tue, 12 Nov 2013 22:51:15 +0000 (22:51 +0000)
Also get rid of the global FGPanelNode pointer.

src/Model/panelnode.cxx
src/Model/panelnode.hxx

index 9e664b4c71eaf58f667a3fbeab7f37fa031a2543..1194a45127f9b00b3aee085327fb0c28b95767b0 100644 (file)
@@ -43,30 +43,18 @@ private:
     FGPanelNode* _panelNode;
 };
 
-static FGPanelNode* global_panel = NULL;
-
-/**
- * Built-in command: pass a mouse click to the panel.
- *
- * button: the mouse button number, zero-based.
- * is-down: true if the button is down, false if it is up.
- * x-pos: the x position of the mouse click.
- * y-pos: the y position of the mouse click.
- */
-static bool
-do_panel_mouse_click (const SGPropertyNode * arg)
+class PanelPathListener : public SGPropertyChangeListener
 {
-  if (global_panel)
-    return global_panel->getPanel()
-    ->doMouseAction(arg->getIntValue("button"),
-                    arg->getBoolValue("is-down") ? PU_DOWN : PU_UP,
-                    arg->getIntValue("x-pos"),
-                    arg->getIntValue("y-pos"));
-  else
-    return false;
-  
-  return false;
-}
+public:
+    PanelPathListener(FGPanelNode* pn) : _panelNode(pn) {}
+    
+    virtual void valueChanged (SGPropertyNode * node)
+    {
+        _panelNode->setPanelPath(node->getStringValue());
+    }
+private:
+    FGPanelNode* _panelNode;
+};
 
 class FGPanelPickCallback : public SGPickCallback {
 public:
@@ -138,12 +126,14 @@ public:
   
 private:
   FGPanelNode* panel;
-  SGPropertyNode* visProp;
+  SGPropertyNode_ptr visProp;
 };
 
 
 FGPanelNode::FGPanelNode(SGPropertyNode* props) :
-  _resizeToViewport(false)
+    _is2d(false),
+    _resizeToViewport(false),
+    _listener(NULL)
 {  
   commonInit();
   _panelPath = props->getStringValue("path");
@@ -168,22 +158,47 @@ FGPanelNode::FGPanelNode(SGPropertyNode* props) :
 }
 
 FGPanelNode::FGPanelNode() :
+    _is2d(true),
   _resizeToViewport(true),
   _depthTest(false)
 {
+    SGCommandMgr::instance()->addCommand("panel-mouse-click", this, &FGPanelNode::panelMouseClickCommand);
+
+    SGPropertyNode* pathNode = fgGetNode("/sim/panel/path");
+    _pathListener.reset(new PanelPathListener(this));
+    pathNode->addChangeListener(_pathListener.get());
+    setPanelPath(pathNode->getStringValue());
+    
     // for a 2D panel, various options adjust the transformation
     // matrix. We need to pass this data on to OSG or its bounding box
     // will be stale, and picking will break.
     // http://code.google.com/p/flightgear-bugs/issues/detail?id=864
-    PanelTransformListener* ptl = new PanelTransformListener(this);
-    fgGetNode("/sim/panel/x-offset", true)->addChangeListener(ptl);
-    fgGetNode("/sim/panel/y-offset", true)->addChangeListener(ptl);
-    fgGetNode("/sim/startup/xsize", true)->addChangeListener(ptl);
-    fgGetNode("/sim/startup/ysize", true)->addChangeListener(ptl);
+    _listener = new PanelTransformListener(this);
+    fgGetNode("/sim/panel/x-offset", true)->addChangeListener(_listener);
+    fgGetNode("/sim/panel/y-offset", true)->addChangeListener(_listener);
+    fgGetNode("/sim/startup/xsize", true)->addChangeListener(_listener);
+    fgGetNode("/sim/startup/ysize", true)->addChangeListener(_listener);
     
     commonInit();
 }
 
+FGPanelNode::~FGPanelNode()
+{
+    if (_is2d) {
+        SGCommandMgr::instance()->removeCommand("panel-mouse-click");
+        SGPropertyNode* pathNode = fgGetNode("/sim/panel/path");
+        pathNode->removeChangeListener(_pathListener.get());
+    }
+    
+    if (_listener) {
+        fgGetNode("/sim/panel/x-offset", true)->removeChangeListener(_listener);
+        fgGetNode("/sim/panel/y-offset", true)->removeChangeListener(_listener);
+        fgGetNode("/sim/startup/xsize", true)->removeChangeListener(_listener);
+        fgGetNode("/sim/startup/ysize", true)->removeChangeListener(_listener);
+        delete _listener;
+    }
+}
+
 void FGPanelNode::setPanelPath(const std::string& panel)
 {
   if (panel == _panelPath) {
@@ -264,10 +279,6 @@ void FGPanelNode::initWithPanel()
   dirtyBound();
 }
 
-FGPanelNode::~FGPanelNode()
-{
-}
-
 osg::Matrix FGPanelNode::transformMatrix() const
 {
   if (!_panel) {
@@ -374,33 +385,9 @@ static osg::Node* createGeode(FGPanelNode* panel)
     return geode;
 }
 
-class PanelPathListener : public SGPropertyChangeListener
-{
-public:
-  PanelPathListener(FGPanelNode* pn) : _panelNode(pn) {}
-  
-  virtual void valueChanged (SGPropertyNode * node)
-  {
-    _panelNode->setPanelPath(node->getStringValue());
-  }
-private:
-  FGPanelNode* _panelNode;
-};
-
-
 osg::Node* FGPanelNode::create2DPanelNode()
 {
-  SGCommandMgr::instance()->addCommand("panel-mouse-click", do_panel_mouse_click);
-  
-  SGPropertyNode* pathNode = fgGetNode("/sim/panel/path");
-  
-  FGPanelNode* drawable = new FGPanelNode();
-// need a global to keep the panel_mouse_click command working, sadly
-  global_panel = drawable;
-  
-  PanelPathListener* ppo = new PanelPathListener(drawable);
-  pathNode->addChangeListener(ppo);
-  drawable->setPanelPath(pathNode->getStringValue());
+  FGPanelNode* drawable = new FGPanelNode;
     
   osg::Switch* ps = new osg::Switch;
   osg::StateSet* stateSet = ps->getOrCreateStateSet();
@@ -424,3 +411,20 @@ osg::Node* FGPanelNode::load(SGPropertyNode *n)
   drawable->lazyLoad(); // force load now for 2.5D panels
   return createGeode(drawable);
 }
+
+/**
+ * Built-in command: pass a mouse click to the panel.
+ *
+ * button: the mouse button number, zero-based.
+ * is-down: true if the button is down, false if it is up.
+ * x-pos: the x position of the mouse click.
+ * y-pos: the y position of the mouse click.
+ */
+bool
+FGPanelNode::panelMouseClickCommand(const SGPropertyNode * arg)
+{
+    return _panel->doMouseAction(arg->getIntValue("button"),
+                         arg->getBoolValue("is-down") ? PU_DOWN : PU_UP,
+                         arg->getIntValue("x-pos"),
+                         arg->getIntValue("y-pos"));
+}
index 772ef9e328194c447a7a0b68f9ba196c2d9c4a25..9d9a7c836679ab565c841b741e04bbe7d90d45ee 100644 (file)
@@ -5,6 +5,7 @@
 #include <osg/Matrix>
 #include <osg/Drawable>
 
+#include <memory>
 #include <simgear/structure/SGSharedPtr.hxx>
 #include <simgear/props/props.hxx>
 
@@ -15,9 +16,7 @@ class SGPropertyNode;
 
 class FGPanelNode : public osg::Drawable
 {
-public:
-    FGPanelNode();
-  
+public:  
     FGPanelNode(SGPropertyNode* props);
     virtual ~FGPanelNode();
 
@@ -51,9 +50,14 @@ public:
       */
     bool isVisible2d() const;
 private:
+    FGPanelNode(); // for 2D panels
+    
     void commonInit();
     void initWithPanel();
     
+    bool panelMouseClickCommand(const SGPropertyNode * arg);
+    
+    const bool _is2d;
     SGSharedPtr<FGPanel> _panel;
     std::string _panelPath;
   
@@ -69,6 +73,9 @@ private:
     // coordinates into 3D coordinates of the panel quadrilateral.
     osg::Matrix _xform;  
   
+    SGPropertyChangeListener* _listener;
+    std::auto_ptr<SGPropertyChangeListener> _pathListener;
+    
     /// should the 2D panel auto-hide when the view orientation changes
     mutable SGPropertyNode_ptr _autoHide2d;