Bienvenue, Invité. Merci de vous connecter ou de vous inscrire. Avez-vous oublié d'activer ?

Voir les contributions

Cette section vous permet de consulter les contributions (messages, sujets et fichiers joints) d'un utilisateur. Vous ne pourrez voir que les contributions des zones auxquelles vous avez accès.


Messages - Rick_Cplusplus

16
Fenêtrage / Imbriquer des events, possible ou pas ?
« le: Juillet 12, 2019, 10:13:13 am »
Bonjour la communauté,

Je voudrais créer un déplacement de vue dans une fenêtre qui ressemble à du "drag and drop".
Le comportement attendu c'est :
sur un bouton (left) souris maintenu enfoncé, suivi d'un mouvement souris, récupérer le vecteur du déplacement souris, et déplacer la vue courante de ce vecteur tant que le bouton n'est pas relâché.

Or le tuto précise bien que event est une union ce que je traduis (peut être à tort) par : une instance de event ne peut traiter qu'un evenement à la fois.

Mais peut-on instancier 2 event (event1 et event2) et les imbriquer dans la même fenêtre via 2 pollEvent ?
Quelque chose comme ça :
sf::event event1;
sf::event event2;
while (fenetre.pollEvent(event1))
        {
        ...
        if (event1.type == sf::Event::MouseButtonPressed
        {
                while (fenetre.pollEvent(event2))
                        {
                                 ...
                        }
        }
        ...
 

Si oui, je tente l'implémentation (mais il y a peut être "plus simple" pour faire ça) :)
Si non, avez-vous une piste pour implémenter "autrement"' ? ::)
Salutations,

Rick.

17
Réseau / Re: Taille maximum d'un packet
« le: Octobre 04, 2018, 09:30:14 pm »
Bonjour Laurent,

En fait je voudrais envoyer (en TCP) les données d'une carte (type wargame) ?  chaque client pour qu'il puissent l'afficher et programmer les déplacements de leurs unités.
Basiquement il pourrait y avoir jusqu'?  10000 hexagones avec pour chacun un type de terrain, les routes, les rivières, les constructions (villes ou fortifications), etc...

De ce que je comprends de ta réponse, il vaut mieux faire un paquet pour chaque hex qu'un gros paquet de 10000 hex ! ^^

Je vais donc coder en ce sens. :)
Rick.

18
Réseau / Taille maximum d'un packet
« le: Octobre 04, 2018, 08:06:41 pm »
Bonjour La communauté,

Il y a t-il une taille maximum (en octet) pour "remplir" un packet ?
si je fais :
sf::packet paquet;
int max;
for(int i(0); i<max; i++)
{
     paquet << "00000 00 000 00";
}
 
quel est la valeur de maxi de max ?

Merci de m'avoir lu,
Rick.

19
Discussions générales / Re: SFML et SFGUI
« le: Septembre 09, 2018, 08:32:04 pm »
Bonjour Laurent,

Merci pour cette explication, je vais aller étudier ça ! :)
Rick.

20
Merci Laurent,

Bon, c'est parti pour une refonte totale !  ;D
Je reviendrai proposer mon résultat.
*senvabosserletruc

Rick.

21
Discussions générales / SFML et SFGUI
« le: Septembre 07, 2018, 09:12:09 am »
Bonjour la communauté,

J'ai entendu parler de SFGUI et ja me pose la question de s compatibilité avec SFML, et d'une façon plus générale des liens entre les 2 (les 2 commencent par SF)...
Il semble que SFGUI soit moins "abouti" que SFML (je ne l'ai vu que sur GitHub et dans la langue du barde immortel), existe-t-il un forum dédié du type de celui là ?
any clue? ::)

Rick.

22
Bonjour la communauté,

Citer
Quel problème avais-tu avec cette solution ?

J'ai sans doute mal codé (niveau faux débutant) mais même avec les isBlocking(false) sur la socket client ET listener, cela ne fonctionne pas.

serveur.cpp
#include "../Header_perso/Serveur.h"

//constructeur
Serveur::Serveur(unsigned int Joueurs, unsigned short int Port, bool bloquer)
{
    nbJoueurs=Joueurs;
    port=Port;
    allo.setBlocking(bloquer);
}

