Re: [Re: [Re: [Re: [[gtkmm] technical question: GTKMM_LIFECYCLE]]]]



Am 30.09.2002 12:26 schrieb(en) Murray Cumming:
MHL Schulze t-online de (Martin Schulze) wrote:
> > As I said before (somewhere), if you want a generic shared
> > reference-counting
> > smart pointer then you should use boost or something similar. So far
I
> > don't
> > see why you need to involve the underlying C object in this. Again,
if
> > you
> > produce test code that shows a problem then we have something to work
on.
>
> I need to involve the underlying C object in it because the underlying
> C object is the one that gets referenced in the gtk container code.

And so far I have no idea why you would be interested in when the C
object
gets referenced. It's wrapped.

But our wrapper uses the reference counter of the C object.
See Glib::Object::reference() / Glib::Object::unreference().

> I
> don't see how the reference counter of boost::shared_ptr<> could be
> increased when adding the object to some Gtk::Container and descreased
> when the object is removed from the container.

I don't know why you would want that to happen.

What use is a smartpointer if some container holds a pointer to my
object without referencing it?

> I.e. I don't see how
> boost::shared_ptr<> could share the underlying object with our
> containers.
>
> Again, my proposal is to _not_ force the destruction of the childs
> when a container is destroyed but only descrease the reference counter
> instead.

But the whole point of manage() is that it is destroyed. That's the
default
GTK+ behaviour. I like to offer C++-like behaviour (default) and
GTK+-like
(using manage()) behaviour but I don't think it's a good idea to add a
3rd way
or to obfuscate the GTK+-like behaviour.

The point of manage() according to what Karl Nelson said earlier on
this list is the possibility to have Gtk::Objects on the stack:
Don't call manage() and be sure that gtk(mm) will never delete your object.
Karl didn't want to force the user to allocate his widgets dynamically.

> I will work on a patch to prove that this wouldn't break
> anything but allow us to create a Glib::RefPtr<> like smart pointer
> that can share the underlying object with our containers.
> (Test code is not possible at the moment, because there is no such
> smart pointer. I would very much like to have one though.)

I am far more interested in seeing what problem this solves - with test
code.
I suspect there is something meaningful at the root of this conversation,
but
I'm not seeing it now so I'm not interested in spending my time on fixing
problems that don't seem to exist.

It doesn't solve problems. It adds flexibility. See sample code below.
I remember people complaining on the ml that they find memory
management with Gtk::Object difficult to understand repeatadly.
Give them the possibility to manage their objects with a smartpointer
and they will happy - that's my opinion.

> > I would like to see an explanation of how GstObject's lifetime is
> > different
> > than GObject, or how it is like/unlike GtkObject. That might be a lot
> > more
> > productive. So far I know nothing about it.
>
> It is different in that the container classes that derive GstObject do
> not force the destruction of its children. Instead they simply
> decrease the reference counter and set the "parent" field to zero.
> If a container holds the only reference to a child, the latter gets
> destroyed in the unref(). I consider this a clear & clean behaviour.
> It allows for a maximum of flexibility in the c++ wrapper.

So maybe it would make sense to derive Gst::Object from Glib::Object and
add
Gtk::Object-like code, but unreference instead of destroy. Maybe then it
could
be used with Glib::RefPtr. Actually you might not even need to write code
for
that - GstObject might do it for you.

Once again, I urge you to _try_ it first - the most obvious thing to do
would
be to use gtkmmproc to derive a Gst::Object wrapper from Glib::Object.
Then,
if there's a problem, it can be investigated. Please just try it.

The Gst::Object wrapper based on Gtk::Object is already done.
It is based on Gtk::Object because GstObject and GtkObject (or better
GtkWidget which adds the methods set_parent() and unparent()) behave
_identically_ (apart from container destruction).
And no, there isn't any problem. The following example code will work
fine with gstmm, as soon as some more wrapper classes are available:
(Gst::Bin is a container class for Gst::Object instantiations):

void test1()
{
  // my_pad won't be deleted until our reference is out of scope.
  // Gst::RefPtr<> is identical to Glib::RefPtr<> but
  // Gst::RefPtr<>::operator=() references and sinks the object.
  // => my_pad->ref_count == 1
  Gst::RefPtr<Gst::Pad> my_pad = Gst::manage(new Gst::Pad);

  test2(my_pad); // first call to test2.
  test2(my_pad); // second call to test2.
}

void test2(const Gst::RefPtr<Gst::Pad>& pad)
{
  // Gst::Bin::add() increases the reference count of the new child.
  // => my_pad->ref_count == 2
  Gst::Bin my_bin;
  my_bin.add(*my_pad);

  /* do something with my_bin */

  // On destruction, my_bin decreases the reference count of its children.
  // => my_pad->ref_count == 1
}

You have no chance getting this example code to work with gtkmm by
replacing Gst::Pad with Gtk::Label and Gst::Bin with Gtk::HBox but
to use a static object and not call manage, currently.
No smart pointer could prevent the destruction of the label when
function test2() ends.

However, I will end this discussion now because nobody else pops up
who seems to want that feature apart from me and because I had to
notice that there are problems getting it to work for gtkmm.
(basically only because of GtkButton with mnemonic that has a
reference count of 2 after construction and thus can only be
destroyed with gtk_widget_destroy() :-( )
I'm sorry if you feel that I have wasted your time.

Regards,

  Martin



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