Bon finalement, j'ai pu bossé sur l'idée et je suis arrivé à quelque chose.
Je vais donc proposer un début de solution ici concernant l'ouverture dynamique simple de plusieurs fenêtre SFML.
Une class qui gère le fenêtrage, tout d'abord son prototype pas grand chose à dire :
Attributs :
- Un conteneur vector
Methodes :
- un constructeur par défaut
- la méthode
addFrame qui permet d'ajouter dans le conteneur dynamiquement autant de fenêtre que vous le souhaitez une fois la class instanciée.
- la méthode
getWindowListSize qui retourne à la boucle principale le nombre de case restant dans le conteneur. ( et donc le nombre de fenêtre encore ouverte ).
- la méthode
poolEvent qui s'occupe d'écouter les événements dans chaque fenêtre ouverte en utilisant bien sur les fonctions et méthodes de la SFML pour les gérer. Cette méthode se charge également de supprimer du conteneur la fenêtre dont l'event de fermeture a été appelé en utilisant un itérateur ( principe de l'idiom erase-remove pour gérer correctement l'itérateur ).
#include <string>
#include <vector>
#include <algorithm>
#include "make_unique_ptr_temp.h"
#include <SFML/Graphics.hpp>
class graphic_engine
{
public:
graphic_engine();
void addFrame(unsigned int width, unsigned int height, std::string title);
int getWindowListSize();
void poolEvent(const int val, sf::Event& e);
virtual ~graphic_engine();
protected:
private:
std::vector<std::unique_ptr<sf::RenderWindow>> windowList;
};
et la définition ( je pense que le code parle de lui même mais ne pas hésiter à me demander si besoin de détail ) :
graphic_engine::graphic_engine()
{
}
void graphic_engine::addFrame(unsigned int width, unsigned int height, std::string title)
{
windowList.push_back(make_unique<sf::RenderWindow>(sf::VideoMode(width, height), title));
}
int graphic_engine::getWindowListSize()
{
return windowList.size();
}
void graphic_engine::poolEvent(const int val, sf::Event& e)
{
if(windowList[val]->pollEvent(e))
{
if (e.type == sf::Event::Closed)
{
windowList[val]->close();
windowList.erase(std::remove(windowList.begin(), windowList.end(), windowList[val]), windowList.end());
}
}
}
graphic_engine::~graphic_engine()
{
//dtor
}
Et enfin dans le main :
int main()
{
graphic_engine* gs = new graphic_engine();
gs->addFrame(300,200,"fen1");
gs->addFrame(300,200,"fen2");
gs->addFrame(300,200,"fen3");
while (gs->getWindowListSize() != 0)
{
for(int i = 0; gs->getWindowListSize() > i; i++)
{
sf::Event event;
gs->poolEvent(i, event);
}
}
return 0;
}
Une fois les fenêtres créées, on démarre la boucle principale qui ne s’arrêtera pas tant qu'il restera des fenêtres dans le conteneur. On ajoute une autre boucle qui aura pour fonction de parcourir toutes les cases du conteneur et d'écouter les events sur chaque fenêtre.
Vous noterez également que les smart pointer ont été sélectionnés, je trouvais très pratique de ne pas avoir à gérer le deleting dans le conteneur avant de supprimer une case. Cependant comme la fonction std::make_unique n'existe pas dans la librairie standard et que je n'utilise pas boost, j'ai récupéré un template proposant l'implémentation de la fonction en attendant la norme c++14 :
http://www.jsfauteux.com/blog/post/2/std::make_unique-dans-le-C++14 basé sur ce rapport :
http://herbsutter.com/gotw/_102/Je me doute bien qu'on doit pouvoir faire mieux et que pour les pratiquants chevronnés du c++, ce n'était absolument pas difficile à réaliser. Je suis en tout cas ouvert à toute critique constructive pour améliorer le code.
En espérant que sa pourra servir à quelqu'un.
Bonne soirée.