iu icon indicating copy to clipboard operation
iu copied to clipboard

Crash when Area component callback accesses instance variable

Open existXFx opened this issue 3 years ago • 2 comments
trafficstars

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)

existXFx avatar Nov 29 '21 06:11 existXFx

Make a PR for it mate!

grkek avatar Dec 30 '21 04:12 grkek

Went ahead and opened the PR, I applied this fix to each of the callbacks

videotoaster avatar Dec 29 '23 21:12 videotoaster