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.
12 files changed:
//----------------------------------------------------------------------------
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;
- }
}
//----------------------------------------------------------------------------
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
ElementPtr Element::getParent() const
{
//----------------------------------------------------------------------------
ElementPtr Element::getParent() const
{
}
//----------------------------------------------------------------------------
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
bool Element::ascend(EventVisitor& visitor)
{
//----------------------------------------------------------------------------
bool Element::ascend(EventVisitor& visitor)
{
- if( _parent )
- return _parent->accept(visitor);
+ ElementPtr parent = getParent();
+ if( parent )
+ return parent->accept(visitor);
EventPropagationPath path;
path.push_back( EventTarget(this) );
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();
path.push_front( EventTarget(parent) );
CanvasPtr canvas = _canvas.lock();
Element::Element( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
Element::Element( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
+ ElementWeakPtr parent ):
PropertyBasedElement(node),
_canvas( canvas ),
_parent( parent ),
PropertyBasedElement(node),
_canvas( canvas ),
_parent( parent ),
Element::getParentStyle(const SGPropertyNode* child) const
{
// Try to get value from parent...
Element::getParentStyle(const SGPropertyNode* child) const
{
// Try to get value from parent...
+ ElementPtr parent = getParent();
+ if( parent )
{
Style::const_iterator style =
{
Style::const_iterator style =
- _parent->_style.find(child->getNameString());
- if( style != _parent->_style.end() )
+ parent->_style.find(child->getNameString());
+ if( style != parent->_style.end() )
- CanvasWeakPtr _canvas;
- Element *_parent;
+ CanvasWeakPtr _canvas;
+ ElementWeakPtr _parent;
mutable uint32_t _attributes_dirty;
mutable uint32_t _attributes_dirty;
Element( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
Element( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
+ 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
Group::Group( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
Group::Group( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
+ ElementWeakPtr parent ):
Element(canvas, node, parent_style, parent)
{
staticInit();
Element(canvas, node, parent_style, parent)
{
staticInit();
Group( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style = Style(),
Group( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style = Style(),
+ ElementWeakPtr parent = 0 );
virtual ~Group();
ElementPtr createChild( const std::string& type,
virtual ~Group();
ElementPtr createChild( const std::string& type,
Image::Image( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
Image::Image( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
+ ElementWeakPtr parent ):
Element(canvas, node, parent_style, parent),
_texture(new osg::Texture2D),
_node_src_rect( node->getNode("source", 0, true) ),
Element(canvas, node, parent_style, parent),
_texture(new osg::Texture2D),
_node_src_rect( node->getNode("source", 0, true) ),
Image( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style = Style(),
Image( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style = Style(),
+ ElementWeakPtr parent = 0 );
virtual ~Image();
virtual void update(double dt);
virtual ~Image();
virtual void update(double dt);
Map::Map( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
Map::Map( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
+ ElementWeakPtr parent ):
Group(canvas, node, parent_style, parent),
// TODO make projection configurable
_projection(new SansonFlamsteedProjection),
Group(canvas, node, parent_style, parent),
// TODO make projection configurable
_projection(new SansonFlamsteedProjection),
Map( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
Map( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
+ ElementWeakPtr parent = 0 );
virtual ~Map();
virtual void update(double dt);
virtual ~Map();
virtual void update(double dt);
Path::Path( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
Path::Path( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
+ ElementWeakPtr parent ):
Element(canvas, node, parent_style, parent),
_path( new PathDrawable(this) )
{
Element(canvas, node, parent_style, parent),
_path( new PathDrawable(this) )
{
Path( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
Path( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
+ ElementWeakPtr parent = 0 );
virtual ~Path();
virtual void update(double dt);
virtual ~Path();
virtual void update(double dt);
Text::Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
Text::Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
+ ElementWeakPtr parent ):
Element(canvas, node, parent_style, parent),
_text( new Text::TextOSG(this) )
{
Element(canvas, node, parent_style, parent),
_text( new Text::TextOSG(this) )
{
Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
+ ElementWeakPtr parent = 0 );
~Text();
void setText(const char* text);
~Text();
void setText(const char* text);