// methodes

//Lancement serveur et chargement vector socket de joueurs
bool Serveur::lancement()
{
    if (allo.listen(port) != sf::Socket::Done)
    {
        // erreur...
        std::cout << "port inécoutable" << std::endl;
        return false;
    }
    else // serveur lancé
    {
        selecteur.add(allo);
        std::cout << "Allo ? J'ecoute le port : " << port << std::endl;
        std::cout << "J'attends " << nbJoueurs << " joueur(s)." << std::endl;
    }

    bool tousPresents(false); // passe à true si tous les joueurs ont un socket attitré

    // boucle de surveillance et connexion des joueurs attendus
    while(!tousPresents)
        {
            // déclaration d'un std::unique_ptr (accessible depuis C++14)
            auto joueur = std::make_unique<sf::TcpSocket>();

            //  obtention du "pointeur sous-jacent" (le sf::TcpSocket * )
            if (allo.accept(*(joueur.get()) ) == sf::Socket::Done)
            {
                //déréférencement du pointeur renvoyé par la fonction get par *(.get())
                selecteur.add(*(joueur.get()));
                // utilisation de la version de push_back avec std::move
                V_joueur.push_back(std::move(joueur));
            }
            if (V_joueur.size() == nbJoueurs) tousPresents=true;
        }
    std::cout << "nos " << nbJoueurs << " joueur(s) est(sont) connecté(s) sur le serveur." << std::endl;
    std::cout << "V_Joueur size = " << V_joueur.size() << std::endl;
    return true;
}
 

Client.cpp
#include "../Header_perso/Client.h"

//constructeur
Client::Client(std::string adresse, unsigned short int Port, bool bloquer)
{
    adrIp=adresse;
    port=Port;
    socket.setBlocking(bloquer);
}

//méthodes

//  Demande connexion serveur
bool Client::rejoindre()
{
    std::cout << "Demande la connexion au serveur" << std::endl;
    sf::Socket::Status statut = socket.connect(adrIp, port);
    if (statut != sf::Socket::Done) return false;
    std::cout << "connexion établie avec serveur sur port : " << port << " adresse Ip locale : " << adrIp << std::endl;
    return true;
}
 

main.cpp
#include "../../Header_perso/Serveur.h"
#include "../../Header_perso/Client.h"

int main()
{
    bool connecte(false);
    bool serveurLance(false);
    unsigned int nbJoueurs(1);
    unsigned short int port(56000);
    std::string adrIp="192.168.1.14";

    Serveur serveur(nbJoueurs, port, false);
    Client joueur(adrIp, port, false);

    while(!connecte)
    {
        if(!joueur.rejoindre())
        {
            system("cls");
            std::cout << "pas connecte au serveur" << std::endl;
        }
        else
        {
            system("cls");
            std::cout << "connecte au serveur" << std::endl;
        }
        if (!serveurLance)
        {
            if(!serveur.lancement())
            {
                std::cout << "serveur planté" << std::endl;
                return -1;
            }
        serveurLance=true;
        std::cout << "serveur opérationnel" << std::endl;
        }
    }
return 0;
}
 

C'est agaçant parce que j'ai l'intuition que c'est un cas hyper courant mais je ne trouve pas comment faire... Bousk sur développer.com suggère de déclarer la socket locale dans la classe serveur et de la "passer" ensuite dans la classe client (l'inverse de ce que je pensais faire en fait) mais je ne vois pas ce que "passer" veut dire en l’occurrence ni quelle syntaxe utiliser...  :-\

Une suggestion ?
Rick.

23
Bonjour la communauté,

Dans ma classe Serveur, j'ai une fonction qui lance le listener,
Dans ma classe Client, j'ai une fonction qui demande une connexion au serveur.

Le pb, (sans doute "classique") c'est que si dans le même programme je lance l'une de ces fonctions, elle garde la main en attendant  l'autre qui du coup n'arrive jamais puisque le pgm est en attente... J'ai essayé de passer les sockets en mode "non blocking" mais cela ne semble pas remédier à la situation.  (si ce n'est pas clair, je peux présenter les codes. ;) )

