Re: More wrapping fun



On Tue, 2006-10-03 at 03:03 -0500, Paul Davis wrote:
[snip]

> 1. A call to GooCanvas::Rect::create( parent, ...) occurs.
> 2. create() calls new Rect( parent, ...)
> 3. new Rect() calls goo_canvas_rect_new( parent, ...... )

Well, it calls g_object_new() hopefully, but the problem remains.

> 4. the GooCanvasView (In C land) creates the corresponding ItemView
> 5. the GooCanvasView emits the item_view_created signal, passing the
> new GooCanvasItemView and new GooCanvasItem pointers.
> 6. These two pointers get passed to the on_item_view_created()
> handler.
> 7. The GooCanvasItem gets converted to GooCanvas::Item via
> Glib::wrap().
> 8. Glib::wrap() causes g_object_set_qdata_full() to be called on the
> pointer. (Haven't tracked down how or why, but it must.)
> 9. Evertying rolls back up the stack
> 10. we finally get back to our constructor. (Remeber the call to
> create?)
> 11. the pointer returned from new Rect() gets passed to the super
> class constructor ItemView::ItemView( GObject* obj )
> 12. ItemVew::ItemView passes obj to its super class constructor
> Glib::Object( GObject* obj )
> 13. Glib::Object ends up calling g_object_get_qdata() which was set in
> step 8.
> 14. We print a nice info message.

Hmm, that is annoying. What is this signal good for?

I suppose we could maybe set the qdata earlier, but then we are marking
a wrapper as available before that wrapper is fully constructed.

> Therefore.
> 
> Rect::Rect(const Glib::RefPtr<Item>& parent, gdouble x, gdouble y,
> gdouble width, gdouble height )
>     :
>         ItemSimple( G_OBJECT( goo_canvas_rect_new( parent->gobj(), x,
> y, width, height, NULL ) ) )
> {
> }
> 
> If the signal handler is active, after G_OBJECT( blah ) returns, the
> returned object is completely constructed. When ItemSimple( blah )
> runs, it attempts to reconstruct the wrapper.
> 
> So, I do this:
> 
> Glib::RefPtr<Rect>
> Rect::create( const Glib::RefPtr<Item>& parent, gdouble x, gdouble y,
> gdouble width, gdouble height )
> {
>     return
> Glib::wrap( GOO_CANVAS_RECT( goo_canvas_rect_new( parent->gobj(), x,
> y, width, height, NULL ) ), true ) ;
> }
> 
> No error message. All is good.
> 
> I've been looking at this.  Really, there isn't any good reason that
> this shouldn't be right.

Yes, maybe it's not so bad. It might be OK if you can make it use
g_object_new() instead of goo_canvas_rect_new(). Otherwise you are not
instantiating the derived GType, and default signal handlers and vfuncs
will not be hooked in.

Do add a comment there, please, about why you've done this.

Well done for figuring this out. It's unusual.


-- 
Murray Cumming
murrayc murrayc com
www.murrayc.com
www.openismus.com




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]