/*---------------------------------------------------------------------------
                   		T A S K
                   		
  This is a portable task switching module. Tasks are maintained in a 
  circular list and switched in between. Waiting for some task to end,
  a yield and a primitive form of inter task communication is implemented.
  
  Mark Koennecke, September 1997
  
  copyright: see implementation file
-----------------------------------------------------------------------------*/
#ifndef TASKOMAT
#define TASKOMAT

/*---------------------------------------------------------------------------*/
  typedef int (*TaskFunc)(void *pData);

/* 
   a task function must be implemented by each task. This function will be
   called when it is the tasks turn to execute. This function obtains a 
   pointer to a user defined data structure as parameter. If the task is going
   to end, it has to return 0. It's data structure will be removed by a
   KillFunction of the type defined below.  If the task is
   going to run again in its next turn the task function has to return a
   1.
*/
/*--------------------------------------------------------------------------*/
  typedef void (*TaskKillFunc)(void *pData);
/*
   Each task using private data structures must define this functions. It's 
   task is to clear the private data structure of the task and free all memory
   associated with it. This function will be called automatically by the
   Tasker when a task finishes or when the whole Tasker is shut down.
*/     
/*---------------------------------------------------------------------------*/
  typedef void (*SignalFunc)(void *pUser,int iSignal, void *pSigData);

/*
   A SignalFunction can be implemented by each task. It is the means of
   inter task communication. The first parameter is a pointer to the
   tasks private datastructure. Further parameters are an integer signal ID 
   and a pointer to a datastructure  for this signal. The meaning of signal 
   ID's  and signal data structures is up to the client of this code.
*/
/*--------------------------------------------------------------------------*/
  typedef struct __TaskHead *pTaskHead;
  typedef struct __TaskMan  *pTaskMan;
/*
   two data structure used internally and defined in task.c
*/
/*===========================================================================
   ALL FUNTIONS RETURN 0 on FAILURE, 1 ON SUCCESS WHEN NOT MENTIONED
                         OTHERWISE
============================================================================*/                         
  int TaskerInit(pTaskMan *self);
  /*
     Initalises a Task Manager. 
  */   
  int TaskerDelete(pTaskMan *self);
  /*
    Stops all running tasks and clears all data structures associated with
    tasks and the TaskManager.
  */
/*--------------------------------------------------------------------------*/
  long TaskRegister(pTaskMan self, TaskFunc    pTaskRun,
                                  SignalFunc  pSignalFunc,
                                  TaskKillFunc    pKillFunc,
                                  void *pData,
                                  int iPriority);
  /*
    This call enter a new task into the system. The caller has to
    specify:
        a TaskFunction   [Required]
        a SignalFunction [Optional, can be NULL]
        a KillFunction for task private data.
                         [Optional, can be NULL]
        a pointer to task  private data     
                         [Optional, can be NULL]
        a priority for this task. This is currently unused.                  
    On Success a positive value denoting the ID of the task is returned.
    On error a negative value is returned.
    */
/*-------------------------------------------------------------------------*/                                                                 
  int TaskSchedule(pTaskMan self);
  /*
    Starts task switching.
  */
/*-----------------------------------------------------------------------*/
  int TaskStop(pTaskMan self);
  /*
    Interrupts task switching all together
  */    
/*------------------------------------------------------------------------*/
  int TaskContinue(pTaskMan self);
  /* 
    Continues an task switching session interrupted by TaskStop. After this
    the apopriate TaskYield, TaskSchedule or wahtever has to be called.
  */  
/*-------------------------------------------------------------------------*/
  int TaskWait(pTaskMan self, long lID);
  /*
    Waits until the task specified by lID has finished. lID is obtained from
    a call to TaskRegister.
  */
/*-------------------------------------------------------------------------*/
  int TaskYield(pTaskMan self);
  /*
    does one cycle of the task loop and returns to the caller.This call allows
    other tasks to execute while a task executeds a lengthy calculation. 
  */  
/*--------------------------------------------------------------------------*/
  int TaskSignal(pTaskMan self, int iSignal, void *pSigData);
  /*
    Invokes each Task's signal function with parameters iSignal and
    pSigData. 
  */            
/*-------------------------------------------------------------------------*/
    
#endif

  