top of page

3. La  boucle principale

 

Voici le logigramme du programme représentant la boucle principale. Quelque soit votre application, la structure du programme peut utiliser cette architecture et nous définirons un corps de programme ( le main() ) identique pour toutes les applications.

 

Vous remarquez que cette architecture générique contient deux boucles, basées sur la boucle While() :

- une boucle (principale) qui tourne tant que l’on ne veut pas quitter le programme

- une boucle interne qui tourne tant qu’il y a des évènements (du passé) à traiter

 

Voici le code correspondant :

Il est impératif de mettre SDL_PollEvent() dans un while() en ligne 79.

Vous pouvez très bien négliger de tester le retour des fonctions de chargement d'images ou même des malloc() et obtenir un programme fonctionnel ! Mais ici, si vous ne testez pas le retour de SDL_PollEvent() , vous n'obtiendrez pas une gestion correcte des évènements. L'instruction renvoie un int non nul lorsque au moins un évènement a eu lieu et est enregistré dans la pile. Le while() permet de tester le retour de la fonction.

Ce test est nécessaire, il y a deux raisons à cela :

 

1. Ne rentrer dans le switch que lorsqu'il y a un évènement à traiter

Si vous transformez la ligne 79 en une simple instruction " SDL_PollEvent(&event) ; " : il n'y a plus de test !

Alors, même si il n'y a aucun évènement à traiter, vous allez rentrer dans le switch et exécuter le traitement !!!

Et vous l'exécutez en boucle en permanence à la vitesse de votre boucle principale !!!

Vous exécutez en permanence le traitement correspondant au type du dernier évènement car event.type n'est pas modifié lorsque l'instruction renvoie 0 (aucun évènement).

Dites-vous bien que si le traitement consiste à basculer un booléen ou à incrémenter un compteur à chaque clic : sans le while() vous allez obtenir n'importe quoi. Voici un post qui donne à la fin un exemple de la bonne et de la mauvaise structure : testez par vous-même !

 

2. Traiter tous les évènements du passé rapidement, sans passer par une séquence d'affichage

La deuxième raison du while() est que sans lui vous traitez les évènements un par un à chaque tour de la boucle principale et les traitements de Actualisation() et de Affichage() peuvent être assez longs.

Avec le while() , vous traitez les évènements en boucle courte : s'il s'agit de mouvements liés au curseur de la souris par exemple : vous traitez tous les MOUSEMOTION à la suite et l'affichage n'est réalisé que pour la dernière position. Sinon vous aurez un retard et une trainée de l'affichage.

 

Voici un exemple de code sur cette architecture : l'affichage d'une image qui suit le curseur de la souris.

(NOTA : pour des raisons de lisibilité event est traité en variable globale, l'aspect pédagogique ne porte ici que sur l'architecture)

 

La fonction de traitement des évènements :

 

void switchEvent()
{
    switch (event.type)
        {
            case SDL_QUIT:
                quitter = 1;
                break;
             case SDL_MOUSEBUTTONDOWN:
                gesDown();
                break;
            case SDL_MOUSEBUTTONUP:
                gesClic();
                break;
            case SDL_MOUSEMOTION:
                gesMotion();
                break;
            case SDL_USEREVENT:
                gesUser();
                break;
            case SDL_KEYDOWN:
                gesKey();
                break;
        }
}

 

La fonction gesMotion() qui suit les mouvements de souris

 

void gesMotion()
{
    int x = event.button.x;
    int y = event.button.y;
    position.x = x; position.y = y;    
// l'image suit la souris

}

 

La fonction d'affichage :

 

void Affichage()
{
   
// clear ecran
    SDL_FillRect(ecran, 0, SDL_MapRGB(ecran->format, 0, 0, 0));

   
// draw bitmap
    SDL_BlitSurface(bmp, 0, ecran, &position);
    SDL_Flip(ecran);
}

 

 

Vous remarquez que l’image suit tous les mouvements de la souris même si vous déplacez celle-ci rapidement.

 

Le programme ainsi construit avec une boucle principale sur cette architecture a cependant un gros inconvénient : la consommation CPU. Il n’y a aucune pause (mise en veille du programme) dans l’enchaînement des instructions.

 

Le « compte-tour » de la consommation CPU s’envole et votre ordinateur chauffe !

 

Et toute cette énergie est gaspillée pour rien, pour afficher 1000 fois par seconde quasiment la même image. Une telle fréquence de répétition de l’affichage est tout simplement inutile, une fréquence de l’ordre de 25 à 50 images par seconde est largement suffisante pour obtenir un affichage très fluide.

 

Vers la solution :

    < Page précédente                                                                                                    Sommaire                                                             > Page suivante

bottom of page