Salutations !!
Je suis en train d'essayer, avec mes élèves, d'écrire une application en mode graphique en ANSI C avec SDL2.
Nous sommes tous contents nous avons une jolie interface graphique... cependant, rien que le fait de l'afficher avec juste quelques processes "traitements" dans la boucle principale, qui peuvent être désactivés facilement, nous avons remarqué:
+ la taille de la mémoire occupée par l'application augmente de 4.0k toutes les cinq secondes, on ne sait pas pourquoi... et nous imaginons qu'à un moment le système va finir par "trasher"... (swapper à n'en plus finir)
+ sur les systèmes multi-coeur que ce soit amd ou intel, il y a un ou deux coeurs qui "montent" à 70% voire 90%, alors qu'il y a une temporisation dans la boucle principale qui boucle jusqu'à ce qu'on ferme la fenêtre, la while(bRunning) que tout le monde connaît.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 ... DisplayUI(); SDL_RenderPresent(r_Dessinateur); Log(logFile,"[START] Graphics --> OK"); Log(logFile,"[MAIN LOOP]"); int rotation=10; while(bRunning) { SDL_Delay(100); // pour éviter que le processeur monte à 100% :{ // (boucle infinie --> obligation de taper une tempo sinon le processus va s'accaparer tout le "temps" processeur) while (SDL_PollEvent(&UnEvenement)) { switch(UnEvenement.type) { case SDL_QUIT: SDL_Delay(500); bRunning=false; break; case SDL_KEYDOWN: // fprintf(stderr,"[DEBUG] Touche appuyée %d\n",UnEvenement.key.keysym.scancode); scancode=UnEvenement.key.keysym.scancode; if(bReleased) { switch(scancode) { case SDL_SCANCODE_LEFT: break; case SDL_SCANCODE_RIGHT: break; case SDL_SCANCODE_UP: break; case SDL_SCANCODE_DOWN: break; case SDL_SCANCODE_SPACE: case SDL_SCANCODE_F1: SDL_Delay(500); bRunning=false; } } bReleased=false; break; case SDL_KEYUP: bReleased=true; //AfficherInterface(r_Dessinateur); break; case SDL_MOUSEMOTION: positionSouris.x=UnEvenement.motion.x; positionSouris.y=UnEvenement.motion.y; break; case SDL_MOUSEBUTTONDOWN: whichbutton=UnEvenement.button.button; switch(whichbutton) { case 3: fprintf(stdout,"Clic bouton droit\n"); break; case 1: fprintf(stdout,"Clic bouton gauche\n"); //toggleArduinoOnline(7); targetArduino=GetObject(positionSouris); toggleArduinoOnline(targetArduino); //UpdateUI(); break; case 2: fprintf(stdout,"Clic bouton milieu\n"); } break; } fflush(stdout); fflush(stderr); } #ifdef PERFS_KO lc_Datas *tmpDatas=lc_search(pile_graphics,idBoutonPlay); // fonction "interne" qui retrouve un objet (par rapport à son identifiant) dans une liste chaînée t_Objet *tmpObject=(t_Objet*)tmpDatas->value; // l'élément de la liste est "transformé" en "objet" SDL_SetRenderDrawColor(r_Dessinateur, 0, 0, 0, 255); // couleur de fond noire SDL_RenderClear(r_Dessinateur); // on efface l'ardoise tmpObject->bDisabled=true; // l'objet en question ne doit pas être dessiné #endif UpdateUI(); #ifdef PERS_KO // on dispose tous les objets à mettre à jour sauf celui-ci SDL_RenderCopyEx(r_Dessinateur,tmpObject->pTexture,NULL,&tmpObject->position,rotation,NULL,SDL_FLIP_HORIZONTAL); rotation+=10; // changement de l'angle de rotation (sens des aiguilles d'une montre) #endif SDL_RenderPresent(r_Dessinateur); // nous avons fini de dessiner } Log(logFile,"[QUIT] Libération des ressources..."); lc_empty(pile_texts); lc_empty(pile_shadows); lc_empty(pile_graphics); lc_empty(pile_background); SDL_DestroyWindow(FenetrePrincipale); TTF_Quit(); SDL_Quit(); Log(logFile,"Fin du programme... retour au shell !!"); fclose(logFile); return (EXIT_SUCCESS); } // Faire mieux que retracer tout l'écran void UpdateUI(void) { SDL_SetRenderDrawColor(r_Dessinateur, 0, 0, 0, 255); // couleur de fond noire SDL_RenderClear(r_Dessinateur); // effacer "la toile" DisplayUI(); // dessiner la "toile" SDL_RenderPresent(r_Dessinateur); // exposer la "toile" } int GetObject(Coordonnee coord) { lc_Datas *tmpDatas; t_Objet *tmpObject; int currentTarget; for(currentTarget=0;currentTarget<pile_graphics->NbElem;currentTarget++) { tmpDatas=lc_get(pile_graphics,currentTarget); tmpObject=(t_Objet*)tmpDatas->value; // Vérifier si le clic a eu lieu sur un objet... if(coord.x>=tmpObject->position.x && coord.y>=tmpObject->position.y && coord.x<=tmpObject->position.x+tmpObject->position.w && coord.y<=tmpObject->position.y+tmpObject->position.h) { if(currentTarget<MAXARDUINO) return 7-currentTarget; // vu que les textures sont empilées (LIFO) le premier élément à enlever de la pile est toujours le dernier entré... } } ... }
Partager