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:
parent
3bfd0c872a
commit
00a20409f7
@ -207,19 +207,6 @@ namespace canvas
|
||||
//----------------------------------------------------------------------------
|
||||
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
|
||||
{
|
||||
return _parent;
|
||||
return _parent.lock();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -324,8 +311,9 @@ namespace canvas
|
||||
//----------------------------------------------------------------------------
|
||||
bool Element::ascend(EventVisitor& visitor)
|
||||
{
|
||||
if( _parent )
|
||||
return _parent->accept(visitor);
|
||||
ElementPtr parent = getParent();
|
||||
if( parent )
|
||||
return parent->accept(visitor);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -374,9 +362,9 @@ namespace canvas
|
||||
EventPropagationPath path;
|
||||
path.push_back( EventTarget(this) );
|
||||
|
||||
for( Element* parent = _parent;
|
||||
parent != NULL;
|
||||
parent = parent->_parent )
|
||||
for( ElementPtr parent = getParent();
|
||||
parent.valid();
|
||||
parent = parent->getParent() )
|
||||
path.push_front( EventTarget(parent) );
|
||||
|
||||
CanvasPtr canvas = _canvas.lock();
|
||||
@ -772,7 +760,7 @@ namespace canvas
|
||||
Element::Element( const CanvasWeakPtr& canvas,
|
||||
const SGPropertyNode_ptr& node,
|
||||
const Style& parent_style,
|
||||
Element* parent ):
|
||||
ElementWeakPtr parent ):
|
||||
PropertyBasedElement(node),
|
||||
_canvas( canvas ),
|
||||
_parent( parent ),
|
||||
@ -871,11 +859,12 @@ namespace canvas
|
||||
Element::getParentStyle(const SGPropertyNode* child) const
|
||||
{
|
||||
// Try to get value from parent...
|
||||
if( _parent )
|
||||
ElementPtr parent = getParent();
|
||||
if( parent )
|
||||
{
|
||||
Style::const_iterator style =
|
||||
_parent->_style.find(child->getNameString());
|
||||
if( style != _parent->_style.end() )
|
||||
parent->_style.find(child->getNameString());
|
||||
if( style != parent->_style.end() )
|
||||
return style->second;
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ namespace canvas
|
||||
class RelativeScissor;
|
||||
|
||||
CanvasWeakPtr _canvas;
|
||||
Element *_parent;
|
||||
ElementWeakPtr _parent;
|
||||
|
||||
mutable uint32_t _attributes_dirty;
|
||||
|
||||
@ -256,7 +256,7 @@ namespace canvas
|
||||
Element( const CanvasWeakPtr& canvas,
|
||||
const SGPropertyNode_ptr& node,
|
||||
const Style& parent_style,
|
||||
Element* parent );
|
||||
ElementWeakPtr parent );
|
||||
|
||||
/**
|
||||
* Returns false on first call and true on any successive call. Use to
|
||||
|
@ -70,7 +70,7 @@ namespace canvas
|
||||
Group::Group( const CanvasWeakPtr& canvas,
|
||||
const SGPropertyNode_ptr& node,
|
||||
const Style& parent_style,
|
||||
Element* parent ):
|
||||
ElementWeakPtr parent ):
|
||||
Element(canvas, node, parent_style, parent)
|
||||
{
|
||||
staticInit();
|
||||
|
@ -45,7 +45,7 @@ namespace canvas
|
||||
Group( const CanvasWeakPtr& canvas,
|
||||
const SGPropertyNode_ptr& node,
|
||||
const Style& parent_style = Style(),
|
||||
Element* parent = 0 );
|
||||
ElementWeakPtr parent = 0 );
|
||||
virtual ~Group();
|
||||
|
||||
ElementPtr createChild( const std::string& type,
|
||||
|
@ -112,7 +112,7 @@ namespace canvas
|
||||
Image::Image( const CanvasWeakPtr& canvas,
|
||||
const SGPropertyNode_ptr& node,
|
||||
const Style& parent_style,
|
||||
Element* parent ):
|
||||
ElementWeakPtr parent ):
|
||||
Element(canvas, node, parent_style, parent),
|
||||
_texture(new osg::Texture2D),
|
||||
_node_src_rect( node->getNode("source", 0, true) ),
|
||||
|
@ -50,7 +50,7 @@ namespace canvas
|
||||
Image( const CanvasWeakPtr& canvas,
|
||||
const SGPropertyNode_ptr& node,
|
||||
const Style& parent_style = Style(),
|
||||
Element* parent = 0 );
|
||||
ElementWeakPtr parent = 0 );
|
||||
virtual ~Image();
|
||||
|
||||
virtual void update(double dt);
|
||||
|
@ -62,7 +62,7 @@ namespace canvas
|
||||
Map::Map( const CanvasWeakPtr& canvas,
|
||||
const SGPropertyNode_ptr& node,
|
||||
const Style& parent_style,
|
||||
Element* parent ):
|
||||
ElementWeakPtr parent ):
|
||||
Group(canvas, node, parent_style, parent),
|
||||
// TODO make projection configurable
|
||||
_projection(new SansonFlamsteedProjection),
|
||||
|
@ -42,7 +42,7 @@ namespace canvas
|
||||
Map( const CanvasWeakPtr& canvas,
|
||||
const SGPropertyNode_ptr& node,
|
||||
const Style& parent_style,
|
||||
Element* parent = 0 );
|
||||
ElementWeakPtr parent = 0 );
|
||||
virtual ~Map();
|
||||
|
||||
virtual void update(double dt);
|
||||
|
@ -531,7 +531,7 @@ namespace canvas
|
||||
Path::Path( const CanvasWeakPtr& canvas,
|
||||
const SGPropertyNode_ptr& node,
|
||||
const Style& parent_style,
|
||||
Element* parent ):
|
||||
ElementWeakPtr parent ):
|
||||
Element(canvas, node, parent_style, parent),
|
||||
_path( new PathDrawable(this) )
|
||||
{
|
||||
|
@ -36,7 +36,7 @@ namespace canvas
|
||||
Path( const CanvasWeakPtr& canvas,
|
||||
const SGPropertyNode_ptr& node,
|
||||
const Style& parent_style,
|
||||
Element* parent = 0 );
|
||||
ElementWeakPtr parent = 0 );
|
||||
virtual ~Path();
|
||||
|
||||
virtual void update(double dt);
|
||||
|
@ -740,7 +740,7 @@ namespace canvas
|
||||
Text::Text( const CanvasWeakPtr& canvas,
|
||||
const SGPropertyNode_ptr& node,
|
||||
const Style& parent_style,
|
||||
Element* parent ):
|
||||
ElementWeakPtr parent ):
|
||||
Element(canvas, node, parent_style, parent),
|
||||
_text( new Text::TextOSG(this) )
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ namespace canvas
|
||||
Text( const CanvasWeakPtr& canvas,
|
||||
const SGPropertyNode_ptr& node,
|
||||
const Style& parent_style,
|
||||
Element* parent = 0 );
|
||||
ElementWeakPtr parent = 0 );
|
||||
~Text();
|
||||
|
||||
void setText(const char* text);
|
||||
|
Loading…
Reference in New Issue
Block a user