comp.lang.ada
 help / color / mirror / Atom feed
* Problem with gtkada and tasks
@ 2001-07-25  8:53 Carlos Aganzo
  2001-07-26 16:07 ` Ted Dennison
  2001-07-30 16:57 ` David Monterroso Cabello
  0 siblings, 2 replies; 7+ messages in thread
From: Carlos Aganzo @ 2001-07-25  8:53 UTC (permalink / raw)


Hi!

 When I instance a task using GtkAda windows, the windows do not
update until  the tasks have completed their execution. Why does this
happen? Is it  because of the thread the Gtk application uses? How can
I solve this?

 Thanks in advance.

 carlos.




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem with gtkada and tasks
  2001-07-25  8:53 Problem with gtkada and tasks Carlos Aganzo
@ 2001-07-26 16:07 ` Ted Dennison
  2001-07-27  8:16   ` Carlos Aganzo
  2001-07-30 16:57 ` David Monterroso Cabello
  1 sibling, 1 reply; 7+ messages in thread
From: Ted Dennison @ 2001-07-26 16:07 UTC (permalink / raw)


In article <3b5e88ee.10782754@news.bt.es>, Carlos Aganzo says...
> When I instance a task using GtkAda windows, the windows do not
>update until  the tasks have completed their execution. Why does this
>happen? Is it  because of the thread the Gtk application uses? How can
>I solve this?

What OS are you using?

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
          home email - mailto:dennison@telepath.com



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem with gtkada and tasks
  2001-07-26 16:07 ` Ted Dennison
@ 2001-07-27  8:16   ` Carlos Aganzo
  2001-07-27 12:31     ` Manuel Carro
  0 siblings, 1 reply; 7+ messages in thread
From: Carlos Aganzo @ 2001-07-27  8:16 UTC (permalink / raw)


> > When I instance a task using GtkAda windows, the windows do not
> >update until  the tasks have completed their execution. Why does this
> >happen? Is it  because of the thread the Gtk application uses? How can
> >I solve this?
> What OS are you using?

    I'm using Windows Millenium. I think there must be some kind of
problem with Windows and the Gtk signal handlers.

  task type cell(init: access location);

  type type_access_cell is access cell;

   (...)

   procedure HandlerBotonComenzar (Widget : access
Gtk.Widget.Gtk_Widget_Record'Class) is
    -- Crea una c�lula que ser� la encargada de crear todo lo dem�s
     t:  type_access_cell;
   begin
     t:=new type_access_cell;
   end HandlerBotonComenzar;

Until t has not completed its execution, the windows do not update.
(and in the body of the task type cell it updates the window, but it
does not appear in screen after the tasks have died).

Thanks for your help




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem with gtkada and tasks
  2001-07-27  8:16   ` Carlos Aganzo
@ 2001-07-27 12:31     ` Manuel Carro
  0 siblings, 0 replies; 7+ messages in thread
From: Manuel Carro @ 2001-07-27 12:31 UTC (permalink / raw)



> Until t has not completed its execution, the windows do not update.
> (and in the body of the task type cell it updates the window, but it
> does not appear in screen after the tasks have died).

    I am not sure of having understood fully your problem, but the
contents of the windows are updated by the Gtk.Main.Main or
Gtk.Main.Main_Iteration procedures.  If you call the former from
inside a handler, then this is probably a mistake: the GtkAda
documentation states that:

  the GtkAda main loop (Gtk.Main.Main) can only be be run inside one
  specific tasks. In other words, you cannot call Gtk.Main.Main from any
  task other than the one that started the outer level main loop.

    If you have another task receiving events, etc, then you should
protect the access to the graphical primitives (cf. the GtkAda
documentation).  In any case, the Ada task semantics, AFAIK, does not
require a task relinquishing the CPU unless blocked (i.e., no
round-robin by default).  

    But, on the other hand, I have found (in Linux) some problems when
using concurrently the GtkAda toolkit, even using Gtk.Threads.  A safe
solution (which is the one I adopted) is to access all the graphical
primitives from a task which initializes the state and has a delay
clause which periodically updates the windows.  Any smarter solution
will be welcome.


-- 
          ||            Manuel Carro -- DLSIIS            ||
          ||           e-mail: mcarro@fi.upm.es           ||
          ||      http://lml.ls.fi.upm.es/~boris          ||
          ||    http://clip.dia.fi.upm.es/Software/Ciao   ||
          || Phone: +34 91 336-7455  FAX: +34 91 336-7412 ||




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem with gtkada and tasks
  2001-07-25  8:53 Problem with gtkada and tasks Carlos Aganzo
  2001-07-26 16:07 ` Ted Dennison
@ 2001-07-30 16:57 ` David Monterroso Cabello
  2001-07-31  0:40   ` MCL
  2001-07-31 11:17   ` Frank
  1 sibling, 2 replies; 7+ messages in thread
From: David Monterroso Cabello @ 2001-07-30 16:57 UTC (permalink / raw)


First of all, thanks to all of you for your help, I really appreciate it
:)

