/*
 * kpvm.h
 *
 * Copyright (c) 1998 Michael Kropfberger <michael.kropfberger@gmx.net>
 *
 * Requires the Qt widget libraries, available at no cost at
 * http://www.troll.no/
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */


#ifndef __KPVM_H__
#define __KPVM_H__

#include <stdio.h>
#include <stdlib.h>

#include <qobject.h>
#include <qwidget.h>
#include <qstring.h>
#include <qdict.h>

#include "serialize.h"
#include "vartuple.h"
#include "kpvm_entity.h"

/** 
  * @short KPvm is the Main PVM-Wrapper. 
  * KPVm stands for the local running pvm-process so there must be exactly one 
  * instance of KPvm.
  * It provides the basic functions and handles them through to the non-OO pvm.
  * @author Michael Kropfberger <michael.kropfberger@gmx.net>
 **/
class KPvm : public QWidget
{ Q_OBJECT

  public:

    KPvm(QWidget *parent=0, const char *name=0);

    ~KPvm() {};

    /**
      * checks if this object has a spawning parent or not.
     **/
    bool hasPvmParent();

    /**
      * returns a @ref KPvmParent object of the spawning parent or NULL if
      * there is no parent.
     **/
    KPvmParent* pvmParent() { return _parent; };

    /**
      * returns the TaskId of the main KPvm-Object
     **/
    int tid() const {return pvm_mytid();};

    /**
      * returns the hostname on which this main KPvm-Object is running
     **/
    QString hostName() const ;

    /**
      * creates numProc tasks and returns a QList< @ref KPvmChild >
      * representing the newly created tasks.
      * @param fname Filename of the pvm-executable (may also be non-OO-pvm). 
                     If fname is not an absolute file, the actual working 
                     directory path  is added.
      * @param flag  same as the non-OO-pvm spawn <BR>
      *          PvmDataDefault-->PVM can choose any host to start on <BR>
      *          PvmTaskHost-->where contains the hostname to start on <BR>
      *          PvmTaskArch-->where contains the architecture to start on
      * @param argv argument vector for the invoked fname
      * @param numProc number of tasks to spawn
     **/
    QList<KPvmChild>  spawn(QString fname, char **argv=0
                                , int flag=PvmDataDefault
                                , QString where=""
                               , int numProc=1 );
 

  public slots:

    /**
      * sends a child of @ref Persist to a @ref KPvmEntity with a msgtag.
      * Persist::objState of the child of @ref Persist is called and
      * this state is then packaged and sent to @ref KPvmEntity.
      * @param sendNetEfficient true (default) packs the types and looses 
                                  the VarTags <BR>
                                false packs the whole VarTuples incl. VarTags
                                  as strings
     **/
    void send(KPvmEntity* entity, Serialize* data
              , int msgtag, bool sendNetEfficient=true);

    /**
      * changes the interval in which it is looked for newly received data.
      * When this object is constructed, a 20 msec Interval is installed.
     **/
    void changeCheckInterval(int msecs);
    
  signals:

    /**
      * dataRecieved is the most important signal, as it passes all received 
      * data to the connected slots.
      * You have to connect an object-generating slot to it (see kpvm-example)
      * where you go through all your possibly sendable Classes (inheriting 
      * Persist) and create an apropriate class and fill it with 
      * @ref #setObjState
      *
      * If your programm works im different steps (eg. Database split -> join 
      * -> merge back) you may want to have different handling slots and you
      * may want to connect/disconnect to the dataHandler needed...
    **/
    void dataReceived(QString className, QList<VarTuple> objState
                      , int msgtag, KPvmEntity *entity);


 protected:

    /**
      * this is internally used to store every known @ref KPvmEntity
      * which was spawned by KPvm or the local parent.
     **/
    void insertNewEntity(KPvmEntity *ent);


 protected slots:

  /**
    * checks in constant time intervals if there is incoming 
    * @ref KPersist data from other tasks.
   **/   
    void checkRecv();

  /**
    * is called to exit cleanly from Qt and pvm.
   **/   
    void exit();

 private:

    QDict<KPvmEntity> _knownEntities;

    KPvmParent       *_parent;

    int               _interval;
   
    bool              _exit;
  
};

#endif

Documentation generated by mike@kermit on Mon Jun 29 21:55:33 MEST 1998