Re: Possible to fix glaring Gjs API issues before GNOME 4?



On Fri, 2013-03-01 at 02:44 +0400, Nikita Churaev wrote:
That's not an issue - you can put even a pointer but the problem is that
you need to pin object. You don't know (automatically without user
intervention) when you can free the resource. At any point GTK might
keep GtkTreeIter alive so data you put inside cannot be freed (or
garbage collected or however you'll call it) and it need's to be always
considered 'alive'. I guess it is possible to workaround the issue by
reverse engineering the Gtk internals but solution would be very
unstable and not remotely elegant. 

The problem with GtkTreeIter is that you can't make any function to be
called when iter goes out of scope. Example:

int
foo(void)
{
  GtkTreeIter iter;
  get_iter_of_something (&iter);
  do_something_with_iter (&iter);

  /* iter is no longer needed, C frees its memory 
     automatically, but we can't make it call a 
     custom function, as C doesn't have C++'s
     destructors, that's why we can't put references
     to JavaScript objects into them */
}

However, luckily for us, GtkTreeIter has an integer stamp field that
could be used instead of a direct reference. JavaScript custom tree
models will be slower as they would need to look up items by their
stamps. Example:

_init: function() {
  this.parent(...);
  this._items = [];
},

getTreeIterOfItem: function(itemStamp)
{
  if (this._items[itemStamp] === undefined)
    return undefined;

  return new Gtk.TreeIter(itemStamp);
},

getItemByTreeIter: function(iter)
{
  return this._items[iter.stamp];
}


Yes. That is the problem I've wrote about. 

I didn't parsed the sentence "models guarantee that an
iterator is valid for as long as the node it refers to is valid (...)"
correctly. Arguably this allows to even point to node in one of the
field speeding things a little:

I assume that we don't use list as probably GtkListModel is better in
such case. Sorry if code is incorrect (I don't use JS):

function MyNode() {
    this._init();
}

MyNode.prototype = {
    _init: function() {
        ....
    },
    next: function() {
        ....
    }
    parent: function() {
        ....
    }
};

function MyModel() {
    this._init();
}

MyModel.prototype = {
    _init: function() {
        ...
    },
    getTreeIterFromTreePath: function(iter, path) {
        var node = doMagic(path);
        iter._user_data1 = marshal_as_unowned(node); // Don't pin
    }
    getNodeFromTreeIter: function(iter) {
        return iter._user_data1;
    }
    root: new MyNode();
};

I'm not sure if marshal_as_unowned exists in GJS now though.

Best regards

Attachment: signature.asc
Description: This is a digitally signed message part



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