Gestion tu temps, créez votre propre "library"

Proposé par nabouill

le 28 January 2010 à 13h 44mn 40s

8224 visualisations

  Créez votre propre library pour gérer le temps dans vos programmes.
Pour appeler une fonction à interval régulier, savoir combien de temps s'est écoulé depuis l'instant T, mettre le programme en pause pour alléger un peu les ressource demander au CPU, récupérer le temps écoulé pour faire un compteur ...   





Voici une petite classe que je ne cesse d'améliorer, très simple mais très pratique. je vais directement mettre le code et on va voir ensuite ce qu'on peu en faire.

Le code
Comment ça marche ?
mettre ça en DLL


Le code
Commençons par MyTimer.h :

Code c++ :



#ifndef __MyTimer_H__
#define __MyTimer_H__

#include <ctime> // for clock()
#include <windows.h> // for Sleep()


class  MyTimer
{
    public:
        MyTimer(int t_ms_interval);

        ///methodes
        bool isExceed();       //renvoie "true" si l'interval temps est depassé
        int getInterval();     //renvoie l'interval definie
        int getTimeExceedMs(); // renvoie les temps passé en ms depuis la derniere mise a jour
        int getTimeExceedSc(); // renvoie les temps passé en seconde depuis la derniere mise a jour
        int getTimeUntilMS();  //renvoie le temps restant en milliseconde
        int getTimeUntilSc();  //renvoie le temps restant en seconde
        void reset();          //remise a zero du temps passé
        void setInterval(int t_ms_interval);  //redéfini l'interval
        void waitUntilInterval();        //endort le programme jusqu'a ce que l'interval soit dépassé
        void waitAll(int t_ms_interval); // endort le programme pendant le temps t_intrerval

    private:

        clock_t timeExceed; //enregistre le temps a l'instant T
        clock_t actualTime; //enregistre le temps a l'instant T
        int interval;       //gestion de l'interval Temps en millisecondes

};

#endif





Puis MyTimer.cpp

Code c++ :


#include "MyTimer.h"


// constructeur
MyTimer::MyTimer(int t_ms_interval)
{
    interval = t_ms_interval;
    actualTime = clock();
    timeExceed = clock();
}


    ///***********************************************************************

int MyTimer::getTimeExceedMs()
{
    actualTime = clock();
    int timeTempo = actualTime - timeExceed;
    return timeTempo;
}

    ///***********************************************************************

int MyTimer::getTimeExceedSc()
{
    actualTime = clock();
    int timeTempo = actualTime - timeExceed;
    int seconde = timeTempo / 1000;
    return seconde;
}

    ///***********************************************************************

int MyTimer::getTimeUntilMS()
{
    int timeTempo = interval - getTimeExceedMs();
    return timeTempo;
}

    ///***********************************************************************

int MyTimer::getTimeUntilSc()
{
    int seconde = (interval - getTimeExceedMs()) / 1000;
    return seconde;
}

    ///***********************************************************************


bool MyTimer::isExceed()
{
    actualTime = clock();
    if(actualTime - timeExceed > interval)
    {
        timeExceed = actualTime;
        return true;
    }
    else
    {
        return false;
    }
}

    ///***********************************************************************

void MyTimer::setInterval(int t_ms_interval)
{
    interval = t_ms_interval;
}

    ///***********************************************************************

int MyTimer::getInterval()
{
    return interval;
}

    ///***********************************************************************

void MyTimer::reset()
{
    actualTime = clock();
    timeExceed = clock();
}

    ///***********************************************************************

void MyTimer::waitUntilInterval()
{
    if(!isExceed())
    {
        Sleep(interval - getTimeExceedMs());
        actualTime = clock();
        timeExceed = clock();
    }
}

    ///***********************************************************************

void MyTimer::waitAll(int t_ms_interval)
{
    Sleep(t_ms_interval);
}






Comment ça marche ?

Petit exemple:

Les trucs de base:

Code c++ :


