Canvas: use weak pointer to protect parent element access.
Using a weak pointer is the best way to ensure no invalid pointer is used. This also fixes a possible crash in simgear::canvas::Element::getParentStyle on destructing canvas elements.
This commit is contained in:
@@ -207,19 +207,6 @@ namespace canvas
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
Element::~Element()
|
Element::~Element()
|
||||||
{
|
{
|
||||||
if( !_transform.valid() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < _transform->getNumChildren(); ++i)
|
|
||||||
{
|
|
||||||
OSGUserData* ud =
|
|
||||||
static_cast<OSGUserData*>(_transform->getChild(i)->getUserData());
|
|
||||||
|
|
||||||
if( ud )
|
|
||||||
// Ensure parent is cleared to prevent accessing released memory if an
|
|
||||||
// element somehow survives longer than his parent.
|
|
||||||
ud->element->_parent = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -246,7 +233,7 @@ namespace canvas
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
ElementPtr Element::getParent() const
|
ElementPtr Element::getParent() const
|
||||||
{
|
{
|
||||||
return _parent;
|
return _parent.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -324,8 +311,9 @@ namespace canvas
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool Element::ascend(EventVisitor& visitor)
|
bool Element::ascend(EventVisitor& visitor)
|
||||||
{
|
{
|
||||||
if( _parent )
|
ElementPtr parent = getParent();
|
||||||
return _parent->accept(visitor);
|
if( parent )
|
||||||
|
return parent->accept(visitor);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,9 +362,9 @@ namespace canvas
|
|||||||
EventPropagationPath path;
|
EventPropagationPath path;
|
||||||
path.push_back( EventTarget(this) );
|
path.push_back( EventTarget(this) );
|
||||||
|
|
||||||
for( Element* parent = _parent;
|
for( ElementPtr parent = getParent();
|
||||||
parent != NULL;
|
parent.valid();
|
||||||
parent = parent->_parent )
|
parent = parent->getParent() )
|
||||||
path.push_front( EventTarget(parent) );
|
path.push_front( EventTarget(parent) );
|
||||||
|
|
||||||
CanvasPtr canvas = _canvas.lock();
|
CanvasPtr canvas = _canvas.lock();
|
||||||
@@ -772,7 +760,7 @@ namespace canvas
|
|||||||
Element::Element( const CanvasWeakPtr& canvas,
|
Element::Element( const CanvasWeakPtr& canvas,
|
||||||
const SGPropertyNode_ptr& node,
|
const SGPropertyNode_ptr& node,
|
||||||
const Style& parent_style,
|
const Style& parent_style,
|
||||||
Element* parent ):
|
ElementWeakPtr parent ):
|
||||||
PropertyBasedElement(node),
|
PropertyBasedElement(node),
|
||||||
_canvas( canvas ),
|
_canvas( canvas ),
|
||||||
_parent( parent ),
|
_parent( parent ),
|
||||||
@@ -871,11 +859,12 @@ namespace canvas
|
|||||||
Element::getParentStyle(const SGPropertyNode* child) const
|
Element::getParentStyle(const SGPropertyNode* child) const
|
||||||
{
|
{
|
||||||
// Try to get value from parent...
|
// Try to get value from parent...
|
||||||
if( _parent )
|
ElementPtr parent = getParent();
|
||||||
|
if( parent )
|
||||||
{
|
{
|
||||||
Style::const_iterator style =
|
Style::const_iterator style =
|
||||||
_parent->_style.find(child->getNameString());
|
parent->_style.find(child->getNameString());
|
||||||
if( style != _parent->_style.end() )
|
if( style != parent->_style.end() )
|
||||||
return style->second;
|
return style->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -232,8 +232,8 @@ namespace canvas
|
|||||||
|
|
||||||
class RelativeScissor;
|
class RelativeScissor;
|
||||||
|
|
||||||
CanvasWeakPtr _canvas;
|
CanvasWeakPtr _canvas;
|
||||||
Element *_parent;
|
ElementWeakPtr _parent;
|
||||||
|
|
||||||
mutable uint32_t _attributes_dirty;
|
mutable uint32_t _attributes_dirty;
|
||||||
|
|
||||||
@@ -256,7 +256,7 @@ namespace canvas
|
|||||||
Element( const CanvasWeakPtr& canvas,
|
Element( const CanvasWeakPtr& canvas,
|
||||||
const SGPropertyNode_ptr& node,
|
const SGPropertyNode_ptr& node,
|
||||||
const Style& parent_style,
|
const Style& parent_style,
|
||||||
Element* parent );
|
ElementWeakPtr parent );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns false on first call and true on any successive call. Use to
|
* Returns false on first call and true on any successive call. Use to
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ namespace canvas
|
|||||||
Group::Group( const CanvasWeakPtr& canvas,
|
Group::Group( const CanvasWeakPtr& canvas,
|
||||||
const SGPropertyNode_ptr& node,
|
const SGPropertyNode_ptr& node,
|
||||||
const Style& parent_style,
|
const Style& parent_style,
|
||||||
Element* parent ):
|
ElementWeakPtr parent ):
|
||||||
Element(canvas, node, parent_style, parent)
|
Element(canvas, node, parent_style, parent)
|
||||||
{
|
{
|
||||||
staticInit();
|
staticInit();
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace canvas
|
|||||||
Group( const CanvasWeakPtr& canvas,
|
Group( const CanvasWeakPtr& canvas,
|
||||||
const SGPropertyNode_ptr& node,
|
const SGPropertyNode_ptr& node,
|
||||||
const Style& parent_style = Style(),
|
const Style& parent_style = Style(),
|
||||||
Element* parent = 0 );
|
ElementWeakPtr parent = 0 );
|
||||||
virtual ~Group();
|
virtual ~Group();
|
||||||
|
|
||||||
ElementPtr createChild( const std::string& type,
|
ElementPtr createChild( const std::string& type,
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ namespace canvas
|
|||||||
Image::Image( const CanvasWeakPtr& canvas,
|
Image::Image( const CanvasWeakPtr& canvas,
|
||||||
const SGPropertyNode_ptr& node,
|
const SGPropertyNode_ptr& node,
|
||||||
const Style& parent_style,
|
const Style& parent_style,
|
||||||
Element* parent ):
|
ElementWeakPtr parent ):
|
||||||
Element(canvas, node, parent_style, parent),
|
Element(canvas, node, parent_style, parent),
|
||||||
_texture(new osg::Texture2D),
|
_texture(new osg::Texture2D),
|
||||||
_node_src_rect( node->getNode("source", 0, true) ),
|
_node_src_rect( node->getNode("source", 0, true) ),
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace canvas
|
|||||||
Image( const CanvasWeakPtr& canvas,
|
Image( const CanvasWeakPtr& canvas,
|
||||||
const SGPropertyNode_ptr& node,
|
const SGPropertyNode_ptr& node,
|
||||||
const Style& parent_style = Style(),
|
const Style& parent_style = Style(),
|
||||||
Element* parent = 0 );
|
ElementWeakPtr parent = 0 );
|
||||||
virtual ~Image();
|
virtual ~Image();
|
||||||
|
|
||||||
virtual void update(double dt);
|
virtual void update(double dt);
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ namespace canvas
|
|||||||
Map::Map( const CanvasWeakPtr& canvas,
|
Map::Map( const CanvasWeakPtr& canvas,
|
||||||
const SGPropertyNode_ptr& node,
|
const SGPropertyNode_ptr& node,
|
||||||
const Style& parent_style,
|
const Style& parent_style,
|
||||||
Element* parent ):
|
ElementWeakPtr parent ):
|
||||||
Group(canvas, node, parent_style, parent),
|
Group(canvas, node, parent_style, parent),
|
||||||
// TODO make projection configurable
|
// TODO make projection configurable
|
||||||
_projection(new SansonFlamsteedProjection),
|
_projection(new SansonFlamsteedProjection),
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace canvas
|
|||||||
Map( const CanvasWeakPtr& canvas,
|
Map( const CanvasWeakPtr& canvas,
|
||||||
const SGPropertyNode_ptr& node,
|
const SGPropertyNode_ptr& node,
|
||||||
const Style& parent_style,
|
const Style& parent_style,
|
||||||
Element* parent = 0 );
|
ElementWeakPtr parent = 0 );
|
||||||
virtual ~Map();
|
virtual ~Map();
|
||||||
|
|
||||||
virtual void update(double dt);
|
virtual void update(double dt);
|
||||||
|
|||||||
@@ -531,7 +531,7 @@ namespace canvas
|
|||||||
Path::Path( const CanvasWeakPtr& canvas,
|
Path::Path( const CanvasWeakPtr& canvas,
|
||||||
const SGPropertyNode_ptr& node,
|
const SGPropertyNode_ptr& node,
|
||||||
const Style& parent_style,
|
const Style& parent_style,
|
||||||
Element* parent ):
|
ElementWeakPtr parent ):
|
||||||
Element(canvas, node, parent_style, parent),
|
Element(canvas, node, parent_style, parent),
|
||||||
_path( new PathDrawable(this) )
|
_path( new PathDrawable(this) )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace canvas
|
|||||||
Path( const CanvasWeakPtr& canvas,
|
Path( const CanvasWeakPtr& canvas,
|
||||||
const SGPropertyNode_ptr& node,
|
const SGPropertyNode_ptr& node,
|
||||||
const Style& parent_style,
|
const Style& parent_style,
|
||||||
Element* parent = 0 );
|
ElementWeakPtr parent = 0 );
|
||||||
virtual ~Path();
|
virtual ~Path();
|
||||||
|
|
||||||
virtual void update(double dt);
|
virtual void update(double dt);
|
||||||
|
|||||||
@@ -740,7 +740,7 @@ namespace canvas
|
|||||||
Text::Text( const CanvasWeakPtr& canvas,
|
Text::Text( const CanvasWeakPtr& canvas,
|
||||||
const SGPropertyNode_ptr& node,
|
const SGPropertyNode_ptr& node,
|
||||||
const Style& parent_style,
|
const Style& parent_style,
|
||||||
Element* parent ):
|
ElementWeakPtr parent ):
|
||||||
Element(canvas, node, parent_style, parent),
|
Element(canvas, node, parent_style, parent),
|
||||||
_text( new Text::TextOSG(this) )
|
_text( new Text::TextOSG(this) )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace canvas
|
|||||||
Text( const CanvasWeakPtr& canvas,
|
Text( const CanvasWeakPtr& canvas,
|
||||||
const SGPropertyNode_ptr& node,
|
const SGPropertyNode_ptr& node,
|
||||||
const Style& parent_style,
|
const Style& parent_style,
|
||||||
Element* parent = 0 );
|
ElementWeakPtr parent = 0 );
|
||||||
~Text();
|
~Text();
|
||||||
|
|
||||||
void setText(const char* text);
|
void setText(const char* text);
|
||||||
|
|||||||
Reference in New Issue
Block a user