Je voudrais éviter le multi-threading juste pour ça (le pgm n'en a pas besoin par ailleurs).
Existe-il une idée rusée pour que la socket "locale" puisse appeler le serveur lorsque celui-ci attend en mode listener ?

Sinon, je pense modifier la fonction d'appel de connexion pour le cas particulier de la socket "locale" et l'ajouter au selecteur et son pointeur au vector listant les pointeurs sur les socket en passant son adresse ainsi :

dans Server.cpp
code supprimé pke toufo ^^
 

dans Client.cpp (avec include de serveur.h dans client.h et &serveur passé argument de la fonction)
code supprimé pke toufo ^^
 

Un tel code visant donc :
- à connecter la socket locale au serveur,
- à ajouter la socket locale au selecteur du serveur et
- à ajouter son pointeur au vector listant les pointeurs sur les socket connectées
fonctionnerait-il? ::)

Merci de m'avoir lu,
Rick.

24
Réseau / Re: le selector ne lit pas une socket qui envoie un packet
« le: Septembre 04, 2018, 01:54:40 pm »
Ok je regarde ça. Merci pour ta réactivité.
Sujet clos... pour le moment. :)

Rick.

25
Réseau / Re: le selector ne lit pas une socket qui envoie un packet
« le: Septembre 04, 2018, 10:42:18 am »
Encore merci pour ton aide et tes indices.  :)
Alors, est-ce que si je fais un code comme suit,

sf::TcpListener allo;

... // code pour que allo écoute le port 56000

std::vector <sf::TcpSocket*> V_client;
bool tousPresents(false);

while(!tousPresents)
    {
        // déclaration d'un socket à affecter au prochain client qui le demande
        sf::TcpSocket *joueur = new sf::TcpSocket();
        if (allo.accept(joueur) == sf::Socket::Done)
        {
            selecteur.add(*joueur);
            V_client.push_back(joueur);
        }
        if (V_client.size() == nbJoueurs) tousPresents=true;
    }
 

on peut dire que j'ai fait une allocation dynamique et que conséquemment, la variable sf::TcpSocket joueur va perdurer au delà de la boucle while donnant du sens à V_client pour la boucle selecteur wait ?

Il faudra aussi surement placer un delete[] à un moment si je veux éviter la fuite de mémoire (sauf si vector gère ça tout seul ?)
Ça vire au cours sur les pointeurs mais comme les socket ne sont pas copyable, il faut bien en passer par eux non ? :'(

Rick.

26
Réseau / Re: le selector ne lit pas une socket qui envoie un packet
« le: Septembre 03, 2018, 09:38:34 pm »
Merci Laurent pour ce retour rapide.

De ta réponse je déduis que le client n'est pas en cause.  ;)

Côté serveur donc, comme hélas les pointeurs et moi sommes fâchés, j'ignorais que les adresses de socket avaient une porté limitée à la boucle ou elle sont déclarées...

Existe-t-il un moyen sioux d'étendre la porté de ces adresses ou suis-je condamné à ne JAMAIS sortir de la boucle while si je veux faire fonctionner les échanges clients / serveur ?

