[comp.sys.amiga.programmer] "Task"'ing trubbles

schwager@m.cs.uiuc.edu (Michael Schwager) (05/21/91)

Vital stats:  Amiga 500 w/ 3Meg ram, 30 Meg hard drive, using Aztec C 5.0d.
Greets,
I have a small (13 x 13 pixels) box in a window in a CUSTOMSCREEN.  I want
to make it flash, and I want it to quit flashing when the user hits another
box.  No sweat, right?  I figger the best way to do this is to set up a
little task running asynchronously that will do the flashing, so that the
main program can wait for messages and kill the little flasher when a
proper gadget is hit.

So, it doesn't work.  My main program calls the function "flash" that
creates the Task "flashTask".  The Task "flashTask" calls another function
named "myDelay"... it works just like DOS' Delay() but using timer.device.
I kill the task later in the program with a DeleteTask().  My algorithms
worked when I was using simple functions (at that time, I had to limit the
number of flashes so that I could go on and wait for another message).  I
want to make this as generic as possible, so I have some parameters come in
as arguments to "flash".  In the future I'll want to flash any Image in any
window.  For now, my Image structure is very simple: no data, just a
rectangle and manipulation of PlaneOnOff.

In general, I'm somewhat confused about what's legal with Tasks... can I
treat 'em just like any other function in my program?  Even give them
arguments?
Here's some pertinent code; any pointers or help would be appreciated.

#include "myprogp.h"
/* Intuition MUST be open for this, cuz it uses DrawImage! */
#define FLASHNAME "JohnnyFlash"
#define FLASHSTK 3000

struct Task *flashTCB = NULL;

/* I tried declaring the next three lines as static, but it didn't help. */
struct Window *flash_Window;
struct Image *flash_Image;
int x, y, mycolor;

struct Task *
flash (flash_Window, flash_Image, x, y, mycolor)

{
  int i;
  void flashTask();
  
  flashTCB = (struct Task *) FindTask (FLASHNAME);
  if (flashTCB) shutdown ("GAACK!  Two flashing things at once!!?!");
  
/* flashTask is killed with a DeleteTask(flashTCB) elsewhere in the
     program; flashTCB is declared as extern there */
  flashTCB = (struct Task *) CreateTask (FLASHNAME, 0, flashTask, FLASHSTK);
  return (flashTCB);
}

void
flashTask ()

{
  geta4 ();
  for (;;) {
    flash_Image->PlaneOnOff = WHITE;
    DrawImage (flash_Window->RPort, flash_Image, x, y);
    flash_Image->PlaneOnOff = mycolor;
    myDelay(8);
    DrawImage (flash_Window->RPort, flash_Image, x, y);
    myDelay(12);
  }
}

-Mike Schwager                             | Machine: Amiga 500, 3 MB RAM/30 HD
INTERNET:schwager@cs.uiuc.edu              | Bike: '83 Kawasaki KZ750 LTD
UUCP:{uunet|convex|pur-ee}!uiucdcs!schwager| Band: Poi Dog Pondering      //
BITNET:schwager@mike.cs.uiuc.edu           | Hero: Robert Bly         \\ //
University of Illinois, Dept. of Comp. Sci.| DoD: #0301                \X/Amiga

jap@convex.cl.msu.edu (Joe Porkka) (05/21/91)

schwager@m.cs.uiuc.edu (Michael Schwager) writes:


>Vital stats:  Amiga 500 w/ 3Meg ram, 30 Meg hard drive, using Aztec C 5.0d.
>Greets,
>I have a small (13 x 13 pixels) box in a window in a CUSTOMSCREEN.  I want
>to make it flash, and I want it to quit flashing when the user hits another
>box.  No sweat, right?  I figger the best way to do this is to set up a
>little task running asynchronously that will do the flashing, so that the
>main program can wait for messages and kill the little flasher when a
>proper gadget is hit.

You could do it without another task by arranging for timer.device
evetns to signal you (which would be noticed by Wait()), then simply call
Flashit() to blink the box once, reset the timer and return.

Instead of using timer.device you could also use IntuiTicks, which
come by at 10Hz, and you only see them when your window is active - thus
you box would not eat CPU if the users flipped screens and started working
on other stuff.

tscott@isis.cs.du.edu (Tony D Scott) (05/21/91)

Have you considered doing this during the vertical blank or perhaps
installing an interrupt handler for the input.device instead.  It would
limit you to doing it very quickly so as to not interfere with other
events, but depending on your application, it might be feasable.
 
Tony Scott
tscott@isis

fjrei@kbsaar.UUCP (Franz-Josef Reichert) (05/23/91)

In article <1991May21.063012.1358@m.cs.uiuc.edu> schwager@m.cs.uiuc.edu (Michael Schwager) writes:
>So, it doesn't work.  My main program calls the function "flash" that
>creates the Task "flashTask".  The Task "flashTask" calls another function
>named "myDelay"... it works just like DOS' Delay() but using timer.device.

Who is setting up the MsgPort/timerequest for your timer.device stuff?
As I see, flashTask() didn't! So the mp_SigTask may be wrong (i.e.
contain the address of the parent task's control block), which will cause
flashTask() waiting forever for a signal which never occures.  

--
Best regards,
Franz-Josef Reichert      VOICE: +49 6805 7417
Kuchlingerstrasse 13      UUCP:  ...uunet!cbmvax!cbmehq!cbmger!kbsaar!fjrei
D-6601 Kleinblittersdorf  GERMANY

schwager@m.cs.uiuc.edu (Michael Schwager) (05/24/91)

fjrei@kbsaar.UUCP (Franz-Josef Reichert) writes:

>In article <1991May21.063012.1358@m.cs.uiuc.edu> schwager@m.cs.uiuc.edu (Michael Schwager) writes:
>>So, it doesn't work.  My main program calls the function "flash" that
>>creates the Task "flashTask".  The Task "flashTask" calls another function
>>named "myDelay"... it works just like DOS' Delay() but using timer.device.

>Who is setting up the MsgPort/timerequest for your timer.device stuff?
>As I see, flashTask() didn't! So the mp_SigTask may be wrong (i.e.
>contain the address of the parent task's control block), which will cause
>flashTask() waiting forever for a signal which never occures.  

Ahhh!  Thanks!  I had figured out that it was waiting forever in myDelay(),
but I didn't quite understand why.  Now I get it!  Indeed, using AskTask
showed that my new task was waiting for a signal.  Thanks muchly.
-Mike