Bonsoir,
Voici un problème que j'ai rencontré en utilisant une fonction qui appelle sf::Window::display ()
J'ai réduit le bug à un code minimaliste qui n'a d'autre but que de mettre en évidence le problème qui se produit apparemment du fait de l'interaction entre l'appel de la fonction sf::Window::display () et le clic gauche de la souris (tout ça au sein d'une boucle qui attend une condition pour rendre la main).
Le soucis c'est que si on clique avec le bouton gauche de la souris plusieurs fois en la déplaçant dans la fenêtre, le programme crashe (la rapidité d'apparition du crash peut être variable).
Le crash est par contre quasi immédiat si on tente de cliquer sur l'icône de fermeture de la fenêtre après avoir cliqué une ou deux fois au sein de la fenêtre.
Le problèmel ne se produit pas si on clique sur les autres boutons de la souris.
Peut-être que j'ai fait une grosse boulette, mais je dois dire que si c'est le cas je ne vois pas où. :-[
Donc pour produire le crash rapidement il suffit une fois l'application démarrée d'appuyer sur la barre d'espace (un texte va apparaître), puis de cliquer sur le bouton gauche de la souris une ou deux fois avec le pointeur situé dans la fenêtre puis d'aller cliquer sur l'icône de fermeture de celle-ci... plantage assuré (en tout cas chez moi).
Je tourne sous Windows XP
#include <string>
#include <SFML/Graphics.hpp>
using namespace std;
using namespace sf;
// G L O B A L S //
// Core
RenderWindow app;
// F U N C T I O N S //
void Print (string Source, float X, float Y);
int main()
{
Event event;
app.create (VideoMode(1024, 768), "Bug Lab");
// Start the game loop
while (app.isOpen())
{
while (app.pollEvent(event))
{
if (event.type == Event::Closed) app.close();
if ((event.type == Event::KeyPressed) && (event.key.code == Keyboard::Space))
{
Print ("Hi there!",10,20);
}
}
app.clear();
app.display();
}
return 0;
}
// F U N C T I O N C O D E //
void Print (string Source, float X, float Y)
{
Text text1 (Source);
text1.setColor(Color(0xCB,0x80,0xFF)); text1.setPosition(X, Y); app.draw(text1);
do
{
app.display();
}
while (!Mouse::isButtonPressed(Mouse::Right));
}
Merci pour une aide éventuelle. ;)
lol, bon je suis désolé : à vouloir écrire un code trop réduit je me rends compte que ça a conduit à ne plus devenir vraiment compréhensible. :-[
Le petit programme posté ci-dessus sert juste si on en fait un copier/coller et qu'on l'exécute à mettre en évidence le bug auquel je suis confronté dans mon programme qui gère un requester.
Je reprends mes explications en essayant d'être plus clair :
Donc à la place de la fonction Print(), mon programme appelle une fonction Requester() qui fait plein de choses dans la boucle avant de faire un app.display(), mais je me suis rendu compte que quoi qu'il y ait avant l'appel de cette fonction, la crash ne se produit (visiblement) que par rapport à l'appel de la fonction sf::Window::display () avec la conjonction du clic gauche de la souris... ce qui est plutôt embêtant justement pour une gestion de requester. :)
La fonction Requester est en cours de développement ; je te mets ci-dessous juste le code de la boucle qui se limite en fait à afficher pour l'instant le (ou les) boutton(s) du requester ainsi que le texte qui doit y être affiché... la couleur des boutons étant différente selon que le pointeur de la souris soit ou non situé au-dessus.
int Requester (string _Text$, string _Answer1$, string _Answer2$, float _X, float _Y, float _W, float _H)
{
.
.
.
do // Mouse management loop
{
MP=Mouse::getPosition(app);
GetMouseButtons(); // Set MB1 / MB2 from Mouse buttons Left / Right status (0=OFF / 1= ON)
_BFocus=0;
if (_B1.contains(MP)) {_Button1_Rect.setFillColor(Color(0xA0,0xA0,0xE0,0xFF)); _BFocus=1;}
else _Button1_Rect.setFillColor(Color(0x90,0x90,0xD0,0xFF));
// Display //
app.draw(_Req_Rect); app.draw(_Button1_Rect);
_TText.setPosition(_T1X, _Y+_H*.20); app.draw(_TText); // Requesters's message
_TAnswer1.setColor(Color(0xFF,0xFF,0xFF)); // Create text's relief effect
_TAnswer1.setPosition(_Button[1].X1+_Butt_W/2-_TAnswer1.getLocalBounds().width/2,_Button[1].Y1+_Butt_H/2-_TAnswer1.getCharacterSize()/2-1); app.draw(_TAnswer1);
_TAnswer1.setColor(Color(0x00,0x00,0x00));
_TAnswer1.setPosition(_Button[1].X1+_Butt_W/2-_TAnswer1.getLocalBounds().width/2-1,_Button[1].Y1+_Butt_H/2-_TAnswer1.getCharacterSize()/2-2); app.draw(_TAnswer1);
if (_N_Butt==2) // If the function was called to manage 2 buttons...
{
if (_B2.contains(MP)) {_Button2_Rect.setFillColor(Color(0xA0,0xA0,0xE0,0xFF)); _BFocus=2;}
else _Button2_Rect.setFillColor(Color(0x90,0x90,0xD0,0xFF));
app.draw(_Button2_Rect);
_TAnswer2.setColor(Color(0xFF,0xFF,0xFF)); // Create text's relief effect
_TAnswer2.setPosition(_Button[2].X1+_Butt_W/2-_TAnswer2.getLocalBounds().width/2,_Button[2].Y1+_Butt_H/2-_TAnswer2.getCharacterSize()/2-1); app.draw(_TAnswer2);
_TAnswer2.setColor(Color(0x00,0x00,0x00));
_TAnswer2.setPosition(_Button[2].X1+_Butt_W/2-_TAnswer2.getLocalBounds().width/2-1,_Button[2].Y1+_Butt_H/2-_TAnswer2.getCharacterSize()/2-2); app.draw(_TAnswer2);
}
if ((MB1) && (!_BFocus)) _MB_Release=1;
if ((MB1) && (!_MB_Release)) _MB_Selected=_BFocus;
if (MB2) _Quit=1;
app.display ();
} while (!_Quit);
return _Button_Selected;
}
Donc comme tu pourras facilement le voir, à part l'affichage de rectangles et de textes, il n'y a pas grand chose. La question est pourquoi le clic gauche cause un crash dans cette boucle ?
Bien évidemment à cause du problème rencontré je n'ai pas encore pu gérer les bouttons sélectionnés par un clic...
Remarque importante : le bug persiste même si on n'appelle aucune fonction de lecture de la souris (position ou état des bouttons)
Forte intuition : N'existe t'il pas un rapport avec le fait que le bouton gauche de la souris soit géré par ailleurs par le système (pour déplacer la fenêtre en cliquant sur sa barre de titre ou sur les icônes réduire, agrandir et fermer) ?
Bonne soirée,
Merci
Bonjour,
Oups, autant pour moi, je pensais à tort que lire la souris directement suffisait.
Effectivement une boucle d'évènements même vide résout le problème.
Histoire de tirer une leçon constructive de mon erreur est-ce dû à la nécessité de vider un buffer ? Ou est-ce autre chose ?
Par contre, mais là ça me semble moins anormal, l'appel à sf::Window::close() depuis cette boucle d'évènements ferme la fenêtre mais pas l'application qui reste présente dans les processus actifs... (ça c'est pas vraiment un problème, je vais le gérer autrement).
while (app.pollEvent(_event))
{
if (_event.type == Event::Closed) app.close();
}
Puis-je en déduire que la fermeture d'une fenêtre qui a été créée dans le corps principal du programme doit l'être également à ce niveau (et non pas à partir d'une fonction) ? Ou est-ce que j'ai fait une autre boulette ?
Désolé de poser un peu trop de questions, mais quitte à faire des erreurs, si je peux en comprendre les raisons ça me permettra de mieux appréhender le fonctionnement de SFML.
Merci encore.