/* Classe d'objets avec une methode (DoPeriodic()) appelee periodiquement */ /* Eric Aubourg 04/96 */ /* Reza Ansari 06/96 */ /* LAL/IN2P3 (Orsay) DAPNIA/CEA (Saclay) */ #include "machdefs.h" #include #include #include "periodic.h" /*! \class SOPHYA::Periodic \ingroup SysTools This class provide the service of calling a given function at regular intervals. It can also be subclassed with the method \b DoPeriodic redefined to perform a periodic action. */ //++ // Class Periodic // Lib SysTools // include periodic.h // // Classe d'objets avec une méthode "DoPeriodic()" appelée périodiquement // à intervalle régulier. //-- //++ // Titre Constructeur, méthodes //-- //++ // Periodic(int dt, UsPeriodicAction act=NULL, void * usp=NULL) // Constructeur avec un intervalle de temps en secondes "dt". // Il est possible de spécifier une fonction "UsPeriodicAction" avec // un argument "usp" qui sera appelée régulierement. //| typedef void (* UsPeriodicAction) (void *); //-- //++ // void Start(int dt=-1) // Activation de l'objet périodique. // On peut spécifier l'intervalle en temps (en secondes) si "dt > 0". // void Stop() // Désactivation de l'objet périodique. // void DoPeriodic() // Méthode virtuelle qui peut être surchargée dans les classes dérivées. // Elle est appelée lorsque l'intervalle de temps est écoulé. Par défaut, // elle appelle la fonction "UsPeriodicAction" associée si "!= NULL" //-- /* --Methode-- */ /*! Constructor with the definition of the interval (in seconds) and an optional user action */ Periodic::Periodic(int dt, UsPeriodicAction act, void * usp) { mDt = dt; mAct = act; mUsp = usp; if (mDt < 1) mDt = 5; mDtms = 1000*mDt; mFgact = false; it = -1; } /* --Methode-- */ Periodic::~Periodic() { if (mFgact) Stop(); } /* --Methode-- */ /*! Sets the user action function and its data \c usp */ void Periodic::SetAction(UsPeriodicAction act, void * usp) { mAct = act; mUsp = usp; } /* --Methode-- */ /*! Changes the interval \c dt specified in seconds */ void Periodic::SetInterval(int dt) { mDt = dt; if (mDt < 1) mDt = 5; mDtms = 1000*mDt; } /* --Methode-- */ /*! Changes the interval \c dtms specified in milli-seconds */ void Periodic::SetIntervalms(int dtms) { if (dtms < 1) dtms = 5; mDtms = dtms; mDt = mDtms/1000; if (mDt < 1) mDt = 1; } /* --Methode-- */ /*! Activate the object */ void Periodic::Start(int dt) { if (mFgact) return; if (dt > 0) { mDt = dt; mDtms = dt*1000; } if (!actifs) actifs = new PeriodicList; it = 0; if (actifs->size() == 0) { signal(SIGALRM, CallBack); alarm(1); } actifs->push_back(this); mFgact = true; return; } /* --Methode-- */ /*! Deactivate the object */ void Periodic::Stop() { if (!mFgact) return; //remove(actifs->begin(), actifs->end(), this); // $CHECK$ - Reza actifs->remove(this); // $CHECK$ if (actifs->size() == 0) { signal(SIGALRM, SIG_IGN); alarm(0); delete actifs; actifs = NULL; } it = -1; mFgact = false; return; } /* --Methode-- */ /*! This method should be redefined for sub-classes of Periodic The default implementation calls the user action function */ void Periodic::DoPeriodic() { if (mAct) mAct(mUsp); } PeriodicList* Periodic::actifs = NULL; void Periodic::CallBack(int) { if (!actifs) return; for (PeriodicList::iterator i = actifs->begin(); i != actifs->end(); i++) { Periodic* p = (Periodic*) *i; p->it ++; if (p->it >= p->mDt) { p->it = 0; p->DoPeriodic(); } } alarm(1); }