liberty-eiffel
[Top][All Lists]
Advanced

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

Re: [Liberty-eiffel] Problem with agents


From: Raphael Mack
Subject: Re: [Liberty-eiffel] Problem with agents
Date: Tue, 22 Dec 2015 23:22:43 +0100

Hi,

let me ask some questions inline...

Am Montag, den 21.12.2015, 20:09 -0600 schrieb Germán Arias:

> 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

What is the use of this function / Why not rename widget_pointer to
widget and remove this one here?

>       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

Have you chosen the client list really wise or is this just a simplified
example? - The same for contracts and handling an uninitialized (= Void)
cb_action in execute_action?

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

I don't understand... In case you do not have a parameter for the
callback, you will need a specific C function for each callback. Agents
are in principle what you'd need here, but there is no "parameterless"
CECIL interface for agent calls if I know correctly.

> 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

Again: exporting to ANY doesn't look very nice e. g.
IUP.iup_set_callback should probably be exported to the widgets, only
and in client code the callback should better be set on the widget (e.
g. IUP_BUTTON.set_action(cb: ROUTINE[TUPLE]))

> 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)".

Why is this necessary in IUP.iup_set_callback at all? I'd expect client
code finally to look something like

make is
    do
        create b.button("OK", "ACTION")
        b.set_action(agent whatever)
        -- put b in the window...
    end

whatever is
    do
        io.put_string("callback in client code")
        -- add whatever is the REAL action to be done after button press
    end

while IUP_BUTTON has something like
feature {NONE}
widget: POINTER
execute_action is
    do
        cb_action.call([]) -- this is the same as you have
    end

feature {ANY}
set_action(cb: ROUTINE[TUPLE])
    do
        iup_open.iup_set_callback(widget, "ACTION",
                                  agent execute_action)
    end

>  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:
> 
[...]
> What is wrong? Any advice? I attached an image that show how looks this
> basic example.

It seems, that you try to call the agent from C, which is not so
simple... In case I see it correct, the callback on C level has a
parameter where you get the handle of the widget, right? What about
having one function IUP.cb_action(widget: POINTER), which you call via
CECIL for all ACTION callbacks and in this you retrieve the agent to
call from a HASH_TABLE, with the widget as index?

Regards,
Rapha





reply via email to

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