]> git.mxchange.org Git - simgear.git/commitdiff
Canvas: clear event listeners on destroy
authorThomas Geymayer <tomgey@gmail.com>
Mon, 3 Jun 2013 21:39:11 +0000 (23:39 +0200)
committerThomas Geymayer <tomgey@gmail.com>
Mon, 3 Jun 2013 21:39:27 +0000 (23:39 +0200)
Removing all event listeneres on destroying a canvas
prevents circular references due to Nasal event listeners
keeping a reference to the canvas in their closure.

Also fix event handling with direct children of the root
group and add some more helpers to the Canvas.

simgear/canvas/Canvas.cxx
simgear/canvas/Canvas.hxx
simgear/canvas/CanvasEventManager.cxx
simgear/canvas/CanvasEventVisitor.cxx
simgear/canvas/elements/CanvasElement.cxx
simgear/canvas/elements/CanvasElement.hxx
simgear/canvas/elements/CanvasGroup.cxx
simgear/canvas/elements/CanvasGroup.hxx

index 4e4255575f68c0e32f7db6a3ea50278770002512..a124642c4e111110f880ec4df680d467950797d5 100644 (file)
@@ -114,6 +114,9 @@ namespace canvas
   //----------------------------------------------------------------------------
   void Canvas::destroy()
   {
+    if( _root_group )
+      _root_group->clearEventListener();
+
     // TODO check if really not in use anymore
     getProps()->getParent()
               ->removeChild( getProps()->getName(),
@@ -185,6 +188,16 @@ namespace canvas
     );
   }
 
+  //----------------------------------------------------------------------------
+  GroupPtr Canvas::getOrCreateGroup(const std::string& name)
+  {
+    GroupPtr group = getGroup(name);
+    if( group )
+      return group;
+
+    return createGroup(name);
+  }
+
   //----------------------------------------------------------------------------
   GroupPtr Canvas::getRootGroup()
   {
index 1d508a8912543c12c07901949cfbaeae6addd8bf..3504b46c9ce0f8f73d8c3cd07ae50bd5fcef32f2 100644 (file)
@@ -102,8 +102,25 @@ namespace canvas
       void removeParentCanvas(const CanvasWeakPtr& canvas);
       void removeChildCanvas(const CanvasWeakPtr& canvas);
 
+      /**
+       * Create a new group
+       */
       GroupPtr createGroup(const std::string& name = "");
+
+      /**
+       * Get an existing group with the given name
+       */
       GroupPtr getGroup(const std::string& name);
+
+      /**
+       * Get an existing group with the given name or otherwise create a new
+       * group
+       */
+      GroupPtr getOrCreateGroup(const std::string& name);
+
+      /**
+       * Get the root group of the canvas
+       */
       GroupPtr getRootGroup();
 
       /**
index 8801d84aad2a2a120c60beda0d33f1e838075e04..7a05a23ebe7253c0d1421aeb06c00666045fa5ed 100644 (file)
@@ -188,13 +188,12 @@ namespace canvas
     // http://www.w3.org/TR/DOM-Level-3-Events/#event-flow
 
     // Capturing phase
-//    for( EventTargets::iterator it = _target_path.begin();
-//                                it != _target_path.end();
-//                              ++it )
+//    for( EventPropagationPath::const_iterator it = path.begin();
+//                                              it != path.end();
+//                                            ++it )
 //    {
-//      if( it->element )
-//        std::cout << it->element->getProps()->getPath() << " "
-//                  << "(" << it->local_pos.x() << "|" << it->local_pos.y() << ")\n";
+//      if( !it->element.expired() )
+//        std::cout << it->element.lock()->getProps()->getPath() << std::endl;
 //    }
 
     // Bubbling phase
index d931f40b10be357cabe1cdfc46b33e23506f0c70..40d4e26b8a76f9a49290880fe6cc6e46b9e81827 100644 (file)
@@ -73,7 +73,7 @@ namespace canvas
       // Don't check collision with root element (2nd element in _target_path)
       // do event listeners attached to the canvas itself (its root group)
       // always get called even if no element has been hit.
-      if( _target_path.size() > 2 && !el.hitBound(pos, local_pos) )
+      if( _target_path.size() > 1 && !el.hitBound(pos, local_pos) )
         return false;
 
       const osg::Vec2f& delta = _target_path.back().local_delta;
index e581e5143e8d636b27b8826588ddcf0c5480ecd2..fcadfc66f783770a220d309e8bd3ea2871612b47 100644 (file)
@@ -179,6 +179,12 @@ namespace canvas
     return naNil();
   }
 
+  //----------------------------------------------------------------------------
+  void Element::clearEventListener()
+  {
+    _listener.clear();
+  }
+
   //----------------------------------------------------------------------------
   bool Element::accept(EventVisitor& visitor)
   {
@@ -220,15 +226,10 @@ namespace canvas
 
     // Drawables have a bounding box...
     if( _drawable )
-    {
-      if( !_drawable->getBound().contains(osg::Vec3f(local_pos, 0)) )
-        return false;
-    }
+      return _drawable->getBound().contains(osg::Vec3f(local_pos, 0));
     // ... for other elements, i.e. groups only a bounding sphere is available
-    else if( !_transform->getBound().contains(osg::Vec3f(pos, 0)) )
-        return false;
-
-    return true;
+    else
+      return _transform->getBound().contains(osg::Vec3f(pos, 0));
   }
 
   //----------------------------------------------------------------------------
index 146cd0d4a9887875d26be9446547cf5171511670..136fd5fc3a03ccd08faccbff5414500a406602a4 100644 (file)
@@ -85,6 +85,7 @@ namespace canvas
       virtual void update(double dt);
 
       naRef addEventListener(const nasal::CallContext& ctx);
+      virtual void clearEventListener();
 
       virtual bool accept(EventVisitor& visitor);
       virtual bool ascend(EventVisitor& visitor);
index 05e752a321cf921f6096cae9e4beb5580117b6db..b290fb0e0de5ddea41b6b92ca6352d269445a4b2 100644 (file)
@@ -133,6 +133,15 @@ namespace canvas
     return ElementPtr();
   }
 
+  //----------------------------------------------------------------------------
+  void Group::clearEventListener()
+  {
+    BOOST_FOREACH( ChildList::value_type child, _children )
+      child.second->clearEventListener();
+
+    Element::clearEventListener();
+  }
+
   //----------------------------------------------------------------------------
   void Group::update(double dt)
   {
index d1b86b7b92527ca220978095ae9c69b272c564a7..8a40eaaba814eeeb62b43fc1fcbf70359688dd0d 100644 (file)
@@ -57,6 +57,8 @@ namespace canvas
        */
       ElementPtr getElementById(const std::string& id);
 
+      virtual void clearEventListener();
+
       virtual void update(double dt);
 
       virtual bool traverse(EventVisitor& visitor);