- numerous bugfixes including fixing a slowdown introduced in a previous recent checkin.

- Added Network Text Message queue as this is required in some tricky cases
- added more logging of memory cleanup events
- added memory safe snprintf calls
This commit is contained in:
Mark Vejvoda 2011-01-11 22:09:46 +00:00
parent 227f39ccf9
commit ccbd707ae1
13 changed files with 186 additions and 109 deletions

View File

@ -136,8 +136,16 @@ void Ai::init(AiInterface *aiInterface, int useStartLocation) {
}
Ai::~Ai() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] deleting AI aiInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,aiInterface);
deleteValues(tasks.begin(), tasks.end());
tasks.clear();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] deleting AI aiInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,aiInterface);
deleteValues(aiRules.begin(), aiRules.end());
aiRules.clear();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] deleting AI aiInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,aiInterface);
aiInterface = NULL;
}
void Ai::update() {

View File

@ -62,6 +62,10 @@ AiInterface::AiInterface(Game &game, int factionIndex, int teamIndex, int useSta
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
AiInterface::~AiInterface() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] deleting AI factionIndex = %d, teamIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,this->factionIndex,this->teamIndex);
cacheUnitHarvestResourceLookup.clear();
}
// ==================== main ====================
void AiInterface::update() {

View File

@ -51,6 +51,7 @@ private:
public:
AiInterface(Game &game, int factionIndex, int teamIndex, int useStartLocation=-1);
~AiInterface();
//main
void update();

View File

@ -40,6 +40,7 @@ Logger::Logger(){
fileName= logs_path + "log.txt";
loadingTexture=NULL;
showProgressBar = false;
}
Logger::~Logger() {
@ -97,7 +98,6 @@ void Logger::clear(){
fclose(f);
}
void Logger::loadLoadingScreen(string filepath) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -152,13 +152,14 @@ void Logger::renderLoadingScreen() {
metrics.getVirtualW()/4,
62*metrics.getVirtualH()/100, false);
if(showProgressBar == true) {
renderer.renderProgressBar(
progress,
metrics.getVirtualW()/4,
59*metrics.getVirtualH()/100,
coreData.getDisplayFontSmall(),
350,""); // no string here, because it has to be language specific and does not give much information
}
renderer.swapBuffers();
}

View File

@ -44,6 +44,7 @@ private:
string current;
Texture2D *loadingTexture;
int progress;
bool showProgressBar;
private:
Logger();
@ -59,6 +60,8 @@ public:
void setSubtitle(const string &subtitle) {this->subtitle= subtitle;}
void setProgress(int value) { this->progress = value; }
int getProgress() const {return progress;}
void showProgress() { showProgressBar = true;}
void hideProgress() { showProgressBar = false;}
void add(const string &str, bool renderScreen= false);
void loadLoadingScreen(string filepath);

View File

@ -152,18 +152,18 @@ void CommanderNetworkThread::execute() {
// =====================================================
Commander::Commander() {
this->networkThread = new CommanderNetworkThread(this);
this->networkThread->setUniqueID(__FILE__);
this->networkThread->start();
//this->networkThread = new CommanderNetworkThread(this);
//this->networkThread->setUniqueID(__FILE__);
//this->networkThread->start();
}
Commander::~Commander() {
if(BaseThread::shutdownAndWait(networkThread) == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete networkThread;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
networkThread = NULL;
//if(BaseThread::shutdownAndWait(networkThread) == true) {
// SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
// delete networkThread;
// SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//}
//networkThread = NULL;
}
void Commander::init(World *world){
@ -455,6 +455,9 @@ CommandResult Commander::pushNetworkCommand(const NetworkCommand* networkCommand
}
void Commander::signalNetworkUpdate(Game *game) {
updateNetwork(game);
/*
if(this->networkThread != NULL) {
this->game = game;
this->networkThread->signalUpdate(1);
@ -465,10 +468,11 @@ void Commander::signalNetworkUpdate(Game *game) {
game->render();
}
}
*/
}
void Commander::commanderNetworkUpdateTask(int id) {
updateNetwork(game);
//updateNetwork(game);
}
void Commander::updateNetwork(Game *game) {
@ -476,6 +480,7 @@ void Commander::updateNetwork(Game *game) {
//check that this is a keyframe
//GameSettings *gameSettings = this->world->getGame()->getGameSettings();
if(game != NULL) {
GameSettings *gameSettings = game->getGameSettings();
if( networkManager.isNetworkGame() == false ||
(world->getFrameCount() % gameSettings->getNetworkFramePeriod()) == 0) {
@ -498,6 +503,7 @@ void Commander::updateNetwork(Game *game) {
gameNetworkInterface->clearPendingCommands();
}
}
}
/*
void Commander::giveNetworkCommandSpecial(const NetworkCommand* networkCommand) const {

View File

@ -77,8 +77,8 @@ private:
World *world;
Chrono perfTimer;
CommanderNetworkThread *networkThread;
Game *game;
//CommanderNetworkThread *networkThread;
//Game *game;
public:
Commander();

View File

@ -89,6 +89,9 @@ Game::Game(Program *program, const GameSettings *gameSettings):
speed= sNormal;
showFullConsole= false;
Logger &logger= Logger::getInstance();
logger.showProgress();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
@ -108,6 +111,7 @@ Game::~Game() {
logger.loadLoadingScreen("");
logger.setState(Lang::getInstance().get("Deleting"));
logger.add("Game", true);
logger.hideProgress();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -116,6 +120,7 @@ Game::~Game() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
deleteValues(aiInterfaces.begin(), aiInterfaces.end());
aiInterfaces.clear();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -125,7 +130,7 @@ Game::~Game() {
world.end(); //must die before selection because of referencers
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] aiInterfaces.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,aiInterfaces.size());
// MUST DO THIS LAST!!!! Because objects above have pointers to things like
// unit particles and fade them out etc and this end method deletes the original
@ -546,6 +551,8 @@ void Game::init(bool initForPreviewOnly)
bool isNetworkGame = this->gameSettings.isNetworkGame();
NetworkRole role = networkManager.getNetworkRole();
deleteValues(aiInterfaces.begin(), aiInterfaces.end());
aiInterfaces.resize(world.getFactionCount());
for(int i=0; i < world.getFactionCount(); ++i) {
Faction *faction= world.getFaction(i);

View File

@ -124,13 +124,17 @@ void ClientInterface::update() {
}
}
int lastSendElapsed = difftime(time(NULL),lastNetworkCommandListSendTime);
if(lastNetworkCommandListSendTime > 0) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] lastSendElapsed = %d\n",__FILE__,__FUNCTION__,__LINE__,lastSendElapsed);
double lastSendElapsed = difftime(time(NULL),lastNetworkCommandListSendTime);
if(lastNetworkCommandListSendTime > 0) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] lastSendElapsed = %f\n",__FILE__,__FUNCTION__,__LINE__,lastSendElapsed);
if(networkMessageCommandList.getCommandCount() > 0 ||
(lastNetworkCommandListSendTime > 0 && lastSendElapsed >= ClientInterface::maxNetworkCommandListSendTimeWait)) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
lastNetworkCommandListSendTime = time(NULL);
sendMessage(&networkMessageCommandList);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
// Possible cause of out of synch since we have more commands that need

View File

@ -263,6 +263,10 @@ ConnectionSlot::ConnectionSlot(ServerInterface* serverInterface, int playerIndex
ConnectionSlot::~ConnectionSlot() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] START\n",__FILE__,__FUNCTION__,__LINE__);
close();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(BaseThread::shutdownAndWait(slotThreadWorker) == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete slotThreadWorker;
@ -270,8 +274,6 @@ ConnectionSlot::~ConnectionSlot() {
}
slotThreadWorker = NULL;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
close();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
}

View File

@ -264,14 +264,15 @@ bool ServerInterface::switchSlot(int fromPlayerIndex,int toPlayerIndex) {
}
void ServerInterface::removeSlot(int playerIndex,int lockedSlotIndex) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__));
// Mention to everyone that this player is disconnected
MutexSafeWrapper safeMutexSlot(NULL,intToStr(__LINE__) + "_" + intToStr(playerIndex));
if(playerIndex != lockedSlotIndex) {
safeMutexSlot.setMutex(&slotAccessorMutexes[playerIndex],intToStr(__LINE__) + "_" + intToStr(playerIndex));
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
safeMutexSlot.setMutex(&slotAccessorMutexes[playerIndex],intToStr(__LINE__) + string("_") + intToStr(playerIndex));
}
ConnectionSlot *slot = slots[playerIndex];
@ -279,7 +280,7 @@ void ServerInterface::removeSlot(int playerIndex,int lockedSlotIndex) {
bool notifyDisconnect = false;
char szBuf[4096]="";
if(slot != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
if(slot->getLastReceiveCommandListTime() > 0) {
const char* msgTemplate = "Player %s, disconnected from the game.";
@ -293,30 +294,31 @@ void ServerInterface::removeSlot(int playerIndex,int lockedSlotIndex) {
notifyDisconnect = true;
}
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
slots[playerIndex]= NULL;
safeMutexSlot.ReleaseLock();
safeMutex.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
delete slot;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
updateListen();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
if(notifyDisconnect == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
string sMsg = szBuf;
sendTextMessage(sMsg,-1, true, lockedSlotIndex);
//sendTextMessage(sMsg,-1, true, lockedSlotIndex);
queueTextMessage(sMsg,-1, true);
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
}
ConnectionSlot* ServerInterface::getSlot(int playerIndex) {
@ -602,6 +604,8 @@ void ServerInterface::update() {
// properly identified themselves within the alloted time period
validateConnectedClients();
processTextMessageQueue();
std::map<PLATFORM_SOCKET,bool> socketTriggeredList;
//update all slots
updateSocketTriggeredList(socketTriggeredList);
@ -642,7 +646,7 @@ void ServerInterface::update() {
threadsDone = true;
// Examine all threads for completion of delegation
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + string("_") + intToStr(i));
ConnectionSlot* connectionSlot = slots[i];
if(connectionSlot != NULL && mapSlotSignalledList[i] == true &&
slotsCompleted.find(i) == slotsCompleted.end()) {
@ -1095,6 +1099,27 @@ void ServerInterface::waitUntilReady(Checksum* checksum) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] END\n",__FUNCTION__);
}
void ServerInterface::processTextMessageQueue() {
MutexSafeWrapper safeMutexSlot(&textMessageQueueThreadAccessor,intToStr(__LINE__));
if(textMessageQueue.size() > 0) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
for(int i = 0; i < textMessageQueue.size(); ++i) {
TextMessageQueue &item = textMessageQueue[i];
sendTextMessage(item.text, item.teamIndex, item.echoLocal);
}
textMessageQueue.clear();
}
}
void ServerInterface::queueTextMessage(const string &text, int teamIndex, bool echoLocal) {
MutexSafeWrapper safeMutexSlot(&textMessageQueueThreadAccessor,intToStr(__LINE__));
TextMessageQueue item;
item.text = text;
item.teamIndex = teamIndex;
item.echoLocal = echoLocal;
textMessageQueue.push_back(item);
}
void ServerInterface::sendTextMessage(const string &text, int teamIndex, bool echoLocal) {
sendTextMessage(text, teamIndex, echoLocal, -1);
}
@ -1327,6 +1352,8 @@ void ServerInterface::broadcastMessage(const NetworkMessage* networkMessage, int
}
}
else {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(NULL,intToStr(__LINE__) + "_" + intToStr(i));
if(i != lockedSlotIndex) {

View File

@ -35,6 +35,13 @@ namespace Glest{ namespace Game{
class ServerInterface: public GameNetworkInterface, public ConnectionSlotCallbackInterface, public SimpleTaskCallbackInterface, public FTPClientValidationInterface {
class TextMessageQueue {
public:
string text;
int teamIndex;
bool echoLocal;
};
private:
ConnectionSlot* slots[GameConstants::maxPlayers];
Mutex slotAccessorMutexes[GameConstants::maxPlayers];
@ -57,6 +64,9 @@ private:
bool exitServer;
int64 nextEventId;
Mutex textMessageQueueThreadAccessor;
vector<TextMessageQueue> textMessageQueue;
public:
ServerInterface();
virtual ~ServerInterface();
@ -75,6 +85,8 @@ public:
virtual void sendTextMessage(const string &text, int teamIndex, bool echoLocal=false);
void sendTextMessage(const string &text, int teamIndex, bool echoLocal, int lockedSlotIndex);
void queueTextMessage(const string &text, int teamIndex, bool echoLocal=false);
virtual void quitGame(bool userManuallyQuit);
//misc
@ -138,6 +150,8 @@ private:
std::map<string,string> publishToMasterserver();
int64 getNextEventId();
void processTextMessageQueue();
};
}}//end namespace

View File

@ -106,25 +106,25 @@ string boolToStr(bool b){
string intToStr(int64 i) {
char str[strSize]="";
sprintf(str, "%lld", (long long int)i);
snprintf(str, strSize-1, "%lld", (long long int)i);
return str;
}
string intToHex(int i){
char str[strSize]="";
sprintf(str, "%x", i);
snprintf(str, strSize-1, "%x", i);
return str;
}
string floatToStr(float f,int precsion) {
char str[strSize]="";
sprintf(str, "%.*f", precsion,f);
snprintf(str, strSize-1, "%.*f", precsion,f);
return str;
}
string doubleToStr(double d,int precsion) {
char str[strSize]="";
sprintf(str, "%.*f", precsion,d);
snprintf(str, strSize-1, "%.*f", precsion,d);
return str;
}