liberty-eiffel
[Top][All Lists]
Advanced

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

[Liberty-eiffel] Problem with agents


From: Germán Arias
Subject: [Liberty-eiffel] Problem with agents
Date: Mon, 21 Dec 2015 20:09:37 -0600

Hi all,

Well, I'm working in an Eiffel plugin to the library IUP [1]. IUP is a
multi-platform toolkit for building graphical user interfaces, is native
on Windows and on GNU/Linux use Gtk+ (or Mottif). Is MIT License.
Anyway, I'm having a problem with agents, and since I'm newbie in Eiffel
I can't figure where is the problem.

To test this I have a small example as follow:

class EXAMPLE

insert
   -- This expanded class have only one routine which
   -- return a shared object
   IUP_INTERFACE

create {ANY}
   make

feature {ANY}
   make
      local
         gui: IUP
         i: INTEGER
         a: COLLECTION[IUP_WIDGET]
         l: IUP_LABEL
         b: IUP_BUTTON
         v: IUP_VBOX
         w: IUP_DIALOG
      do
         -- The returned object is a shared object
         -- created with a once routine
         gui := iup_open
                        
        create l.label("Hello world from Liberty Eiffel!")
        create b.button("OK", "ACTION")
        gui.iup_set_callback(b, "ACTION", agent display)
        a := {ARRAY[IUP_WIDGET] 0, << l, b >>}

        create v.vbox(a)
        create w.dialog(v)
        gui.set_attribute(w, "TITLE", "Hello world")
        gui.set_attribute(v, "ALIGNMENT", "ACENTER")
        gui.set_attribute(v, "GAP", "10")
        gui.set_attribute(v, "MARGIN", "10x10")
        
        i := w.show

        gui.iup_main
     end

     display
        do
           io.put_string("Executed %N")
        end
end 


Almost all widgets inherit from a class like this (reference class):


feature {ANY}
   widget_pointer: POINTER
   cb_action: ROUTINE[TUPLE]

   widget: POINTER
      do
         Result := widget_pointer
      end

      set_widget (wgt: POINTER)
         do
            widget_pointer := wgt
         end
        
      set_cb_action (act: ROUTINE[TUPLE])
         do
            cb_action := act
         end

      execute_action
         do
            cb_action.call([])
         end
end

I need store internally the agents because the IUP interface don't let
me pass user data into callbacks.

The shared object (mentioned avobe) have routines to handle callbacks,
like these (this is a reference class):

feature {ANY} -- Commands to handle callbacks
   wer: IUP_WIDGET
        
   iup_set_callback (wgt: IUP_WIDGET; name: STRING; callback:
ROUTINE[TUPLE])
      do
         wer := wgt
         wgt.set_cb_action(callback)
                
         int_set_callback(wgt.widget, name.to_external)
                
         -- This call work here
         -- wer.execute_action
      end

   int_set_callback (object: POINTER; name: POINTER)
      external "plug_in"
      alias "{
         location: "."
         module_name: "iup"
         feature_name: "set_callback"
         }"
      end

   launch_routine (obj: POINTER): INTEGER
      do
        wer.execute_action
        Result := 1
      end

For the moment I keep the widget in "wer", but of course I will change
this. The problem is with the agent, stored in the widget with
"wgt.set_cb_action(callback)". If I execute this agent, as shown the
commented lines, this works. But don't work later in "launch_routine".
"launche_routine" is executed by a external call. The program crash here
when try to execute the stored agent. Here the backtrace:


Line : 64 column 8
in /home/german/Instalados/tests/liberty/iup_test/auxiliary/iup.e.
*** Error at Run Time ***: Invalid type for the target of this procedure
call.
4 frames in run-time stack.
====  Bottom of run-time stack  ====
<system root>
Current = EXAMPLE#0x24f57b8
line 10 column 4
file /home/german/Instalados/tests/liberty/iup_test/example.e 
======================================
make EXAMPLE
Current = EXAMPLE#0x24f57b8
gui = IUP#0x27429e8
        [ wer = #0x274d278
        ]
i = 0
a = ARRAY[IUP_WIDGET]#0x2751c88
        [ storage = NATIVE_ARRAY[IUP_WIDGET]#0x2753cb0
          lower = 0
          generation = 1
          capacity = 2
          upper = 1
        ]
l = IUP_LABEL#0x274aa28
        [ cb_action = Void
          widget_pointer = POINTER#0x274ca10
        ]
b = IUP_BUTTON#0x274d278
        [ cb_action = #0x274fc78
          widget_pointer = POINTER#0x274f260
        ]
v = IUP_VBOX#0x275bca8
        [ cb_action = Void
          widget_pointer = POINTER#0x275dc90
        ]
w = IUP_DIALOG#0x275e4a8
        [ cb_action = Void
          widget_pointer = POINTER#0x2760490
        ]
line 36 column 14
file /home/german/Instalados/tests/liberty/iup_test/example.e 
======================================
External call (may be a -cecil call).
======================================
launch_routine IUP
Current = IUP#0x274f260
        [ wer = #0x26c3270
        ]
obj = POINTER#0x7f7c07ada265
Result = 0
line 64 column 8
file /home/german/Instalados/tests/liberty/iup_test/auxiliary/iup.e 
====  Top of run-time stack   ====
Line : 64 column 8
in /home/german/Instalados/tests/liberty/iup_test/auxiliary/iup.e.
*** Error at Run Time ***: Invalid type for the target of this procedure
call.



What is wrong? Any advice? I attached an image that show how looks this
basic example.

Germán

[1] http://webserver2.tecgraf.puc-rio.br/iup/

Attachment: example.jpg
Description: JPEG image


reply via email to

[Prev in Thread] Current Thread [Next in Thread]