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: Germán Arias
Subject: Re: [Liberty-eiffel] Problem with agents
Date: Tue, 22 Dec 2015 18:19:55 -0600

Hi

El mar, 22-12-2015 a las 23:23 +0100, Raphael Mack escribió:
> 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?

Are you saying I don't need queries to the attributes? I thought the
principle of Hidden information in Eiffel don't allow this? This is if I
have an attribute "bar" at class "foo", then "object_foo.bar" is enough?

> 
> >       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?

Right, but for the moment I want see this working. And (see below) if no
agent is associated to a widget, I don't expect calls to
"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.

Right, but the number is little (ACTION, IDLE_ACTION, K_ANY,
MAP_CB, ...)

>  Agents
> are in principle what you'd need here, but there is no "parameterless"
> CECIL interface for agent calls if I know correctly.

I get the Ihandle (a pointer) of the widget, and if I know the action
associated with the callback (because each action will have its specific
C function), then there are enough information.

> 
> > 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]))

Maybe, but I would like keep things close to IUP, so the end users will
be able to use (almost) the same tutorials, with some minor changes.

> 
> > 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
> 

I will try these suggestions.

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

But at the end all the agents will be executed by an external call from
C, right?. The "launch_routine" is in the side of Eiffel code.

> 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?

This is my idea, with a kind of dictionary (or HASH_TABLE as you
suggest) to know in which IUP_WIDGET should be called the
"execute_action".

I will try some of your suggestion.

Thanks
Germán

> 
> Regards,
> Rapha
> 
> 





reply via email to

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