Re: Mixing XS with Gtk2::TreeStore

Sorry for the delay. I was trying to commit all the code into SVN so I could share it.

muppet wrote:
Alright, this is a different beast from how i interpreted your original message. Context helps. :-)
Sorry for now sharing the code earlier, but I had it in an internal SVN repository. I uploaded everything to Google Code. For the curious, here's the project on which I have been working: Xacobeo - An XPath visualizer. It's all written in Perl (except for 2 functions that I had to convert to C).

Google Code:

The main goal of this application is to provide a simple GUI that let's some one run XPath queries and to see their results. I made already 4 releases and the next one will address some performance issues. This next release took longer because I had to profile the code, optimize it and then realized that I had to rewrite the 2 "hotspots" (the loading of the TreeStore and the loading of the TextBuffer) in C. The problem of course is that I never done XS and had to learn it.

If you try the program you will see that the trunk ( is very slow, while the XS branch ( performs the same tasks but with the help of 2 XS functions.

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.
My intention was really to rewrite the 2 perl functions that where slow in C. For the moment I'm quite happy with the TreeStore, there's no need for me to maintain a cache. For the moment I think that I will use the TreeStore, now that I fixed the C access to the 'Glib::Scalar' the program works and it's fast enough. So until I profile the program for memory consumption I will not touch the code.

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.
Sadly the package XML::LibXML doesn't export their helper functions as Gtk2 does. At least the project's maintainer was of great help on this issue. By they way your bindings make it so easy to access their internals through XS. I really appreciated this, kudos!

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

leveraging GtkTreeModel

Thanks for the pointers.
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.  ;-)

Yes and it's quite nice when it works!

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