So far, it seems to me that i have not been able to explain my problem,
So I'm going to try, in my poor english, to fully explain it:

The purpose of the program is to create a simulation in which a cell is
represented by an Ada95 task, and it is capable of
replicating by itself. I have not completely coded the behavior of the
cell task, for I have found a lot of problems, first using
ObjectAda+Guibuilder, and now using Gnat+Gtk (under Win32):

The cells live in a bi-dimensional world (14x12), represented by this
array:

    type mrecord is record
       imagen: Gtk.Pixmap.Gtk_Pixmap;  -- graphic representation of the
cell
       e: estado:=vacia;                           -- state of the cell:
growing, sick, dead...
    end record;

  Matriz           : array(1..14, 1..12) of mrecord;

    The cells will have several states, and this will have a graphical
representation, updating the Gtk_Pixmaps associated with the
array.

    The problem is that the Gtk_Pixmap do *NOT* update until all the
tasks have died, so I don't get what I want (getting to see the
cells growing, breeding and dying in real-time), and I only can see the
pictures of all of them dead.

    What could it be: Windows, Gtk, a coding problem...?

    Thanks in advance, I include the full code so far (note that several
things are not completed, for example I have not yet fully
represented all the states of the cells) :

--->cut<---

with Gtk.Main, Gtk.Window, Gtk.Button, Gtk.Label, Gtk.Pixmap, Gdk.Pixmap,
Gdk.Bitmap;
with Gtk.Style; use Gtk.Style; with Gtk.Enums;
with Gtk.Box, Gtk.Frame;
with concurrencia; use concurrencia;
with manejadores; use manejadores;
with pprotegido; use pprotegido;

package interfaz is
  -- Ventana principal y el contenedor inclu�do en ella
  VentanaPrincipal : Gtk.Window.Gtk_Window;
  ContenedorMain   : Gtk.Box.Gtk_HBox;
  c                : tarea;
  -- Matriz de c�lulas

  type mrecord is record
    imagen: Gtk.Pixmap.Gtk_Pixmap;
    e: estado:=vacia; -- El estado en un principio es vac�o, claro
  end record;

  Matriz           : array(1..14, 1..12) of mrecord;

  -- Contenedores de la matriz
  Cont             : array(1..12) of Gtk.Box.Gtk_HBox;  --contenedor de
los pix horizontales
  ContCont         : Gtk.Box.Gtk_VBox;                  --contenedor de
los hboxes
  FrameMatriz      : Gtk.Frame.Gtk_Frame;

  -- Bitmaps de los diferentes estados de la c�lula
  I_Sana, I_Enferma, I_E_Ar, I_E_Ab, I_E_Iz, I_E_Dc :
Gdk.Pixmap.Gdk_Pixmap;
  Mascara          : Gdk.Bitmap.Gdk_Bitmap;
  Estilo           : Gtk.Style.Gtk_Style;

  -- Botones y sus contenedores
  FrameBotones     : Gtk.Frame.Gtk_Frame;
  BotonComenzar    : Gtk.Button.Gtk_Button;
  EtiquetaBoton    : Gtk.Label.Gtk_Label;

  procedure crear_nueva_celula(px, py: integer);
  procedure dibujar_interfaz;

end interfaz;

