Salut alors je m'explique :
J'ai une classe statique World qui contient toutes les maps de mon jeux (côté serveur.), donc un static std::vector<Map>, je charge les maps à l'initialisation de ma classe serveur, donc, dans le thread principal.
Pour le serveur j'utilise un thread secondaire pour la réception des paquets venant du client, dans ce thread je récupère la map (de la classe world) sur laquelle est le client à partir du thread secondaire donc...
Sur windows ça marche très bien mais sur mon ubuntu, lorsque je veux récupéré la map sur laquelle est le client à partir de mon thread secondaire, je me retrouve avec un vector vide.
Je ne sais pas pour quelle raison mais on dirait que mon vecteur n'a pas été partagé entre mes deux threads. :/
Voici quelques bout de code pour plus de clarté :
Le constructeur de ma classe serveur, il charge la map, ceci se fait dans le thread principal.
SrkServer::SrkServer(int nbChannels) : thread(&SrkServer::run, this)
{
UpsMapLoader loader("Maps/test.upsmap");
Map *map = new Map();
if (loader.createMap(*map,map->getLightManager(), map->getImageManager())) {
World::addMap(map);
} else {
delete map;
}
for (int i = 0; i < nbChannels; i++) {
SrkChannel *channel = new SrkChannel(*this, "Channel "+conversionIntString(i+1));
channels.push_back(channel);
}
running = false;
}
Ma boucle qui réceptionne les messages du client ceci se fait dans mon thread secondaire :
void SrkServer::run () {
running = true;
while (running) {
if (selector.wait()) {
if (selector.isReady(listener)) {
TcpSocket *client = new TcpSocket();
if (listener.accept(*client) == Socket::Done) {
selector.add(*client);
Network::addUser(*client);
}
} else {
vector<TcpSocket*>::iterator it;
vector<TcpSocket*> clients = Network::getClients();
for (it = clients.begin(); it != clients.end(); it++) {
TcpSocket &client = **it;
if (selector.isReady(client)) {
Packet* packet;
bool pbKeyRsaSend = Network::hasPbKeyRsa(client);
bool pbKeySend = Network::hasPbKey(client);
bool authentified = Network::isAuthentified(client);
if (pbKeySend && pbKeyRsaSend) {
packet = new SymEncPacket ();
} else if (!pbKeySend && pbKeyRsaSend) {
packet = new EncryptedPacket ();
} else {
packet = new Packet();
}
if (client.receive(*packet) == Socket::Done) {
string request;
(*packet)>>request;
Network::addRequest (client, request);
if (pbKeySend && pbKeyRsaSend && authentified) {
Network::processLastResquest();
} else if (pbKeySend && pbKeyRsaSend && !authentified) {
Network::authentify(client);
} else if (!pbKeyRsaSend && request == "GetPbKeyRsa") {
Network::sendPbKeyRsa();
} else if (!pbKeySend && request == "GetPbKey") {
Network::sendPbKey();
} else {
selector.remove(client);
Network::removeUser(client);
}
} else {
selector.remove(client);
Network::removeUser(client);
for (unsigned int i = 0; i < channels.size(); i++){
channels[i]->removeClient(client);
}
}
}
}
}
}
}
}
Ma classe world, classe statique qui contient toutes les maps, j'ai fait une classe statique ainsi je ne dois pas à chaque fois passé la variable world à toute les classes qui utilisent la classe map, et puis comme il n'y a que une seul monde..., j'ai fait aussi pareil avec une classe Network qui se charge de traiter toutes les requêtes provenant du client.
#include "world.h"
using namespace std;
vector<Map*> World::maps = vector<Map*> ();
void World::addMap (Map *map) {
maps.push_back(map);
}
Map* World::getMap (string mapName) {
vector<Map*>::iterator it;
cout<<"Map size : "<<maps.size()<<endl;
for (it = maps.begin(); it != maps.end(); it++) {
if ((*it)->getName() == mapName) {
return *it;
}
}
return NULL;
}
World::~World() {
for (unsigned int i = 0; i < maps.size(); i++)
delete maps[i];
maps.clear();
}
Voilà et lorsque j'appelle Network::processLastRequest(), à partir de mon second thread mon vecteur maps de ma classe statique World est vide (je n'ai ce problème que sur linux.), donc quand je veux récupérer la map ça me retourne une adresse null et ça plante. :/
void Network::loadMap(TcpSocket &client, string mapName) {
Map *map = World::getMap(mapName);
cout<<"Map : "<<map<<endl;
loadPathsImages(client, map);
loadTiles(client, map);
loadAnims(client, map);
loadLights(client, map);
loadWalls(client, map);
}
PS : processLastRequest appelle loadMap.
PS 2 : je n'ai ce problème apparemment que avec les variables statique, toutes les variables qui ne sont pas statiques semblent être partagées entre les différents threads.