iu
iu copied to clipboard
Crash when Area component callback accesses instance variable
A class inherits Iu::Components::Area and implements on_* callback, will crash program when its instance access instance variables:
class MyArea < Iu::Components::Area
def initialize(width = nil, height = width)
@blah = "blah"
super(width, height)
end
def on_draw(params : UI::AreaDrawParams)
puts @blah
end
def on_mouse_event(mouse_event : UI::AreaMouseEvent);end
def on_mouse_crossed(left : Bool);end
def on_drag_broken;end
def on_key_event(key_event : UI::AreaKeyEvent);end
end
I'm not familiar with Crystal. I think the reason is that the callback function passed to the libui C library forms a closure. The Iu shard wraps libui, a new member "data" is added to the AreaHandler structure to store pointers to an area objects. This allows libui to call back the on_* method implemented by the MyArea class, I'm not sure if this is the scenario described in Crystal document. After testing, this bug can be solved in this way:
@@on_mouse_event_cb = Proc(UI::AreaHandler*, UI::Area*, UI::AreaMouseEvent*, Nil).new { |h, a, e|
# h.value.data.as(Area*).value.on_mouse_event(e.value).as(Nil)
::Box(Area).unbox(h.value.data).on_mouse_event(e.value).as(Nil)
}
# @handler.data = self.as(Void*)
@handler.data = ::Box.box(self)
Make a PR for it mate!
Went ahead and opened the PR, I applied this fix to each of the callbacks