Re: Do TreeIters persist after foreach search ?

2007-11-18 Thread Torsten Schoenfeld
On Fri, 2007-11-09 at 11:29 +, Dave Howorth wrote:

 I've also noticed that there is some specific Gtk2-Perl documentation
 about iterators in the Gtk2::TreeModel description. I think the text is
 misleading as well as incomplete, especially since it differs from the
 underlying gtk+ functionality. So I'd suggest a change.

Sounds good to me, committed.  Thanks!

-- 
Bye,
-Torsten

___
gtk-perl-list mailing list
gtk-perl-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-perl-list


Re: Do TreeIters persist after foreach search ?

2007-11-09 Thread Dave Howorth
Torsten Schoenfeld wrote:
 On Thu, 2007-11-08 at 11:53 +, Dave Howorth wrote:
 
 I think there must be something I'm overlooking about iters. I have code
 which for testing I've simplified to the following:
 
 What works for me in Odot is storing a copy of the iterator:
 ...
   $match_iter = $iter-copy;

Thanks, Torsten. I've just checked with my test program and it works for
me too. I'm rewriting another way to get more efficiency, but I'll
remember about Glib::Boxed-copy now you've introduced me to it!


I've also noticed that there is some specific Gtk2-Perl documentation
about iterators in the Gtk2::TreeModel description. I think the text is
misleading as well as incomplete, especially since it differs from the
underlying gtk+ functionality. So I'd suggest a change. Presently it says:

 ... These iterators are the primary way of accessing a model and are
similar to the iterators used by Gtk2::TextBuffer. They are generally
used only for a short time, and are valid only as long as the model is
unchanged. The model interface defines a set of operations using them
for navigating the model.

How about something like:

 ... These iterators are the primary way of accessing a model and are
similar to the iterators used by Gtk2::TextBuffer. The model interface
defines a set of operations using them for navigating the model.

The iterators are generally used only for a short time, and their
behaviour is different to that suggested by the Gtk+ documentation. They
are not valid when the model is changed, even though get_flags returns
'iters-persist'. Iterators obtained within a GtkTreeModelForeachFunc are
also invalid after the foreach terminates. There may be other such
cases. In the foreach case, and perhaps others, a persistent iterator
may be obtained by copying it (see Glib::Boxed-copy)

Sorry it's not very elegant but I don't know enough to be definitive!

Cheers, Dave
___
gtk-perl-list mailing list
gtk-perl-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-perl-list


Do TreeIters persist after foreach search ?

2007-11-08 Thread Dave Howorth
I'm trying to write a method that locates a particular node in a
Gtk2::TreeStore. I'm using the foreach method as the basis for walking
the tree to find the node, but I'm having trouble extracting the
resulting iter. I get errors like this:

  Gtk-CRITICAL **: gtk_tree_store_get_value: assertion `iter-stamp ==
GTK_TREE_STORE (tree_model)-stamp' failed

I think there must be something I'm overlooking about iters. I have code
which for testing I've simplified to the following:

my $match_iter;
$tree_store-foreach(
sub {
my ($tree_store, $path, $iter) = @_;

my $level = $tree_store-get($iter, LEVEL);
warn   tree_store=$tree_store, iter=$iter;\n;

$match_iter = $iter;
return TRUE;
});

warn search $tree_store = $match_iter;\n;
my $level = $tree_store-get($match_iter, LEVEL);

It prints

tree_store=Gtk2::TreeStore=HASH(0x8283970),
iter=Gtk2::TreeIter=SCALAR(0x43e28c48);
  search Gtk2::TreeStore=HASH(0x8283970) =
Gtk2::TreeIter=SCALAR(0x43e28c48);
  Gtk-CRITICAL **: gtk_tree_store_get_value: assertion `iter-stamp ==
GTK_TREE_STORE (tree_model)-stamp' failed at [[[ the second get ]]]

So the tree_store and the iter values seem to be the same but somehow
the stamp is different and I can't see why.

