2017-06-10 4 views
1

J'essaye d'envoyer des données cartographiques à un client, qui prend la forme de plusieurs vecteurs contenant les coordonnées des tuiles de la carte. La structure de carte entière peut être réduite à quelque chose comme ça (le code non réel, mais je reproduit le problème en utilisant aussi):Réseau SFML | Envoyer des objets contenant d'autres objets sur sf :: Les paquets provoquent des données nulles

struct Tile { 
    sf::Vector3<int> coords; 
}; 

struct Map { 
    Tile tiles[4]; 
}; 

Ensuite, j'utiliser ces opérateurs d'ajouter ce type d'objets à un sf::Packet:

sf::Packet& operator<<(sf::Packet& packet, sf::Vector3<int> vec) { 
    return packet << vec.x << vec.y << vec.z; 
} 

sf::Packet& operator>>(sf::Packet& packet, sf::Vector3<int> vec) { 
    return packet >> vec.x >> vec.y >> vec.z; 
} 

sf::Packet& operator<<(sf::Packet& packet, Tile test) { 
    return packet << test.coords; 
} 

sf::Packet& operator>>(sf::Packet& packet, Tile test) { 
    return packet >> test.coords; 
} 

sf::Packet& operator<<(sf::Packet& packet, Map test) { 
    for(int i = 0; i < 4; i++) { 
     packet << test.tiles[i]; 
    } 
    return packet; 
} 

sf::Packet& operator>>(sf::Packet& packet, Map test) { 
    for(int i = 0; i < 4; i++) { 
     packet >> test.tiles[i]; 
    } 
    return packet; 
} 

Jusqu'à ici, il ne devrait pas y avoir de problème: la carte doit être désérialisée 4 tuiles qui doivent être désérialisé à un sf::Vector3<int> lui-même.

Puis vient l'envoi:

Tile test; 
test.coords.x = 42; 
test.coords.y = 34; 
test.coords.z = 43; 

Map test3; 
test3.tiles[0] = test; 

sf::Packet packet; 
packet << test3; 

sock.send(packet); 

Ce code fonctionne très bien (j'ai vérifié le contenu du packet avec GDB, les données sont en effet les mêmes). Le code de réception fonctionne bien aussi côté serveur:

sf::Packet packet; 
sock.receive(packet); 
Map test; 
cout << "packet received" << endl; 

Vérification du contenu du paquet (toujours avec GDB) donne la même chose que quand il a été envoyé. Le contenu de test est aléatoire (ce qui est normal, car il n'a pas encore été initialisé).

Le vrai problème se produit lorsque la désérialisation les données par paquets réels à la variable test:

if(packet >> test) { 
    cout << test.tiles[0].coords.x; 
} else { 
    cout << "fail" << endl; 
} 

Le résultat imprimé est 0. Le désérialisation a bien (pas « échec » qui apparaît dans la console), mais les données Incorrect. L'inspection du contenu de test avec GDB révèle que tous les éléments de ses tableaux sont des 0. Voici la sortie de GDB:

(gdb) print test 
$1 = {tiles = {{coords = {x = 0, y = 0, z = 0}}, {coords = {x = 0, y = 0, z = 0}}, {coords = {x = 0, y = 0, z = 0}}, {coords = { 
     x = 0, y = 0, z = 0}}}} 

Ce qui pourrait être la cause de ceci? Je suis très sûr de faire quelque chose de mal ici, mais je ne comprends vraiment pas pourquoi.

Merci à l'avance pour toute aide :)

Répondre

1

Ok, j'ai finalement réussi à comprendre pourquoi cela ne fonctionne pas. La réponse, était, bien sûr, extrêmement stupide, et typique d'un débutant stupide C++: D. L'utilisation des fonctions de l'opérateur sans passer les objets par référence n'avait pas une seule chance de fonctionner (puisque le contenu de la variable resterait dans la fonction opérateur et ne serait pas changé).

donc, de changer cette situation

sf::Packet& operator>>(sf::Packet& packet, Map test) { 
    for(int i = 0; i < 4; i++) { 
     packet >> test.tiles[i]; 
    } 
    return packet; 
} 

à ceci:

sf::Packet& operator>>(sf::Packet& packet, Map& test) { 
    for(int i = 0; i < 4; i++) { 
     packet >> test.tiles[i]; 
    } 
    return packet; 
} 

travaillé beaucoup mieux :)