Et dans le second cas, cela veut sans doute dire que TOUT le reste de mon programme devra AUSSI s’insérer dans la boucle while via (j'espère) des appels de fonctions, isn't it ?

Si oui, GROS boulot ahead apparemment... :P

Rick.

27
Réseau / [Résolu] le selector ne lit pas une socket qui envoie un packet
« le: Septembre 03, 2018, 07:20:22 pm »
Bonjour la communauté,

Avant de vous fournir mon code, je met le contexte :

Le serveur doit attendre la connexion d'un nombre précis de clients (2 à 7).
 => pour se faire j'utilise un "listener", chaque nouvelle socket est indexée dans un vector, et ajoutée à un selector.
Note je n'ajoute pas le listener au selector puisque le nombre de client atteint, aucune autre connexion ne doit s'ajouter.

Lorsque le nombre est atteint, les échanges serveurs / client peuvent commencer.
=> sur le serveur, utilisation de selector "wait" et boucle "for" sur le vector pour déterminer la socket concernée, puis réception du packet
=> sur le client, socket send packet dès que la connexion est établie.

je lance le serveur en débug et le client en release. impossible de voir le selector quitter le "wait" et lancer la lecture du vector (comme si le packet n'était pas envoyé par le client...) Je sèche  ???

ci dessous le code serveur minimal (pour le test je n'attend qu'un seul client):
#include <iostream>
#include <vector>
#include <SFML/Network.hpp>

using namespace std;

int main()
{
    unsigned int nbJoueurs(1); // un seul client pour le test

    // vector pour stocker les socckets des joueurs
    std::vector <sf::TcpSocket*> V_client;

    // declaration du socket (allo) de l'écouteur
    sf::TcpListener allo;

    //Declaration d'un selecteur de socket
    sf::SocketSelector selecteur;

    // affectation au port (breton 56 ^^) à écouter
    unsigned short int port=56000;
    if (allo.listen(port) != sf::Socket::Done)
    {
         // erreur...
        std::cout << "port inécoutable" << std::endl;
        return -1;
    }
    else std::cout << "Allo ? J'ecoute le port 56000" << std::endl; // serveur lancé

    bool tousPresents(false); // passe à true si tous les joueurs ont un socket attitré

    // boucle de surveillance et connexion des joueurs attendus
    while(!tousPresents)
    {
        // déclaration d'un socket à affecter au prochain client qui le demande
        sf::TcpSocket joueur;
        if (allo.accept(joueur) == sf::Socket::Done)
        {
            V_client.push_back(&joueur);
            selecteur.add(joueur);
        }
        if (V_client.size() == nbJoueurs) tousPresents=true;
    }
    std::cout << "nos " << nbJoueurs << " joueurs sont connectés sur le serveur." << std::endl;
    std::cout << "V_client size = " << V_client.size() << std::endl;

    //boucle d'échange de données
    sf::Packet paquet;
    sf::Int32 x(0);
    bool flag(false);
    while(!flag)
    {
        //boucle d'attente de message
        if (selecteur.wait()) // <= c'est là que ça semble foirer...
        {
            for(unsigned int i(0); i<V_client.size(); i++)
            {
                if (selecteur.isReady(*V_client[i]))
                {
                    V_client[i]->receive(paquet);
                    paquet >> x;
                    std::cout << "paquet reçu ; x vaut : " << x << endl;
                    if (x==-1) flag=true;
                    x=-10;
                    paquet << x;
                    system("pause");
                    V_client[i]->send(paquet);
                }
            }
        }
    }
    return 0;
}
 

et le code client :
#include <iostream>
#include <SFML/Network.hpp>

using namespace std; // DSL...

int main()
{
    sf::Int32 x = 10;
    unsigned short int port(56000);
    bool flag(false);
    sf::TcpSocket socket;
    sf::Socket::Status statut = socket.connect("192.168.1.14", port); // Ipv4 locale du serveur
    if (statut != sf::Socket::Done)
    {
        return -1;
    }
    else
    {
        std::cout << "connexion établie sur port " << port << std::endl;
        sf::Packet paquet;
        paquet << x;
        if (socket.send(paquet)!= sf::Socket::Done)
        {
            std::cout << "erreur d'envoi de paquet" << std::endl;
            system("pause");
        }
        while (!flag)
        {
         // pour patienter
        }
        return 0;
}

 

Je devrais recevoir le packet et en extraire x qui vaudrait 10, mais non...  :-\
Une piste ?

Rick.

28
Fenêtrage / Re: Pourquoi sf::Event event dans le while de frame ?
« le: Août 23, 2018, 10:47:22 am »
Merci Laurent,

Je ne jurerai pas avoir tout compris de la réponse (les POD notamment) ; mais je comprends que c'est aussi "économique" d'instancier un POD au moment du besoin (et même dans une boucle) qu'en amont de la ladite boucle parce qu'instancier un POD c'est juste réserver de la place sur la pile.

Et faire ainsi assure la lisibilité du code. :)

Rick.

29
Bonsoir la communauté,

Je me pose une question en étudiant les tutoriels quand je lis le code qui suit :
 while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
 

Pourquoi instancier un sf::Event à chaque frame (dans la boucle while) et non une seule fois (i.e. avant le while) ?
Ça m'intrigue...

Rick.


30
 ;D énorme !

Bon bin sujet clos, merci Laurent du support rapide et pédagogique.

Rick

anything