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