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