MyTimer timer(1000);
timer.setInterval(5000); //change l'interval temps (en ms)

//executer un fonction que si l'interval temps et dépassé
if(timer.isExceed())
{
      //je fais mon truc
}

//je veut créer un boucle qui dur le temp de mon interval
while(!timer.isExceed())
{
}

//je recupère mon interval
int intervalTemp = timer.getInterval();


Faire une pause, alléger les ressources cpu:

Code c++ :

MyTimer timer(1000);

//je mais mon programme en pause seulement le temps restant de mon interval
timer.waitUntilInterval();

//je met mon programme en pause le temps que je veux, sans modifier l'interval de timer
timer.waitAll(10000);

//je reset mon timer , c'est a dire que je remet le temps actuel  et le temps passé a l'instant T
timer.reset();


Chronmètre / compte à rebour:

Code c++ :

MyTimer timer(10000); //un interval de 10 secondes

//**** exemple chronomètre

while(1)
{
     cout << timer.getTimeExceedMs() << endl; //affiche le temps ecoulé depuis le début du timer (en ms)
     cout << timer.getTimeExceedSc() << endl; //affiche le temps ecoulé depuis le début du timer (en seconde)
       /*je me permet de préciser que cette méthode ne reset jamais le timer,
          donc peut importe son interval défini il continuera indéfiniment*/

}

//**** exemple compte a rebours

while(1)
{
     cout << timer.getTimeUntilMs() << endl; //affiche le temps restant avant la fin du timer (en ms)
     cout << timer.getTimeUntilSc() << endl; //affiche le temps restant avant la fin du timer (en seconde)
      /* là encore, le timer ne sera jamais réinitialiser, donc attention si vous ne souhaiter pas rentrer dans les valeurs négative
          la mise en place d'un   if(timer.isExceed()) peut s'avérer utile pour arrêter pile a 0 */

}




mettre ça en DLL


Pour une utilisation fréquente dans vos programmes, je vous propose de créer un lib pour facilité sont intégration.

Avec Code::Blocks créez un projet "Dynamic Link Library", supprimez les fichiers crée automatiquement.
Puis créer les 2 fichiers "MyTimer.cpp" et "MyTimer.h" (ou appelez les comme vous voulez)
Compilez. Et vous obtenez une belle DLL (de 6,5 ko)  et un fichier .a smile

Et pour ceux qui n'aurait pas code::blocks (où les fainéant ... si si je sait qu'il y en a wink )
je vous laisse les télécharger sur ce lien:
fichier.dll+fichier.a+fichier.h


Semblerait-il que pour faire fonctionner ce code sous linux, il faut remplacer #include <windows.h> par #include <unistd.h>.
Perso, je n'ai pas essayé, mais si quelqu'un peut me le confirmer...

#1 

28-01-2010 16:01:19

nico
Webmaster
Date d'inscription: 07-08-2009
Messages: 563
Corrections: 9

Merci nabouill, cette classe à l'air pratique.
Je m'interroge juste sur <ctime>, je sais plus trop où sur le net, j'ai récupéré une classe exemple qui utilise la fréquence de l'horloge pour chronométrer, Donc je voulais savoir si il y a des différences au niveau de la précision ? télécharger exemple 64 bit

Hors ligne


#2 

28-01-2010 17:13:45

TUpac
Habitué
Date d'inscription: 08-09-2009
Messages: 387
Corrections: 1

Beau boulot nabouille mais on trouve l'équivalence sous irrlicht je crois non ?


"Si vous ne partagez pas votre stabilité avec les pauvres, les pauvres partageront leur instabilité avec vous."

Hors ligne


#3 

29-01-2010 22:27:27

nabouill
Abonné
Date d'inscription: 17-09-2009
Messages: 242
Corrections: 1

Merci à vous.

nico :

Je m'interroge juste sur <ctime>


Effectivement, ce serait un peut l'équivalent de time.h plus révolue et réservé au C++ d'après ce que j'ai trouvé (ne pas confondre avec le fichier time.h sur ton lien)
mais je ne saurait te dire si il est plus précis ou non.