with ptareas; use ptareas;
with Gdk.Threads;

package body interfaz is

  procedure crear_nueva_celula(px, py: integer) is
   type cel is access celula; c: cel;
   type pos is access posicion; p: pos;
   begin
    p:=New posicion; p.px:=px; p.py:=py;
    c:=new celula(p);
  end crear_nueva_celula;

 procedure dibujar_interfaz is
  begin
   --Y tenemos que hacerlo usando el soporte de threads de gtkada. SU
PUTA MADRE.
   Gtk.Main.Init;
   Gtk.Window.Gtk_New(VentanaPrincipal); --Crea ventana
   Gtk.Box.Gtk_New_HBox (ContenedorMain, True, 0);

   -- Nada m�s empezar, enlazamos la se�al de quit al bot�n de cerrar,

   Return_Handlers.Connect (VentanaPrincipal, "delete_event",
                            Return_Handlers.To_Marshaller
(Delete_Event'Access));

   Gtk.Frame.Gtk_New (FrameMatriz, "Vista de la matriz celular");
   -- Creamos la matriz de im�genes y la enmarcamos en los Boxes
   Gtk.Box.Gtk_New_VBox (ContCont, True, 0);
   Estilo:=Gtk.Window.Get_Style(VentanaPrincipal);

   -- Asignamos las imagenes a los Pixmap
   Gdk.Pixmap.Create_from_Xpm (I_Sana, null, Mascara,
Gtk.Style.Get_Bg(Estilo, Gtk.Enums.State_Normal), "new.xpm");
   Gdk.Pixmap.Create_from_Xpm (I_Enferma, null, Mascara,
Gtk.Style.Get_Bg(Estilo, Gtk.Enums.State_Normal), "open.xpm");

   for i in 1..12 loop
     Gtk.Box.Gtk_New_HBox (Cont(i), True, 0);
     for j in 1..14 loop
          Gtk.Pixmap.Gtk_New(Matriz(j, i).imagen, I_Sana, Mascara);
          Gtk.Pixmap.Show(Matriz(j, i).imagen);
          Gtk.Box.Add(Cont(i), Matriz(j, i).imagen);
     end loop;
     Gtk.Box.Show (Cont(i));
     Gtk.Box.Add (ContCont, Cont(i));
   end loop;

   -- A�adimos un Contenedor Horizontal a la ventana
   Gtk.Box.Show (ContCont);
   Gtk.Frame.Add (FrameMatriz, ContCont);
   Gtk.Frame.Show (FrameMatriz);

   -- Creamos el bot�n de comienzo, su callback y lo a�adimos al lienzo
   Gtk.Button.Gtk_New(BotonComenzar);
   Handlers.Object_Connect (BotonComenzar, "clicked",
                            Handlers.To_Marshaller
(HandlerBotonComenzar'Access)
                            ,VentanaPrincipal);
   Gtk.Label.Gtk_New(EtiquetaBoton, "Comenzar simulacion");
   Gtk.Label.Show(EtiquetaBoton);
   Gtk.Button.Add(BotonComenzar, EtiquetaBoton);
   Gtk.Button.Show(BotonComenzar);
   Gtk.Frame.Gtk_New(FrameBotones, "Controles");
   Gtk.Frame.Add (FrameBotones, BotonComenzar);
   Gtk.Frame.Show (FrameBotones);

   -- Metemos los dos frames en el contenedor principal
   Gtk.Box.Add (ContenedorMain, FrameMatriz);
   Gtk.Box.Add (ContenedorMain, FrameBotones);
   Gtk.Box.Show (ContenedorMain);
   Gtk.Window.Add (VentanaPrincipal, ContenedorMain);

   -- Y ahora, con dos cojones, modificamos din�micamente un bitmap a ver
si tira
   -- Gtk.Pixmap.Set (Matriz(1,1), I_Enferma, Mascara);

   Gtk.Window.Show(VentanaPrincipal); -- La muestra
   -- Gtk.Pixmap.Set (Matriz(1,1), I_Enferma, Mascara);
   Gtk.Main.Main;
 end dibujar_interfaz;
end interfaz;

with Gtk.Widget;
with Gtk.Handlers;

package manejadores is

  function Delete_Event
    (Widget : access Gtk.Widget.Gtk_Widget_Record'Class) return Boolean;

  procedure HandlerBotonComenzar (Widget : access
Gtk.Widget.Gtk_Widget_Record'Class);

  package Handlers is new Gtk.Handlers.Callback
    (Gtk.Widget.Gtk_Widget_Record);

  package Return_Handlers is new Gtk.Handlers.Return_Callback
    (Gtk.Widget.Gtk_Widget_Record, Boolean);

end manejadores;
with Gtk.Main;
with interfaz; use interfaz;
with Gtk.Pixmap;
with ptareamain; use ptareamain;

package body manejadores is

 -- manejador de darle al aspa de la ventana
  function Delete_Event (Widget : access
Gtk.Widget.Gtk_Widget_Record'Class) return Boolean is
    begin
      Gtk.Main.Main_Quit;
      return False;
  end Delete_Event;

 -- manejador de comienzo de la simulaci�n

  procedure HandlerBotonComenzar (Widget : access
Gtk.Widget.Gtk_Widget_Record'Class) is
    -- Crea una c�lula que ser� la encargada de crear todo lo dem�s
    -- Creates a cell that will be the one that will create the rest of
the cells
     type tt is access tareamain; t:tt;
   begin
     t:=new tareamain;
   end HandlerBotonComenzar;

end manejadores;

package pprotegido is
  type estado is (vacia, sana, enferma, i_energia, d_energia, ar_energia,
ab_energia, muerta);
  protected cerrojorecursos is   --protected object that implements the
exclusive access to the bi-dimensional array
    procedure set_estado(px, py: integer; e: estado);
    function get_estado(px, py: integer) return estado;
  end cerrojorecursos;
end pprotegido;

with interfaz; use interfaz;
with Gtk.Pixmap; with Gdk.Main;
with ptareas; use ptareas;

package body pprotegido is

  protected body cerrojorecursos is
    procedure set_estado(px, py:integer; e: estado) is
     begin
        case e is
        when vacia=> Gtk.Pixmap.Set (Matriz (px, py).imagen, I_Enferma,
Mascara);
                     Matriz(px, py).e := vacia;
        when sana=> Gtk.Pixmap.Set (Matriz (px, py).imagen, I_Enferma,
Mascara);
                     Matriz(px, py).e := sana;
        when enferma=> Gtk.Pixmap.Set (Matriz (px, py).imagen, I_Enferma,
Mascara);
                     Matriz(px, py).e := enferma;
        when i_energia=> Gtk.Pixmap.Set (Matriz (px, py).imagen,
I_Enferma, Mascara);
                     Matriz(px, py).e := i_energia;
        when d_energia=> Gtk.Pixmap.Set (Matriz (px, py).imagen,
I_Enferma, Mascara);
                     Matriz(px, py).e := d_energia;
        when ar_energia=> Gtk.Pixmap.Set (Matriz (px, py).imagen,
I_Enferma, Mascara);
                     Matriz(px, py).e := ar_energia;
        when ab_energia=> Gtk.Pixmap.Set (Matriz (px, py).imagen,
I_Enferma, Mascara);
                     Matriz(px, py).e := ab_energia;
        when muerta=> Gtk.Pixmap.Set (Matriz (px, py).imagen, I_Enferma,
Mascara);
                     Matriz(px, py).e := muerta;
       end case;
    end set_estado;

    function get_estado(px, py: integer) return estado is
     begin
        return matriz(px, py).e;
    end get_estado;

  end cerrojorecursos;

end pprotegido;

package ptareas is

  type posicion is record
    px, py: integer;
   end record;

  task type celula(inicial: access posicion);

end ptareas;

with pprotegido; use pprotegido;
with interfaz; use interfaz;
with Ada.Text_io; use Ada.Text_Io;

package body ptareas is

   type a is access celula;

   task body celula is
     anon:a;-- C�lulas an�nimas que vamos creando
    begin
     -- Aqu� el cuerpo principal activo
     -- 1. La c�lula nace. Coloca su estado.
     cerrojorecursos.set_estado(inicial.px, inicial.py, sana);

     -- 1.5. La c�lula hace un delay, porque si no esto no se muestra
como es debido

     -- 2. La c�lula debe crecer, intentando ocupar sus cuatro c�lulas
adyacentes
     -- Como convenci�n, siempre seguir� para hacer los ensayos, de
izquierda a derecha desde la izquierda
     if cerrojorecursos.get_estado(inicial.px-1, inicial.py) = vacia then

        crear_nueva_celula(inicial.px-1, inicial.py);
     end if;
     if cerrojorecursos.get_estado(inicial.px, inicial.py-1) = vacia then

        crear_nueva_celula(inicial.px, inicial.py-1);
     end if;
     if cerrojorecursos.get_estado(inicial.px+1, inicial.py) = vacia then

        crear_nueva_celula(inicial.px+1, inicial.py);
     end if;
     if cerrojorecursos.get_estado(inicial.px, inicial.py+1) = vacia then

        crear_nueva_celula(inicial.px, inicial.py+1);
     end if;
   delay 2.0;
   Put ("Soy una c�lula que voy a morir.");
   end celula;

end ptareas;


with interfaz; use interfaz;

procedure main is
   begin
    dibujar_interfaz;
 end principal;
<---cut-->

Thanks for everything.

Carlos.





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem with gtkada and tasks
  2001-07-30 16:57 ` David Monterroso Cabello
@ 2001-07-31  0:40   ` MCL
  2001-07-31 11:17   ` Frank
  1 sibling, 0 replies; 7+ messages in thread
From: MCL @ 2001-07-31  0:40 UTC (permalink / raw)



> So I'm going to try, in my poor english, to fully explain it:

    Practice makes perfect.


> The purpose of the program is to create a simulation in which a cell
> is represented by an Ada95 task, and it is capable of replicating by
> itself.

    I do not know if this is a requirement of the problem.  In any
case, although this is conceptually valid, isn't a bit of a waste?
Unless you really want to let cells "live" at a rate which is not set
by you, but by the underlying scheduler.  The final restult, I am
afraid, can be disappointing.

    On the other hand you just call a thread-unprotected
Gtk.Main.Main while other tasks update the graphical objects.  This is
highly unreliable!  Chances are that concurrent updates will corrupt
the shared data.  Go to the GtkAda user & reference manual, look up
"tasking".


>    --Y tenemos que hacerlo usando el soporte de threads de gtkada. SU
>      PUTA MADRE.

    Yes, that is right.  You have to take care of concurrent updates.
Note that even if you update the state within a protected object, the
Main loop is *not* in exclusive access.

    As I pointed out before, the only reliable way to do this I've
found is to make every Gtk-related operation from within the *same
task*.  OTOH, I am not an experienced Gtk/Ada programmer, so there may
be a simpler way.


-- 
          ||            Manuel Carro -- DLSIIS            ||
          ||           e-mail: mcarro@fi.upm.es           ||
          ||      http://lml.ls.fi.upm.es/~boris          ||
          ||    http://clip.dia.fi.upm.es/Software/Ciao   ||
          || Phone: +34 91 336-7455  FAX: +34 91 336-7412 ||




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem with gtkada and tasks
  2001-07-30 16:57 ` David Monterroso Cabello
  2001-07-31  0:40   ` MCL
@ 2001-07-31 11:17   ` Frank
  1 sibling, 0 replies; 7+ messages in thread
From: Frank @ 2001-07-31 11:17 UTC (permalink / raw)


Hi!

Could it be that you are missing a call to the Draw-method to the drawing
area after you have changed the GUI?
Try to look at the scribble-example in the GtkAda installation (called
scribble.adb) where a pixmap is copied to the drawing area when you click
the mouse button.

Frank





^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2001-07-31 11:17 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-07-25  8:53 Problem with gtkada and tasks Carlos Aganzo
2001-07-26 16:07 ` Ted Dennison
2001-07-27  8:16   ` Carlos Aganzo
2001-07-27 12:31     ` Manuel Carro
2001-07-30 16:57 ` David Monterroso Cabello
2001-07-31  0:40   ` MCL
2001-07-31 11:17   ` Frank

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox