Hi Kevin
Kevin Smith wrote:> alex fenton wrote:
>> I seem to be segfaulting quite a bit (actually, on TreeEvt#get_item),
>> but it disappears when I don''t use item_data. The methods are
easy
>> enough to fake in pure Ruby, so I don''t want to spend time
chasing
>> something I can work around.
>
>
> Bummer. Perhaps there is something about the life cycle of tree items
> that is causing problems...
Yep, that sounds like a good guess. I''ve only started having problems
since I''ve added support for dragging around the items and (internally)
recording the changes in structure in XML. What I''m doing is destroying
and recreating the whole branch, recursively, but I am creating a fresh
ItemData object each time. Sorry, I''ve tried, but I can''t
reproduce it in a simple test case.
> Oh, more likely: wxRuby does not keep track of the data you set, which
> means it is free to be garbage collected unless you keep your own
> reference to it in your ruby code.
>
> For example:
>
> a = Person.new
> tree.set_item_data(1, a)
> a = nil
> ...
>
> At this point, the new Person object is available to be freed, as far as
> ruby is concerned, because it doesn''t think anyone is still using
it.
OK. I don''t know any C, but I get the idea of ref-count GC
and can see how that would be a problem. Still, as you guessed, it''s
only a problem when I chop''n''change the trees about.
> The "right" solution is that the tree control would need to
include a gc
> hook that would alert the gc system about the extra ruby objects it
> holds. Or, as an easier alternative, we could remove those calls from
> the wxRuby API.
I don''t want to put other people off using them if it''s
something I''m
doing, but on the other hand, there looks to be some classes in
WxWidgets that are intended to provide higher-level cross-platform
abstractions that already exist in Ruby (stuff like File, IO, Hashes).
I''m sure they''re useful for C programmers, but maybe not so
important
when writing Ruby. Maybe this is one of those.
As a side question, how easy might it be in the future to have WxRuby
raise Exceptions (with line no, backtrace &c) when I do things like
calling methods with args of the wrong type? eg
def set_item_data(id, val)
unless val.is_a?(Wx::TreeItemData)
raise ArgumentError,
"Expected a TreeItemData, got #{val.inspect}"
end
end> You mentioned that the functionality is easy to achieve in other ways.
> If that really is the case, we should probably drop support for those,
> at least in the short term.
See an implementation in Ruby below, which has the advantage that the
data content can be any Ruby object, not just an instance of
TreeItemData or subclass. The retutn values should match the C methods;
I think the only other method it would be necessary to duplicate is
#collapse_and_reset, but I''ve just moved house too and I''m
tired ;)
Thanks
alex
class MyTreeCtrl < Wx::TreeCtrl
def initialize(*args)
super(*args)
@data_table = Hash.new()
end
def append_item(parent, text, img = -1, sel_img = -1, data = nil)
id = super(parent, text, img, sel_img)
@data_table[id] = data
return id
end
def prepend_item(parent, text, img = -1, sel_img = -1, data = nil)
id = super(parent, text, img, sel_img)
@data_table[id] = data
return id
end
def delete(id)
super(id)
@data_table.delete(id)
return nil
end
def get_item_data(id)
@data_table[id]
end
def set_item_data(id, data)
@data_table[id] = data
return nil
end
end