TUpac :

mais on trouve l'équivalence sous irrlicht je crois non ?


J'ai bien vue une sorte de gestion de temps dans Irrlicht oui mais je ne l'ai pas bien saisie, du moins ce que j'en ai compris ne me paraissait pas très pratique (ça vient peut-être de moi aussi)
du coup a force de me créer des petite fonction un peu partout dans chaque projet et faire des copier coller a chaque coup, j'ai penser de créer une petite lib pour gérer ça deviendrais plus pratique.

En attendant, si vous avez des idée d'amélioration... faite signe


mes sites: www.manga-vf.fr et www.series-vf.fr

Hors ligne


#4 

30-01-2010 02:48:31

nico
Webmaster
Date d'inscription: 07-08-2009
Messages: 563
Corrections: 9

coucou, comme amélioration je verrai bien une suppression des fonctions qui retournent le temps en seconde,
je trouve que ça alourdi la classe et qu'il serait préférable d'adopté une solution plus succinte.
tu pourrait aussi passer par une liste d'initialisation pour les objets afin de réduire encore le code, puis supprimer la fonction de destruction de l'objet qui est vide, pour encore grappiller de la place. cela dit c'est vraiment du chipotage hein wink
et une version française en option tongue

edit: j'ai bloqué sur le terme "wait", ça me parait bizarre avec l'utilisation de sleep(), qu'en pensez-vous ?

Hors ligne


#5 

31-01-2010 22:15:08

nabouill
Abonné
Date d'inscription: 17-09-2009
Messages: 242
Corrections: 1

nico :

je verrai bien une suppression des fonctions qui retournent le temps en seconde,


Oui, c'est vrai que j'ai hésiter un peu a la mettre celle là, mais l'idée était que ce serait plus simple pour intégrer un chrono dans un programme, car sinon on devrait récupère le temps en ms puis faire le calcule pour afficher le temps en seconde, ce qui du coup alourdirais le code du programme. En somme l'un où l'autre.. c'est vrai que ça porte à réflexion. (mais perso, je préfère alléger mes programmes, ce qui n'engage que moi bien sûr).

nico :

tu pourrait aussi passer par une liste d'initialisation pour les objets afin de réduire encore le code


C'est vrai, je les écrit comme çà par habitude, car j'ai toujours trouvé çà plus facile à lire. Mais ça pourrait bien faire l'objet d'une modification, effectivement.

nico :

puis supprimer la fonction de destruction de l'objet qui est vide


Là encore, rien ne t'echappe tongue, mais tu as raison , ça aussi sa fait partie de mon protocole de codage, je ne peut pas m'en empêcher (faudrait que je revois mes vieilles habitudes) OK je l'enlève.

nico :

cela dit c'est vraiment du chipotage hein


Oui, si on veut, mais toutes remarque est bonne à prendre et mérite réflexion.

nico :

j'ai bloqué sur le terme "wait", ça me parait bizarre avec l'utilisation de sleep(), qu'en pensez-vous ?


Tout a fait d'accord, j'ai chercher un terme que ça, mais mon imagination n'as pas trouvé, mais je voudrais un autre truc que Sleep(), qui des dérivé  est déjà intégrer dans bien des classe (nanoSleep, uSleep...) Si quelqu'un à une idée, je suis preneur.

Dernière modification par nabouill (31-01-2010 22:18:55)


mes sites: www.manga-vf.fr et www.series-vf.fr

Hors ligne


#6 

03-02-2010 08:01:19

nico
Webmaster
Date d'inscription: 07-08-2009
Messages: 563
Corrections: 9

salut, j'ai viré mon précédant post qui racontait n'importe quoi wink et je vous propose un nouvel essai à critiquer.

Code c++ :

#ifndef CTIMER_LOADED
#define CTIMER_LOADED

#include <ctime> // pour clock()
#include <windows.h> // pour Sleep()

#define tempsActuel  clock()
enum Temps {Ms = 1, Sc = 1000};

class  CTimer
{
    public:
        CTimer(int Interval);

        void pausePendantInterval();        //endort le programme jusqu'a ce que l'interval soit dépassé
        void pauseDurant(int Interval)const; // endort le programme pendant le temps t_intrerval
        void raz();          //remise a zero du temps passé

        bool delaiEcoule();       //renvoie "true" si l'interval temps est depassé
        int recupTempsEcoule(Temps Format=Ms)const; // renvoie les temps passé en ms depuis la derniere mise a jour
        int recupTempsRestant(Temps Format=Ms)const;  //renvoie le temps restant en seconde

        int interval;       //gestion de l'interval Temps en millisecondes

    private:
        clock_t tempsDeDepart; //enregistre le temps a l'instant T
       
};
#endif



Code c++ :

using namespace std;

CTimer::CTimer(int Interval)
{
    interval = Interval;
    tempsDeDepart = tempsActuel;
}

///***********************************************************************

int CTimer::recupTempsEcoule(Temps Format)const
{
    return (tempsActuel - tempsDeDepart)/Format ;
}

///***********************************************************************

int CTimer::recupTempsRestant(Temps Format)const
{
    return (interval - recupTempsEcoule())/Format ;
}

///***********************************************************************

bool CTimer::delaiEcoule()
{
    if(tempsActuel - tempsDeDepart > interval)
    {
        tempsDeDepart = tempsActuel;
        return true;
    }
    else return false;
}

///***********************************************************************

void CTimer::raz()
{
    tempsDeDepart = tempsActuel;
}

///***********************************************************************

void CTimer::pausePendantInterval()
{
    if(!delaiEcoule())
    {
        Sleep(interval - recupTempsEcoule());
        tempsDeDepart = tempsActuel;
    }
}

///***********************************************************************

void CTimer::pauseDurant(int Interval)const
{
    Sleep(interval);
}



Code c++ :

#include <iostream>

int main()
{
    CTimer monTimer(5000); //un interval de 5 secondes

    while(!monTimer.delaiEcoule())
        cout << "exemple chronomètre : " << monTimer.recupTempsEcoule() << endl;

    monTimer.interval=5000;

    while(!monTimer.delaiEcoule())
        cout << "exemple compte a rebours : " << monTimer.recupTempsRestant() << endl;

    return 0;
}

Hors ligne


#7 

04-02-2010 23:35:27

nabouill
Abonné
Date d'inscription: 17-09-2009
Messages: 242
Corrections: 1

nico :

j'ai viré mon précédant post qui racontait n'importe quoi


Non y avait du bon aussi, mais j'avais pas encore eu le temps de l'étudier a fond. Sinon:

1_
Dans l'ensemble, je trouve ça vraiment mieux a part un point extrêmement important :

Code c++ :


     public:
        CTimer(int Interval);
        //.......
        int interval;       //QU'EST-CE QUE TU FAIT LA TOI COCO ! TU SORT TOUT DE SUITE ET TU RETOURNE DANS private !!!!!

     private:
        clock_t tempsDeDepart;



Même si je sais que tu va me dire "oui mais ça évite de créer des ascenseurs, ce qui allège pas mal notre code" roll
C'est vrai, mais ceci est INTERDIT yikes . (j'exagère un peu hein)

2_
Sinon le

Code c++ :

#define tempsActuel  clock()

est vraiment très bon

3_
Ta traduction française passe plutôt pas mal, c'est vrai que le terme "pause" passe bien mieu que "wait"wink si tu me permet de chipoter un peut :
Je remplacerais bien "bool delaiEcoule()" par "bool delaiEstEcoule()"
et "void pausePendantInterval()" par "void pauseJusquaInterval()"
je trouve ça plus parlant.

4_
Dernier point (mais là ça viens de mes connaissance) je ne comprend pas bien comment marche:

Code c++ :

enum Temps {Ms = 1, Sc = 1000};
//.............
int recupTempsEcoule(Temps Format=Ms)const;


je ne vois pas comment on fait pour récupérer le temps en seconde ou en milliseconde (à la demande), tu aurais un exemple STP ?

En tout cas beau travail.


mes sites: www.manga-vf.fr et www.series-vf.fr

Hors ligne


#8 

05-02-2010 03:04:59

nico
Webmaster
Date d'inscription: 07-08-2009
Messages: 563
Corrections: 9

Coucou, sympa la critique, dommage qu'il n'y ai pas plus de monde sad , mais en tout cas je trouve que c'est très enrichissant de faire des codes ensemble. on devrait en faire plus souvent wink

Code c++ :


     public:
        CTimer(int Interval);
        //.......
        int interval;       //QU'EST-CE QUE TU FAIT LA TOI COCO ! TU SORT TOUT DE SUITE ET TU RETOURNE DANS private !!!!!

     private:
        clock_t tempsDeDepart;


Alors concernant la variable que j'ai mit en public, en fait je n'ai pas compris pour quelle raison il faut la privatisé, puisque il y à une fonction pour la modifier et une autre pour la lire, donc est-ce que ça ne revient pas au-même ? pourtant tu as raison que c'est une règle de base, mais j'avoue ne pas comprendre les problèmes que ça peut engendrer ?

nabouill :

Sinon le

Code c++ :


#define tempsActuel  clock()


est vraiment très bon


Oui, d'ailleur on pourrai l'utiliser pour sleep aussi, ce qui donnerai un truc du genre: #define pause(millisecondes)  sleep((millisecondes))

nabouill :

Ta traduction française passe plutôt pas mal, c'est vrai que le terme "pause" passe bien mieu que "wait" si tu me permet de chipoter un peut :
Je remplacerais bien "bool delaiEcoule()" par "bool delaiEstEcoule()"
et "void pausePendantInterval()" par "void pauseJusquaInterval()"


ouai, je me suis étonné moi même smile, la plupart du temps quand j'écris en français c'est moins compréhensible qu'en anglais sad , il faut dire que c'est pas evident avec les accents interdit et companies........
j'adère au "delaiEstEcoule", par contre je ne suis pas d'accord sur  "jusqu'a Intervalle"(je viens d'apprendre comment ça s'écrit wink ), d'àprès ce que j'ai pu comprendre, un intervalle représente une gamme àvec une valeur basse et une valeur haute, donc quand tu dis jusqu'a "intervalle" pour moi ça voudrait dire: j'usqu'a ce qu'on rentre dans l'intervalle, enfin ça dépend comment on l'interprete, je pense que tu voulais dire "jusqu'a sortie de l'intervalle" ?

nabouill :

Dernier point (mais là ça viens de mes connaissance) je ne comprend pas bien comment marche:

Code c++ :

enum Temps {Ms = 1, Sc = 1000};
//.............
int recupTempsEcoule(Temps Format=Ms)const;


alors je vais essayer de t'expliquer ce que j'ai compris, mais le problème c'est que j'ai pas tout compris lol puisque normalement l'enumeration devrait être à l'interieur de la classe, mais je n'ai pas reussi à l'utiliser de cette façon donc je l'ai déclaré avant. enfin bref....
La fonction "recupTempsEcoule(Temps Format);", prend comme parametre la variable Format.
cette variable peut prendre uniquement les valeurs "1" et "1000", puisqu'elle est du type "Temps" (*)
Ensuite dans la declaration de la fonction, tu peut voir "=Ms", ce qui signifie que la valeur par defaut égal la valeur de "Ms" soit "1"
voici comment ça s'utilise:
ex: recupTempsEcoule(Sc); l'ordi va traduire-> recupTempsEcoule(1000);
ex: recupTempsEcoule(Ms); l'ordi va traduire-> recupTempsEcoule(1);
ex: recupTempsEcoule(); l'ordi va traduire-> recupTempsEcoule(1) puisque on a declaré "Ms" comme valeur par defaut.

Dit moi si tu veut que j'explique plus en detail smile même si j'ai moi même besoins de plus d'info à ce sujet wink


(*) c'est pour ça que j'ai virer mon premier code avec les define, puisque on pouvait se retrouver avec des divisions par zero hmm , alors qu'avec les enumerations c'est ultra plus sécurisé wink

Hors ligne


#9 

13-02-2010 21:54:33

nabouill
Abonné
Date d'inscription: 17-09-2009
Messages: 242
Corrections: 1

nico :

sympa la critique, dommage qu'il n'y ai pas plus de monde  , mais en tout cas je trouve que c'est très enrichissant de faire des codes ensemble. on devrait en faire plus souvent


Tout a fait d'accord, dommage qu'il ni ais pas plus de monde. La progression s'accroit nettement plus vite a plusieurs.

nico :

Alors concernant la variable que j'ai mit en public, en fait je n'ai pas compris pour quelle raison il faut la privatisé, puisque il y à une fonction pour la modifier et une autre pour la lire, donc est-ce que ça ne revient pas au-même ? pourtant tu as raison que c'est une règle de base, mais j'avoue ne pas comprendre les problèmes que ça peut engendrer ?


Le problème que ça peut engendrer dans notre cas n'est pas bien méchant, le problème s'agrandit vite si l'on a plusieurs attribues, dont certaine qui sert a calculer certaine chose dans des méthode, des attribues que l'on utilise nul par dans notre code sauf pour faire des vérifications. Si ces attribues sont modifiable de l'extérieur, elle peuvent vite fausser toutes notre classe. Un utilisateur crée un pointeur sur cette attribue qui l'envoie a des méthodes et des méthodes d'autre classe... et tout peut vite devenir n'importe quoi. C'est pour ça qu'il faut les privatiser, c'est une SECURITE, et plutôt que dire "celle là je la privatise, pas celle là ça va être plus simple..." Il est préférable de toutes les privatisé directement car le simple ajout d'une méthode par la suite peut vite faire changer d'avis.

nico :

je pense que tu voulais dire "jusqu'à sortie de l'intervalle" ?


Non enfaite je voulais dire "jusqu'à la fin de l'interval" pour etre exact (ce qui aurait pus donné "pauseJusquaFinInteval" mais je l'avais raccourcie un peut) c'est que signification de "interval" semble bonne, du coup ton "pausePendantInterval()" est sans doute un meilleur terme même si je pense que l'on peut trouver mieu. Si quelqu'un a une idée...

nico :

alors je vais essayer de t'expliquer ce que j'ai compris


Merci, je pense avoir bien compris ce que tu m'as expliqué smile


Bon, du coup je regarde ça, et je remet tout au propredès que j'ai un peu de temps, e, attendant, si il y a d'autre idée, faite signe

Dernière modification par nabouill (13-02-2010 21:55:55)


mes sites: www.manga-vf.fr et www.series-vf.fr

Hors ligne


#10 

16-02-2010 15:06:28

nico
Webmaster
Date d'inscription: 07-08-2009
Messages: 563
Corrections: 9

merci nabouill, on m'avait toujours dit de mettre les attributs en privé ou protected, mais on m'a jamais dit les risques, là je me rend compte qu'on peut faire des allocations et tout et tout, donc c'est clair que c'est plus sécurisé avec les accesseurs, faut que je perde les réflexe du C.

Bon bein elle commence à avoir de la gueule cette classe smile y a juste l'énumération qu'il faudrait déclarer dans la classe, le problème est que quand j'apelle la fonction depuis la main, il dit que l'énumération n'est pas déclaré, j'ai essayé de me baser sur irrlicht qui met l'énumération en public mais je n'arrive à rien(d'ailleurs ça porte à confusion de voir un attribut public, mais c'est une exception wink )
En tout cas c'est un bon exercice pour les débutants en poo smile

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
881 membres
1427 sujets
11117 messages
Dernier membre inscrit: Bidule
47 invités en ligne
Aucun membre connecté
RSS Feed