void Manager::StartServer() { //if(!db.Connect(conf.GetDbFile().c_str())) // throw std::runtime_error("Database could not be opened"); #ifndef _REMOTE_MODE Music music; #else BaseMusic music; #endif music.GetList().LoadDir(conf.GetDir()); std::thread mplayer( [&music] { music.PlayList(); } ); if(conf.GetAutostart()) { music.SetStatus(Status::Playing); } CommandControler cmd(music); //FIXME: This should not detach #ifdef _NAMED_PIPE std::thread([&, this](){ while(music.GetStatus() != Status::Exit) ProcessCommand(pipe, cmd); }).detach(); #endif #ifdef _TCP_SOCKET std::thread([&, this](){ while(music.GetStatus() != Status::Exit) ProcessCommand(tcp, cmd); }).detach(); #endif mplayer.join(); }
// gère l'affichage graphique et la gestion évènementielle void RenduGraphique::boucleMaitresse() { if(affichage) std::cout << "INI: \tBoucle Maîtresse Lancée" <<std::endl<<std::endl; // intialisations int inter = 0; // variable intermédiaire entière std::string stmp(""); // variable intermédiaire de type string bool interbool = false; // variable intermédiaire de type bool bool pause = false; // vrai quand le programme est en pause bool suivreAstre = false; // vrai quand on suit l'astre sélectionné const Input& input = app->GetInput(); // contient les stattus des touches et boutons en temps réel. // variables relatives à la sourie bool sourisDroit = false, sourisGauche = false; // vrai si appuyé bool boiteInfoBougee = false; // vrai quand la BoiteInfoAstre est ferrée Vector2f posSourie(0,0); // coorodnnées de la sourie par rapport // au dernier endroit cliqué droit // Zoom double calcZoom; // utilisée pour calculer les zooms // Musique int statMsq = 1; // mit à faux si la musique n'est pas utilisable Music msq; if(NAV_ActiverMusique) { // si musique autorisée if(!msq.OpenFromFile(musique)) { FATAL_ERROR("INI: Le fichier de musique n'a pas été ouvert", false); statMsq = 0; // on ne doit pas agir sur la musique ! } else { msq.Play(); msq.SetLoop(true); // on joue la musique en boucle } } else statMsq = 0; Event event; // évènement // boucle évènementielle while(app->IsOpened()) { // si on est pas en pause, on passe au dt suivant ! directive = "SOURIS: deplacer ou selectionner, M: Arreter la musique, A: modifier astre selectionne, ESPACE: changer referentiel, ESC: quitter"; if(!pause) { U->passagedt(); // si un astre est suivis (on suit la sélection), avec sécurité if(suivreAstre && selection != NULL) { vue->Move(selection->GetVitesse().x,selection->GetVitesse().y); // si on suit un astre, on indique bien ce mode ! etat[ETAT_GENERAL] = 'R'; } else etat[ETAT_GENERAL] = 'N'; } // gestion évènementielle while(app->GetEvent(event)) { if(event.Type == Event::Closed) app->Close(); //=================== // TOUCHES DU CLAVIER else if(event.Type == Event::KeyPressed) { switch(event.Key.Code) { case Key::Escape: // fin du programme (avec confirmation) directive = "Quitter ? Oui: Escape, Non: Autre touche"; if(confirmationQuitter(suivreAstre)) app->Close(); break; case Key::Tab: // on saute le nombre indiqué par le tampon, ou la constante utilisateur NAV_PasTab inter = str2num(tampon); tampon = ""; // on vide le tampon // si rien n'est rentré if(inter == 0) inter = NAV_PasTab; for(int i = 0; i < inter; i++) U->passagedt(); if(affichage) std::cout<<inter<<" dt ont été sautés"<<std::endl; break; case Key::Return: // on reviens au zoom normal // étant donné les problèmes d'imprécision, on préfère une technique admettant une petite incertitude. while (fabs(zoomActuel - 1) > 0.09) { if(zoomActuel < 1) { zoomActuel *= NAV_CoefficientMolette; vue->Zoom(NAV_CoefficientMolette); } else if(zoomActuel > 1) { zoomActuel /= NAV_CoefficientMolette; vue->Zoom(1/NAV_CoefficientMolette); } } // de plus, on recentre la fenêtre sur l'origine vue->SetCenter(0,0); break; case Key::Space: // suivre l'astre sélectionné suivreAstre = false; // si un astre est sélectionné if(selection != NULL) suivreAstre = true; // on suit l'astre sélect. break; case Key::Back: // on retire la dernière case du tampon if(tampon.size() == 0) break; stmp = tampon; tampon = ""; for(unsigned int i = 0; i < stmp.size()-1; i++) { tampon += stmp[i]; } break; case Key::Pause: // on met en pause, ou on redémarre pause = !pause; break; // utilisation des lettres, pour différents effets case Key::M: // pour arrêter ou continuer la musique if(statMsq) { // si tout vas bien pour la musique if(msq.GetStatus() != Sound::Playing) msq.Play(); // si en pause, on démarre else // sinon on met en pause msq.Pause(); } break; case Key::A: // modifier l'astre sélectionné // si pas d'astre sélectionné, pas la peine de continuer // Si Ctrl+a : on AJOUTE aux valeurs existantes // Si a : on REMPLACE les valeurs existantes if(input.IsKeyDown(Key::LControl) || // ctrl gauche input.IsKeyDown(Key::LControl)) // ou droit interbool = true; // donc on ajoute else // sinon interbool = false; // on remplace if(selection != NULL) modificationAstre(interbool); if(affichage) std::cout<<"Astre en cours de modification..."<<std::endl; break; case Key::R: // réinitialiser l'Univers U->reinitialiserUnivers(); // on déselectionne et on se suit plus d'astre selection = NULL; suivreAstre = false; if(affichage) std::cout<<"UNIVERS REINITIALISE !"<<std::endl; break; // utilisation des flèches, pour se déplacer dans l'univers // Le nombre de pixel s'adapte au zoom case Key::Up: vue->Move(0, -NAV_PasFleche/zoomActuel); break; case Key::Right: vue->Move(NAV_PasFleche/zoomActuel, 0); break; case Key::Down: vue->Move(0, NAV_PasFleche/zoomActuel); break; case Key::Left: vue->Move(-NAV_PasFleche/zoomActuel, 0); break; // utilisation des chiffres, pour le tampon case Key::Numpad0: case Key::Num0: tampon += '0'; break; case Key::Numpad1: case Key::Num1: tampon += '1'; break; case Key::Numpad2: case Key::Num2: tampon += '2'; break; case Key::Numpad3: case Key::Num3: tampon += '3'; break; case Key::Numpad4: case Key::Num4: tampon += '4'; break; case Key::Numpad5: case Key::Num5: tampon += '5'; break; case Key::Numpad6: case Key::Num6: tampon += '6'; break; case Key::Numpad7: case Key::Num7: tampon += '7'; break; case Key::Numpad8: case Key::Num8: tampon += '8'; break; case Key::Numpad9: case Key::Num9: tampon += '9'; break; case Key::Comma: // virgule, pour les nombres flottants case Key::Period: // ou le point // La SFML ne gère pas le point du keypad tampon += '.'; break; case Key::Subtract: // utile pour faire des négatifs tampon += '-'; break; case Key::Add: // ajoute le tampon au FPS (max 1000, min 1) SFML_FPS += str2num(tampon); if(SFML_FPS > 1000) SFML_FPS = 1000; else if(SFML_FPS < 1) SFML_FPS = 1; tampon = ""; app->SetFramerateLimit(SFML_FPS); if(affichage) std::cout << "Nouvelle valeur de FPS : " << SFML_FPS << std::endl; break; // dans tous les autres cas : default: break; } } // fin gestion appuis de touche //===================== // BOUTONS DE LA SOURIE else if(event.Type == Event::MouseButtonPressed) { // on défini les coordonnées du point de clic posSourie.x = event.MouseButton.X; posSourie.y = event.MouseButton.Y; // si c'est le bouton droit if(event.MouseButton.Button == Mouse::Right) { sourisDroit = true; } // si c'est le gauche else if(event.MouseButton.Button == Mouse::Left) { sourisGauche = true; // si on n'a pas cliqué sur l'interface OBJET_INTERFACE oi = selectionInterface(event.MouseButton.X,event.MouseButton.Y); // on récupère la sortie if(oi == Dehors) { // on sélectionne un astre selectionAstre(event.MouseButton.X,event.MouseButton.Y); } else if(oi == BoiteInfo) { // on a cliqué sur la BoiteInfoAstre // on indique donc que cette boite peut-être déplacée au mouvement de sourie, jusqu'à relâchement du bouton boiteInfoBougee = true; } else if(oi == Barre) { // si clique sur la barre haute // rien à faire pour le moment } } } else if(event.Type == Event::MouseButtonReleased) { // si c'est le bouton droit if(event.MouseButton.Button == Mouse::Right) sourisDroit = false; // si c'est le gauche else if(event.MouseButton.Button == Mouse::Left) { sourisGauche = false; boiteInfoBougee = false; // la boite est déselectionnée, quoiqu'il arrive. } } // mouvement de la molette else if(event.Type == Event::MouseWheelMoved) { calcZoom = -(event.MouseWheel.Delta*NAV_CoefficientMolette); if(NAV_InverserZoom) calcZoom *= -1; // on rapelle que le zoom est une valeur positive // zoom avant si < 1 // zoom arrière si > 1 if(calcZoom > 0) calcZoom = 1/calcZoom; // calcZoom < 1 if(calcZoom < 0) calcZoom = -calcZoom; // calcZoom > 1 vue->Zoom(calcZoom); zoomActuel *= calcZoom; if(affichage) std::cout<<"ZOOM: " << zoomActuel << std::endl; } // fin gestion des boutons de la souris //======================== // MOUVEMENTS DE LA SOURIE else if(event.Type == Event::MouseMoved) { // si la souris bouge et que le bouton droit est appuyé if(sourisDroit) { // on bouge la vue d'un nombre de px égal à la différence entre la position de la sourie et la position de la sourie lorsque le clic gauche à été fait // note : on multiplie pas 1/zoom pour que ce dernier agisse sur le déplacement. Plus logique et pratique float tmpx = -(event.MouseMove.X - posSourie.x)/zoomActuel; float tmpy = -(event.MouseMove.Y - posSourie.y)/zoomActuel; if(NAV_InverserDefilement) { tmpx *= -1; tmpy *= -1; } vue->Move(tmpx, tmpy); // on modifie les coordonnées de la sourie pour éviter d'additionner nombres toujours plus grands posSourie.x = event.MouseMove.X; posSourie.y = event.MouseMove.Y; } // si la souris bouge et que le bouton gauche est appuyé else if(sourisGauche) { // si on a ferré la BoiteInfoAstre if(boiteInfoBougee) { // même technique que pour le clic droit, mais indépendant du zoom (l'interface n'est pas liée au zoom) float tmpx = (event.MouseMove.X - posSourie.x); float tmpy = (event.MouseMove.Y - posSourie.y); bia->addPosition(tmpx, tmpy); // on modifie les coordonnées de la sourie pour éviter d'additionner nombres toujours plus grands posSourie.x = event.MouseMove.X; posSourie.y = event.MouseMove.Y; } } } // fin de gestion des mouvements de la souris } // FIN GESTION EVENEMENT // on vide l'écran (couleur noire) app->Clear(); // et on affiche le shmilblick affichageSFML(); // actualisation de l'écran app->Display(); } // fin de la boucle maîtresse if(affichage) std::cout << "LAB: \tBoucle maîtresse terminée" << std::endl; }