Re: Mixing XS with Gtk2::TreeStore
- From: muppet <scott asofyet org>
- To: Emmanuel Rodriguez <emmanuel rodriguez gmail com>
- Cc: gtk-perl-list gnome org
- Subject: Re: Mixing XS with Gtk2::TreeStore
- Date: Sat, 27 Dec 2008 13:31:25 -0500
On Dec 27, 2008, at 12:19 PM, Emmanuel Rodriguez wrote:
On Sat, Dec 27, 2008 at 4:14 PM, muppet <scott asofyet org> wrote:
On Dec 27, 2008, at 6:41 AM, Emmanuel Rodriguez wrote:
Stop. Custom XS should be a last resort, as it ratchets up the
difficulty
of maintaining and deploying your application, and is often
unnecessary.
Let's do some sanity checks first:
Let me present more deeply the problem. I have a Perl application that
displays an XML document with both source code syntax highlighting and
a DOM tree view. For now the problem I have is showing the DOM tree in
the tree view. For the moment, I'm using a TreeStore because there are
many examples showing how to work with a TreeStore. Populating the
TreeStore with the DOM tree is my current bottleneck. The application
is based on XML::LibXML which in turn is using libxml2. So the there's
already a quite decent data model: XML::LibXML::Document.
The slowness is due to the nature of XML::LibXML where each node and
field access is performed through XS. A small document of 400K can
very easily return over 170_000 DOM nodes. Walking such a tree in Perl
is slow (about 0.5sec) when combining it with the operations of a
TreeStore it takes 1.2 sec. Now imagine loading a 20 Megs document...
Alright, this is a different beast from how i interpreted your
original message. Context helps. :-)
So, your current design is to mirror the DOM in the TreeStore by
holding a reference to each element in the corresponding node in the
tree.
Two approaches come to mind:
x) Create a custom TreeModel implementation that directly accesses the
DOM. With some caching you could avoid having to walk the DOM on each
access, at the expense of memory, but it's unclear whether this would
actually be more efficient than letting TreeStore do that caching work.
y) Glue the DOM and TreeStore together in C code as a custom subclass
of TreeStore (or possibly a custom TreeModel, as above, but in C), and
create a perl binding for that object.
I think that something like y) was what you were initially trying to
do, correct? However, it sounds like you were still creating the
objects in perl and trying to implement only the bare minimum, the
populate function, in C.
sub create_model {
my $model = Gtk2::TreeStore->new(
'Glib::Scalar', # An instance to XML::LibXML::Element
'Glib::String', # The name of the Element
);
}
There it is -- the first column is 'Glib::Scalar', which is a generic
wrapper for a perl SV. Down in C, you'll see that as an SV. What's
inside depends on what you loaded into it. You can't just assume it's
a pointer. In fact, since XML::LibXML also wraps stuff up in XS goo,
you don't really know for sure how to get to the juicy C pointer
inside without scrubbing through the XML::LibXML source. I don't know
if they export helper functions in the vein of gtk2-perl's
gperl_get_object(), but you'll have to do some research.
This marshaling difficulty is one reason that i would recommend
actually writing the whole glue thing up as a GObject in C, and then
binding that GObject to perl, instead of trying to do only the
populate function. That way, you feed in one XML::LibXML object from
perl, and everything else happens in C.
Is there an example on how to implement a custom TreeModel?
I think the list archives will help most. The iters are the biggest
stumbling blocks in perl, thanks to how the C api works. For what
you're doing, i think i've talked myself into thinking you do, indeed,
want to do the work in C.
GTK+ 2.0 Tree View Tutorial
http://scentric.net/tutorial/
leveraging GtkTreeModel
http://davyd.livejournal.com/252351.html
Your stack trace indicates that you *are* adding Perl data types to
your
tree. Did you create your store with a column type of
'Glib::Scalar'?
Yes the TreeStore has slot for passing the XML::LibXML::Node that's
been displayed in the TreeView. I didn't realized that I had to pass
an SV* there. I was trying to pass a simple C pointer and expected it
to be magically transformed to a Perl type!
Hehe, magic takes work. ;-)
--
The one difference between Dali and a crazy man is very simple: Dali
is not crazy at all.
-- Salvador Dali
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]