Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Amélioration des paquets  (Lu 3887 fois)

0 Membres et 1 Invité sur ce sujet

Sapin

  • Newbie
  • *
  • Messages: 10
    • Voir le profil
Amélioration des paquets
« le: Décembre 02, 2012, 11:07:51 am »
Bonjour,

Je me suis rendu compte que le potentiel de la classe sf::Packet est beaucoup plus important que ceux qu'on en fait, et pour cause, on pourrait l'utiliser pour envoyer/recevoir des données binaires sérialisées, ce que boost par exemple ne gère pas (rien que çà !), à travers les flux de la STL. Ça permettrait de stocké des données sérialisées dans le DD par exemple. De plus, il suffirait de rendre compatible sa classe avec sf::Packet pour la rendre compatible avec toutes les STL : gain de temps et de simplicité.

J'ai une proposition d'implémentation ( toute simple et surtout optimisable ) :

std::istream& operator >> (std::istream& stream, sf::Packet& packet)
{
    sf::Uint32 start = stream.tellg ();
    stream.seekg (0, std::ios::end);
    sf::Uint32 lenght = stream.tellg ();
    lenght -= start;
    stream.seekg (start, std::ios::beg);

    char** buffer = new char* [lenght];

    stream.read (*buffer,lenght);
    packet.Append (*buffer,lenght);

    return stream;
}

std::ostream& operator << (std::ostream& stream, sf::Packet& packet)
{
    stream.write (packet.GetData (), packet.GetDataSize ());

    return stream;
}

Remarqué la belle double réécriture de tampon ...
Sinon pour l'utiliser :

file << packet; // écriture
file >> packet; // lecture

Aussi je propose une autre amélioration des paquets, il serait bien de pouvoir utiliser l'opérateur & pour écrire ou lire dans les paquets. Le problème est que le compilateur ne sait pas dans quelle sens faire l'opération, c'est pour çà que je propose 2 classes qui ont comme seul caractéristique d’exister :

namespace sf
{

class InPacket : public Packet
{
public:
    InPacket () : Packet () {}
};

class OutPacket : public Packet
{
public:
    OutPacket () : Packet () {}
};

}

Il faut aussi gérer les données de base : (désolé pour le long fichier, je ne trouve de balise spoil/secret )

// *** *** *** IN *** *** ***

inline InPacket& operator& (InPacket& packet, bool e){
    packet >> e;
    return packet;
}

inline InPacket& operator& (InPacket& packet, Int8 e){
    packet >> e;
    return packet;
}

inline InPacket& operator& (InPacket& packet, Uint8 e){
    packet >> e;
    return packet;
}

inline InPacket& operator& (InPacket& packet, Int16 e){
    packet >> e;
    return packet;
}

inline InPacket& operator& (InPacket& packet, Uint16 e){
    packet >> e;
    return packet;
}

inline InPacket& operator& (InPacket& packet, Int32 e){
    packet >> e;
    return packet;
}

inline InPacket& operator& (InPacket& packet, Uint32 e){
    packet >> e;
    return packet;
}

inline InPacket& operator& (InPacket& packet, float e){
    packet >> e;
    return packet;
}

inline InPacket& operator& (InPacket& packet, double e){
    packet >> e;
    return packet;
}

inline InPacket& operator& (InPacket& packet, char* e){
    packet >> e;
    return packet;
}

inline InPacket& operator& (InPacket& packet, std::string& e){
    packet >> e;
    return packet;
}

inline InPacket& operator& (InPacket& packet, wchar_t* e){
    packet >> e;
    return packet;
}

inline InPacket& operator& (InPacket& packet, std::wstring& e){
    packet >> e;
    return packet;
}

// *** *** *** OUT *** *** ***

inline OutPacket& operator& (OutPacket& packet, bool e){
    packet << e;
    return packet;
}

inline OutPacket& operator& (OutPacket& packet, Int8 e){
    packet << e;
    return packet;
}

inline OutPacket& operator& (OutPacket& packet, Uint8 e){
    packet << e;
    return packet;
}

inline OutPacket& operator& (OutPacket& packet, Int16 e){
    packet << e;
    return packet;
}

inline OutPacket& operator& (OutPacket& packet, Uint16 e){
    packet << e;
    return packet;
}



inline OutPacket& operator& (OutPacket& packet, Int32 e){
    packet << e;
    return packet;
}

inline OutPacket& operator& (OutPacket& packet, Uint32 e){
    packet << e;
    return packet;
}

inline OutPacket& operator& (OutPacket& packet, float e){
    packet << e;
    return packet;
}

inline OutPacket& operator& (OutPacket& packet, double e){
    packet << e;
    return packet;
}

inline OutPacket& operator& (OutPacket& packet, char* e){
    packet << e;
    return packet;
}

inline OutPacket& operator& (OutPacket& packet, std::string& e){
    packet << e;
    return packet;
}

inline OutPacket& operator& (OutPacket& packet, wchar_t* e){
    packet << e;
    return packet;
}

inline OutPacket& operator& (OutPacket& packet, std::wstring& e){
    packet << e;
    return packet;
}


Pour l'utiliser :


struct Data
{
    sf::Uint32 number;
    sf::Uint32 anOtherNumber;
    sf::Uint32 anImportantOne;
}



template <class Packet>
Packet& operator& (Packet& packet, Data& data)
{
    sf::Uint32 version = 2;


    packet & version;


    switch (version)
    {
    case 2:
        packet & anImportantOne;
    case 1:
        packet & data.anOtherNumber
    case 0:
        packet & data.number;
        break;
    default:
        break;
    }


    return packet;
}


 


Voilà tout  :D  !

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Amélioration des paquets
« Réponse #1 le: Décembre 02, 2012, 11:22:35 am »
Merci de chercher un peu avant de poster :P

https://github.com/SFML/SFML/issues/112
Laurent Gomila - SFML developer

danman

  • Hero Member
  • *****
  • Messages: 1121
    • Voir le profil
    • E-mail
Re : Amélioration des paquets
« Réponse #2 le: Décembre 02, 2012, 03:37:42 pm »
packet & data pour stocker/lire dans un packet fait vraiment pas C++ mais bien plus VB6 pour ma part, on a les opérateurs de flux c'est bien plus lisible.
Pointilleur professionnel

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Amélioration des paquets
« Réponse #3 le: Décembre 02, 2012, 04:43:02 pm »
L'opérateur & est souvent utilisé lorsqu'on veut coder les deux sens (lecture et écriture) dans une même fonction, comme ce que fait boost.serialization.
Laurent Gomila - SFML developer

Lynix

  • Sr. Member
  • ****
  • Messages: 403
    • Voir le profil
Re : Amélioration des paquets
« Réponse #4 le: Décembre 04, 2012, 09:00:33 am »
Moi je trouverais ça bien plus naturel de surcharger l'opérateur &= pour l'écriture et & pour la lecture.

Sapin

  • Newbie
  • *
  • Messages: 10
    • Voir le profil
Re : Amélioration des paquets
« Réponse #5 le: Décembre 04, 2012, 05:36:14 pm »
L'avantage que j'y trouve est que ça permet d'avoir un code pour la lecture et l'écriture donc gain de temps et minimisation des erreurs. Aussi, le rendre compatible avec les flux pour choisir le sens est très aisé.