On 09.01.2010 16:08, Emmanuel Rodriguez wrote:
What I've noticed is that the data stored in the Gtk2::TreeIter is
really volatile and that it doesn't survive too long after a method
returns. Furthermore, only the 2 first elements of the TreeIter make it
back to the TreeModel methods intact. I also noticed that setting
references into the last 2 fields can yield strange situations.

As Kevin said, tree iters don't keep stuff you put into them alive for you. If you want to put any non-integer thing into an iter, you need to keep it alive some other way, for example by also storing it in a cache inside the tree model. This is also shortly explained in perldoc Gtk2::TreeModel / CREATING A CUSTOM TREE MODEL.

Here's a patch against your program that implements this. It also fixes an unrelated typo.

Is the Perl sample code wrong? Maybe I missed something..
Would it make sense to add it to the Gtk2-Perl examples, perhaps someone
could find it useful.

The customlist.pl example does this in GET_ITER:

        my $record = $self->{rows}[$n];
        ...
        return [ $self->{stamp}, $n, $record, undef ];

So the reference it puts into the iter is kept alive by $self->{rows}.

I guess a better explanation in the example and maybe also in the Gtk2::TreeModel docs would be useful. Care to write something up?
--- dom.pl.orig	2010-01-13 23:54:13.000000000 +0100
+++ dom.pl	2010-01-13 23:55:08.000000000 +0100
@@ -109,7 +109,7 @@ sub new {
 	my ($node) = @_ or croak "Usage: ${class}->new(node)";
 
 	my $self = $class->SUPER::new();
-	$self->{stam} = 4; # Random value
+	$self->{stamp} = 4; # Random value
 	$self->{node} = $node;
 	$self->{iters} = {};
 	$self->{types} = [ 'Glib::Scalar', 'Glib::String' ];
@@ -241,17 +241,12 @@ sub get_node {
 		and ! defined $iter->[3]
 	;
 
-	my $address = $iter->[1];
-	if (! $address) {
-		Carp::cluck "Iter has no address: ", iter_dumper($iter);
-		return undef;
-	}
-
-	my $node = $self->{iters}{$address};
+	my $node = $iter->[2];
 	if (! $node) {
-		Carp::cluck "Iter has no node at address $address: ", iter_dumper($iter);
+		Carp::cluck "Iter has no node: ", iter_dumper($iter);
 		return undef;
 	}
+
 	return $node;
 }
 
@@ -261,11 +256,10 @@ sub new_iter {
 
 	return undef unless $node;
 
-	my $address = refaddr $node;
-	$self->{iters}{$address} = $node;
-	# The first slot is for the stamp, the second slot is assumed to be an int by
-	# the perl bindings the other 2 slots are volatile nothing there survives.
-	return [ $self->{stamp}, $address, undef, undef ];
+	# We need to keep $node alive ourselves, as the iter doesn't do it.  So
+	# stuff into $self under its path.
+	$self->{iters}{$node->nodePath} = $node;
+	return [ $self->{stamp}, 0, $node, undef ];
 }
 
 
_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-perl-list

Reply via email to