From 9fa49a5c11359714a62afc430499897538b59cc4 Mon Sep 17 00:00:00 2001 From: dooglus Date: Fri, 1 Feb 2008 01:58:45 +0000 Subject: [PATCH] I still think it would be great to get rid of reference counting - read the new comment in layer_pastecanvas.h and you'll almost certainly agree! git-svn-id: http://svn.voria.com/code@1542 1f10aa63-cdf2-0310-b900-c93c546f37ac --- synfig-core/trunk/src/synfig/layer_pastecanvas.cpp | 12 ++++++++-- synfig-core/trunk/src/synfig/layer_pastecanvas.h | 27 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/synfig-core/trunk/src/synfig/layer_pastecanvas.cpp b/synfig-core/trunk/src/synfig/layer_pastecanvas.cpp index 04ed8b9..edc3d0b 100644 --- a/synfig-core/trunk/src/synfig/layer_pastecanvas.cpp +++ b/synfig-core/trunk/src/synfig/layer_pastecanvas.cpp @@ -85,7 +85,8 @@ Layer_PasteCanvas::Layer_PasteCanvas(): origin(0,0), depth(0), zoom(0), - time_offset(0) + time_offset(0), + extra_reference(false) { children_lock=false; muck_with_time_=true; @@ -103,6 +104,7 @@ Layer_PasteCanvas::~Layer_PasteCanvas() set_sub_canvas(0); //if(canvas && (canvas->is_inline() || !get_canvas() || get_canvas()->get_root()!=canvas->get_root())) + //if(extra_reference) // canvas->unref(); } @@ -186,7 +188,8 @@ Layer_PasteCanvas::set_sub_canvas(etl::handle x) if(canvas && muck_with_time_) remove_child(canvas.get()); - if(canvas && (canvas->is_inline() || !get_canvas() || get_canvas()->get_root()!=canvas->get_root())) + // if(canvas && (canvas->is_inline() || !get_canvas() || get_canvas()->get_root()!=canvas->get_root())) + if (extra_reference) canvas->unref(); child_changed_connection.disconnect(); @@ -209,7 +212,12 @@ Layer_PasteCanvas::set_sub_canvas(etl::handle x) add_child(canvas.get()); if(canvas && (canvas->is_inline() || !get_canvas() || get_canvas()->get_root()!=canvas->get_root())) + { canvas->ref(); + extra_reference = true; + } + else + extra_reference = false; if(canvas) on_canvas_set(); diff --git a/synfig-core/trunk/src/synfig/layer_pastecanvas.h b/synfig-core/trunk/src/synfig/layer_pastecanvas.h index 0aa3d6b..1dc9506 100644 --- a/synfig-core/trunk/src/synfig/layer_pastecanvas.h +++ b/synfig-core/trunk/src/synfig/layer_pastecanvas.h @@ -70,6 +70,33 @@ private: mutable Rect bounds; sigc::connection child_changed_connection; + + // Nasty hack: Remember whether we called an extra ref() when + // setting the canvas, so we know whether to call an extra unref() + // when finished with the canvas. + // + // Here's the story: + // + // The root canvas is destructed first. That sets the + // Layer::canvas_ (the parent canvas) of any PasteCanvas layer it + // contains to nil, due to a call to Layer::set_canvas(0), + // triggered by the connection made when Layer::set_canvas + // originally set its canvas_ member to point to the root canvas. + // ~Canvas does begin_delete() which triggers that connection. + // + // After ~Canvas has run, the members of the root canvas are + // freed, including its children_ list. If this was the last + // reference to the child canvas that the pastecanvas uses, that + // child canvas will Layer_PasteCanvas::set_sub_canvas(0) on the + // PasteCanvas layer to set its canvas (the child, pasted canvas) + // not to refer to the soon-to-be destroys child canvas. But + // set_sub_canvas() originally looked at the value of + // Layer::canvas_ (the parent canvas, obtained via + // Layer::get_canvas()) to decide whether to do an extra ref() on + // canvas (the child canvas). We need to unref() it now if we + // did, but we've forgotten whether we did. So we use this + // 'extra_reference' member to store that decision. + bool extra_reference; public: virtual void on_canvas_set(); -- 2.7.4