The gtk+ docs mention complications about the lifetime of iters but (a)
I don't think what I'm doing causes the model to emit any signals and
(b) the GtkTreeModelFlags include 'iters-persist' when I print them. The
docs say Additionally, some models guarantee that an iterator is valid
for as long as the node it refers to is valid (most notably the
GtkTreeStore ...

Any ideas what's happening, or better ways to find a node in the model?

Cheers, Dave
___
gtk-perl-list mailing list
gtk-perl-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-perl-list


Re: Do TreeIters persist after foreach search ?

2007-11-08 Thread Emmanuele Bassi

On Thu, 2007-11-08 at 11:53 +, Dave Howorth wrote:

 Any ideas what's happening, or better ways to find a node in the model?

use a Gtk2::TreePath instead, which is meant to keep pointing to a row
in the model (regardless of the fact if that row exists or if the data
has been changed):

  # inside the foreach():
  $match_path = $model-get_path($iter);

and then:

  $iter = $model-get_iter($match_path); # always check retval
  $value = $model-get($iter, $column) if defined $iter;

ciao,
 Emmanuele.

-- 
Emmanuele Bassi,
W: http://www.emmanuelebassi.net
B: http://log.emmanuelebassi.net

___
gtk-perl-list mailing list
gtk-perl-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-perl-list


Re: Do TreeIters persist after foreach search ?

2007-11-08 Thread Dave Howorth
Emmanuele Bassi wrote:
 On Thu, 2007-11-08 at 11:53 +, Dave Howorth wrote:
 
 Any ideas what's happening, or better ways to find a node in the model?
 
 use a Gtk2::TreePath instead, which is meant to keep pointing to a row
 in the model (regardless of the fact if that row exists or if the data
 has been changed):
 
   # inside the foreach():
   $match_path = $model-get_path($iter);

the sub is already given the path as an arg so that can be simplified:

$match_path = $path;

 and then:
 
   $iter = $model-get_iter($match_path); # always check retval

I was trying to avoid this because I think it must do a second tree walk
to reach the node? Which shouldn't be necessary.

But I've switched to this technique at the moment unless anybody can
suggest anything better.

At the moment the search is way too slow. I'm just about to profile it
to see whether I can fix it or whether I need to do my main tree
handling outside of the gtk tree model and just use the gtk model as a
display slave.

I guess another alternative might be to reimplement foreach's tree walk
myself which would lose the function call overhead and will probably
avoid whatever weirdness is messing with the stamp.

Thanks, Dave
___
gtk-perl-list mailing list
gtk-perl-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-perl-list


Re: Do TreeIters persist after foreach search ?

2007-11-08 Thread muppet

Dave Howorth wrote:
 I think there must be something I'm overlooking about iters. I have code
 which for testing I've simplified to the following:

 my $match_iter;
 $tree_store-foreach(
 sub {
 my ($tree_store, $path, $iter) = @_;

 my $level = $tree_store-get($iter, LEVEL);
 warn   tree_store=$tree_store, iter=$iter;\n;

 $match_iter = $iter;
 return TRUE;
 });

 warn search $tree_store = $match_iter;\n;
 my $level = $tree_store-get($match_iter, LEVEL);


The iters are intended to be used on the stack in C, so for a foreach(), they
would be destroyed before returning from the foreach() call.

Instead, either store the $path or, better yet, the data from the row that you
found, like this:

my $row_data;
$tree_store-foreach(
sub {
my ($tree_store, $path, $iter) = @_;
my $this_row = [ $tree_store-get ($iter) ];
if (this_row_is_the_one_i_want ($this_row)) {
$row_data = $this_row;
return TRUE;
}
return FALSE;
});
if (defined $row_data) {
...
}

Alternatively, you could just call the i-found-it-action in the foreach
callback when you find the row you want, and avoid the issue.

___
gtk-perl-list mailing list
gtk-perl-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-perl-list


Re: Do TreeIters persist after foreach search ?

2007-11-08 Thread muppet

Dave Howorth wrote:
 Emmanuele Bassi wrote:
   $iter = $model-get_iter($match_path); # always check retval

 I was trying to avoid this because I think it must do a second tree walk
 to reach the node? Which shouldn't be necessary.

It's not a full walk of the tree, so it's not heinously expensive, but you are
correct that it is not free.


 But I've switched to this technique at the moment unless anybody can
 suggest anything better.

See my other post in this thread.  (I should've read the whole thread before
replying...)


 At the moment the search is way too slow. I'm just about to profile it
 to see whether I can fix it or whether I need to do my main tree
 handling outside of the gtk tree model and just use the gtk model as a
 display slave.

That path often leads to madness involving dual-data-structure synchronization
and memory wastage.  You may wish to investigate creating your own TreeModel
implementation in that case, so that the TreeView will effectively display
your native data structure.


 I guess another alternative might be to reimplement foreach's tree walk
 myself which would lose the function call overhead and will probably
 avoid whatever weirdness is messing with the stamp.

I doubt that would save much, honestly.

-- 
muppet scott at asofyet dot org

___
gtk-perl-list mailing list
gtk-perl-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-perl-list


Re: Do TreeIters persist after foreach search ?

2007-11-08 Thread Dave Howorth
muppet wrote:
 The iters are intended to be used on the stack in C, so for a foreach(), they
 would be destroyed before returning from the foreach() call.

I saw the sentence about allocation on the stack but then it's followed
by the specific 'guarantee that an iterator is valid for as long as the
node it refers to is valid'. We learn by experience!

 Instead, either store the $path or, better yet, the data from the row that you
 found, like this:

 snip code

 Alternatively, you could just call the i-found-it-action in the foreach
 callback when you find the row you want, and avoid the issue.

I'm trying this. I've basically inverted my algorithm so I can step
through the gtk tree once and search a hash containing the matching data.

 (I should've read the whole thread before replying...)

Thanks to you and Emmanuele for taking the time to help.

Cheers, Dave
___
gtk-perl-list mailing list
gtk-perl-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-perl-list


Re: Do TreeIters persist after foreach search ?

2007-11-08 Thread Torsten Schoenfeld
On Thu, 2007-11-08 at 11:53 +, Dave Howorth wrote:

 I think there must be something I'm overlooking about iters. I have code
 which for testing I've simplified to the following:

What works for me in Odot is storing a copy of the iterator:

 my $match_iter;
 $tree_store-foreach(
 sub {
 my ($tree_store, $path, $iter) = @_;
 
 my $level = $tree_store-get($iter, LEVEL);
 warn   tree_store=$tree_store, iter=$iter;\n;
 
 $match_iter = $iter;

  $match_iter = $iter-copy;

 return TRUE;
 });
 
 warn search $tree_store = $match_iter;\n;
 my $level = $tree_store-get($match_iter, LEVEL);

-- 
Bye,
-Torsten

___
gtk-perl-list mailing list
gtk-perl-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-perl-list