- attempt to improve issues in the custom menu related to freezing

- modified debug UI display to support multi levels of UI debug info
- added more validations to mutexes
- improved client sockets to properly be setup as non blocking
This commit is contained in:
Mark Vejvoda 2011-02-06 07:01:54 +00:00
parent 0380bcdb5d
commit c58e893047
11 changed files with 96 additions and 19 deletions

View File

@ -1744,10 +1744,12 @@ void Game::render2d(){
10, metrics.getVirtualH() - mh - 90 - 210 - (i * 16), false); 10, metrics.getVirtualH() - mh - 90 - 210 - (i * 16), false);
} }
if(renderer.getAllowRenderUnitTitles() == false) { if((renderer.getShowDebugUILevel() & debugui_unit_titles) == debugui_unit_titles) {
renderer.setAllowRenderUnitTitles(true); if(renderer.getAllowRenderUnitTitles() == false) {
renderer.setAllowRenderUnitTitles(true);
}
renderer.renderUnitTitles(coreData.getMenuFontNormal(),Vec3f(1.0f));
} }
renderer.renderUnitTitles(coreData.getMenuFontNormal(),Vec3f(1.0f));
} }
//network status //network status

View File

@ -150,6 +150,7 @@ Renderer::Renderer() {
this->menu = NULL; this->menu = NULL;
this->game = NULL; this->game = NULL;
showDebugUI = false; showDebugUI = false;
showDebugUILevel = debugui_fps;
modelRenderer = NULL; modelRenderer = NULL;
textRenderer = NULL; textRenderer = NULL;
particleRenderer = NULL; particleRenderer = NULL;
@ -2439,7 +2440,9 @@ void Renderer::renderSelectionEffects() {
//selection circle //selection circle
if(world->getThisFactionIndex() == unit->getFactionIndex()) { if(world->getThisFactionIndex() == unit->getFactionIndex()) {
if( showDebugUI == true && unit->getCommandSize() > 0 && if( showDebugUI == true &&
((showDebugUILevel & debugui_unit_titles) == debugui_unit_titles) &&
unit->getCommandSize() > 0 &&
dynamic_cast<const BuildCommandType *>(unit->getCurrCommand()->getCommandType()) != NULL) { dynamic_cast<const BuildCommandType *>(unit->getCurrCommand()->getCommandType()) != NULL) {
glColor4f(unit->getHpRatio(), unit->getHpRatio(), unit->getHpRatio(), 0.3f); glColor4f(unit->getHpRatio(), unit->getHpRatio(), unit->getHpRatio(), 0.3f);
} }
@ -4744,5 +4747,15 @@ Texture2D * Renderer::findFactionLogoTexture(string logoFilename) {
return result; return result;
} }
void Renderer::cycleShowDebugUILevel() {
if((showDebugUILevel & debugui_fps) != debugui_fps ||
(showDebugUILevel & debugui_unit_titles) != debugui_unit_titles) {
showDebugUILevel |= debugui_fps;
showDebugUILevel |= debugui_unit_titles;
}
else {
showDebugUILevel = debugui_fps;
}
}
}}//end namespace }}//end namespace

View File

@ -42,6 +42,11 @@
#include "leak_dumper.h" #include "leak_dumper.h"
enum DebugUILevelType {
debugui_fps = 0x01,
debugui_unit_titles = 0x02
};
namespace Glest{ namespace Game{ namespace Glest{ namespace Game{
using namespace Shared::Graphics; using namespace Shared::Graphics;
@ -246,6 +251,7 @@ private:
bool no2DMouseRendering; bool no2DMouseRendering;
bool showDebugUI; bool showDebugUI;
int showDebugUILevel;
int lastRenderFps; int lastRenderFps;
float smoothedRenderFps; float smoothedRenderFps;
@ -412,6 +418,10 @@ public:
bool getShowDebugUI() const { return showDebugUI; } bool getShowDebugUI() const { return showDebugUI; }
void setShowDebugUI(bool value) { showDebugUI = value; } void setShowDebugUI(bool value) { showDebugUI = value; }
int getShowDebugUILevel() const { return showDebugUILevel; }
void setShowDebugUILevel(int value) { showDebugUILevel=value; }
void cycleShowDebugUILevel();
void setLastRenderFps(int value); void setLastRenderFps(int value);
int getLastRenderFps() const { return lastRenderFps;} int getLastRenderFps() const { return lastRenderFps;}

View File

@ -664,9 +664,15 @@ void MainWindow::eventKeyDown(char key){
Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys)); Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
if(key == configKeys.getCharKey("HotKeyShowDebug")) { if(key == configKeys.getCharKey("HotKeyShowDebug")) {
Renderer &renderer= Renderer::getInstance(); Renderer &renderer= Renderer::getInstance();
bool showDebugUI = renderer.getShowDebugUI(); if(keystate.mod & (KMOD_LCTRL | KMOD_RCTRL)) {
renderer.setShowDebugUI(!showDebugUI); renderer.cycleShowDebugUILevel();
}
else {
bool showDebugUI = renderer.getShowDebugUI();
renderer.setShowDebugUI(!showDebugUI);
}
} }
else if(key == configKeys.getCharKey("ReloadINI")) { else if(key == configKeys.getCharKey("ReloadINI")) {
Config &config = Config::getInstance(); Config &config = Config::getInstance();
@ -1579,6 +1585,7 @@ int glestMain(int argc, char** argv) {
return -1; return -1;
} }
//setVBOSupported(false);
// Explicitly disable VBO's // Explicitly disable VBO's
if(config.getBool("DisableVBO","false") == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_VBO]) == true) { if(config.getBool("DisableVBO","false") == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_VBO]) == true) {
setVBOSupported(false); setVBOSupported(false);

View File

@ -513,7 +513,7 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
GraphicComponent::applyAllCustomProperties(containerName); GraphicComponent::applyAllCustomProperties(containerName);
publishToMasterserverThread = new SimpleTaskThread(this,0,25); publishToMasterserverThread = new SimpleTaskThread(this,0,200);
publishToMasterserverThread->setUniqueID(__FILE__); publishToMasterserverThread->setUniqueID(__FILE__);
publishToMasterserverThread->start(); publishToMasterserverThread->start();

View File

@ -298,9 +298,13 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) {
if(serverInterface->getServerSocket() != NULL && if(serverInterface->getServerSocket() != NULL &&
serverInterface->getServerSocket()->hasDataToRead() == true) { serverInterface->getServerSocket()->hasDataToRead() == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to accept new client connection playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to accept new client connection playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
socket = serverInterface->getServerSocket()->accept(); Socket *newSocket = serverInterface->getServerSocket()->accept();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] called accept new client connection playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] called accept new client connection playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
if(socket != NULL) { if(newSocket != NULL) {
// Set Socket as non-blocking
newSocket->setBlock(false);
socket = newSocket;
this->connectedTime = time(NULL); this->connectedTime = time(NULL);
this->clearChatInfo(); this->clearChatInfo();
this->name = ""; this->name = "";

View File

@ -330,6 +330,8 @@ void ServerInterface::updateSlot(ConnectionSlotEvent *event) {
bool checkForNewClients = true; bool checkForNewClients = true;
// Safety check since we can experience a disconnect and the slot is NULL // Safety check since we can experience a disconnect and the slot is NULL
//Chrono chrono;
//chrono.start();
ConnectionSlot *connectionSlot = NULL; ConnectionSlot *connectionSlot = NULL;
MutexSafeWrapper safeMutexSlot(NULL); MutexSafeWrapper safeMutexSlot(NULL);
if(event->triggerId >= 0 && event->triggerId < GameConstants::maxPlayers) { if(event->triggerId >= 0 && event->triggerId < GameConstants::maxPlayers) {
@ -341,17 +343,29 @@ void ServerInterface::updateSlot(ConnectionSlotEvent *event) {
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] ERROR CONDITION, event->triggerId = %d\n",__FILE__,__FUNCTION__,__LINE__,event->triggerId); SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] ERROR CONDITION, event->triggerId = %d\n",__FILE__,__FUNCTION__,__LINE__,event->triggerId);
} }
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
if(connectionSlot != NULL && if(connectionSlot != NULL &&
(gameHasBeenInitiated == false || (gameHasBeenInitiated == false ||
(connectionSlot->getSocket() != NULL && socketTriggered == true))) { (connectionSlot->getSocket() != NULL && socketTriggered == true))) {
if(connectionSlot->isConnected() == false || socketTriggered == true) { if(connectionSlot->isConnected() == false || socketTriggered == true) {
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
safeMutexSlot.ReleaseLock(true);
connectionSlot->update(checkForNewClients,event->triggerId); connectionSlot->update(checkForNewClients,event->triggerId);
//chrono.start();
safeMutexSlot.Lock();
connectionSlot = slots[event->triggerId];
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
// This means no clients are trying to connect at the moment // This means no clients are trying to connect at the moment
if(connectionSlot != NULL && connectionSlot->getSocket() == NULL) { if(connectionSlot != NULL && connectionSlot->getSocket() == NULL) {
checkForNewClients = false; checkForNewClients = false;
} }
} }
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
} }
safeMutexSlot.ReleaseLock(); safeMutexSlot.ReleaseLock();
} }

View File

@ -71,10 +71,11 @@ class Mutex {
private: private:
SDL_mutex* mutex; SDL_mutex* mutex;
int refCount; int refCount;
string ownerId;
public: public:
Mutex(); Mutex(string ownerId="");
~Mutex(); ~Mutex();
void setOwnerId(string ownerId) { this->ownerId = ownerId; }
void p(); void p();
void v(); void v();
int getRefCount() const { return refCount; } int getRefCount() const { return refCount; }

View File

@ -83,12 +83,18 @@ void Mesh::end() {
ReleaseVBOs(); ReleaseVBOs();
delete [] vertices; delete [] vertices;
vertices=NULL;
delete [] normals; delete [] normals;
normals=NULL;
delete [] texCoords; delete [] texCoords;
texCoords=NULL;
delete [] tangents; delete [] tangents;
tangents=NULL;
delete [] indices; delete [] indices;
indices=NULL;
delete interpolationData; delete interpolationData;
interpolationData=NULL;
if(textureManager != NULL) { if(textureManager != NULL) {
for(int i = 0; i < meshTextureCount; ++i) { for(int i = 0; i < meshTextureCount; ++i) {
@ -109,11 +115,15 @@ void Mesh::buildInterpolationData(){
} }
void Mesh::updateInterpolationData(float t, bool cycle) { void Mesh::updateInterpolationData(float t, bool cycle) {
interpolationData->update(t, cycle); if(interpolationData != NULL) {
interpolationData->update(t, cycle);
}
} }
void Mesh::updateInterpolationVertices(float t, bool cycle) { void Mesh::updateInterpolationVertices(float t, bool cycle) {
interpolationData->updateVertices(t, cycle); if(interpolationData != NULL) {
interpolationData->updateVertices(t, cycle);
}
} }
void Mesh::BuildVBOs() { void Mesh::BuildVBOs() {
@ -155,6 +165,9 @@ void Mesh::BuildVBOs() {
delete [] normals; normals = NULL; delete [] normals; normals = NULL;
delete [] indices; indices = NULL; delete [] indices; indices = NULL;
delete interpolationData;
interpolationData = NULL;
hasBuiltVBOs = true; hasBuiltVBOs = true;
} }
} }
@ -167,6 +180,7 @@ void Mesh::ReleaseVBOs() {
glDeleteBuffersARB( 1, &m_nVBOTexCoords ); // Get A Valid Name glDeleteBuffersARB( 1, &m_nVBOTexCoords ); // Get A Valid Name
glDeleteBuffersARB( 1, &m_nVBONormals ); // Get A Valid Name glDeleteBuffersARB( 1, &m_nVBONormals ); // Get A Valid Name
glDeleteBuffersARB( 1, &m_nVBOIndexes ); // Get A Valid Name glDeleteBuffersARB( 1, &m_nVBOIndexes ); // Get A Valid Name
hasBuiltVBOs = false;
} }
} }
} }

View File

@ -1072,6 +1072,7 @@ int Socket::send(const void *data, int dataSize) {
#else #else
bytesSent = ::send(sock, (const char *)data, dataSize, MSG_NOSIGNAL | MSG_DONTWAIT); bytesSent = ::send(sock, (const char *)data, dataSize, MSG_NOSIGNAL | MSG_DONTWAIT);
#endif #endif
safeMutex.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 EAGAIN during send, trying again returned: %d\n",__FILE__,__FUNCTION__,__LINE__,bytesSent); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 EAGAIN during send, trying again returned: %d\n",__FILE__,__FUNCTION__,__LINE__,bytesSent);
@ -1113,6 +1114,8 @@ int Socket::send(const void *data, int dataSize) {
#else #else
bytesSent = ::send(sock, &sendBuf[totalBytesSent], dataSize - totalBytesSent, MSG_NOSIGNAL | MSG_DONTWAIT); bytesSent = ::send(sock, &sendBuf[totalBytesSent], dataSize - totalBytesSent, MSG_NOSIGNAL | MSG_DONTWAIT);
#endif #endif
safeMutex.ReleaseLock();
if(bytesSent > 0) { if(bytesSent > 0) {
totalBytesSent += bytesSent; totalBytesSent += bytesSent;
} }
@ -1186,6 +1189,7 @@ int Socket::receive(void *data, int dataSize) {
else if(Socket::isReadable() == true) { else if(Socket::isReadable() == true) {
MutexSafeWrapper safeMutex(&dataSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); MutexSafeWrapper safeMutex(&dataSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__));
bytesReceived = recv(sock, reinterpret_cast<char*>(data), dataSize, 0); bytesReceived = recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
safeMutex.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 EAGAIN during receive, trying again returned: %d\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 EAGAIN during receive, trying again returned: %d\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived);
} }
@ -1207,7 +1211,7 @@ int Socket::peek(void *data, int dataSize) {
ssize_t err = 0; ssize_t err = 0;
if(isSocketValid() == true) { if(isSocketValid() == true) {
MutexSafeWrapper safeMutex(&dataSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); MutexSafeWrapper safeMutex(&dataSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(sock) + "_" + intToStr(dataSize));
err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK); err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
} }
if(err < 0 && getLastSocketError() != PLATFORM_SOCKET_TRY_AGAIN) { if(err < 0 && getLastSocketError() != PLATFORM_SOCKET_TRY_AGAIN) {
@ -1217,7 +1221,7 @@ int Socket::peek(void *data, int dataSize) {
disconnectSocket(); disconnectSocket();
} }
else if(err < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) { else if(err < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 EAGAIN during peek, trying again...\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 ERROR EAGAIN during peek, trying again...\n",__FILE__,__FUNCTION__,__LINE__);
time_t tStartTimer = time(NULL); time_t tStartTimer = time(NULL);
while((err < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) && while((err < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) &&
@ -1232,6 +1236,7 @@ int Socket::peek(void *data, int dataSize) {
else if(Socket::isReadable() == true) { else if(Socket::isReadable() == true) {
MutexSafeWrapper safeMutex(&dataSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); MutexSafeWrapper safeMutex(&dataSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__));
err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK); err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
safeMutex.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 EAGAIN during peek, trying again returned: %d\n",__FILE__,__FUNCTION__,__LINE__,err); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 EAGAIN during peek, trying again returned: %d\n",__FILE__,__FUNCTION__,__LINE__,err);
} }

View File

@ -77,8 +77,9 @@ void Thread::resume() {
// Mutex // Mutex
// ===================================== // =====================================
Mutex::Mutex() { Mutex::Mutex(string ownerId) {
refCount=0; refCount=0;
this->ownerId = ownerId;
mutex = SDL_CreateMutex(); mutex = SDL_CreateMutex();
assert(mutex != NULL); assert(mutex != NULL);
if(mutex == NULL) { if(mutex == NULL) {
@ -91,9 +92,15 @@ Mutex::Mutex() {
Mutex::~Mutex() { Mutex::~Mutex() {
if(mutex == NULL) { if(mutex == NULL) {
char szBuf[1024]=""; char szBuf[1024]="";
snprintf(szBuf,1023,"In [%s::%s Line: %d] mutex == NULL",__FILE__,__FUNCTION__,__LINE__); snprintf(szBuf,1023,"In [%s::%s Line: %d] mutex == NULL refCount = %d owner [%s]",__FILE__,__FUNCTION__,__LINE__,refCount,ownerId.c_str());
throw runtime_error(szBuf); throw runtime_error(szBuf);
} }
else if(refCount >= 1) {
char szBuf[1024]="";
snprintf(szBuf,1023,"In [%s::%s Line: %d] about to destroy mutex refCount = %d owner [%s]",__FILE__,__FUNCTION__,__LINE__,refCount,ownerId.c_str());
throw runtime_error(szBuf);
}
SDL_DestroyMutex(mutex); SDL_DestroyMutex(mutex);
mutex=NULL; mutex=NULL;
} }
@ -101,7 +108,7 @@ Mutex::~Mutex() {
void Mutex::p() { void Mutex::p() {
if(mutex == NULL) { if(mutex == NULL) {
char szBuf[1024]=""; char szBuf[1024]="";
snprintf(szBuf,1023,"In [%s::%s Line: %d] mutex == NULL",__FILE__,__FUNCTION__,__LINE__); snprintf(szBuf,1023,"In [%s::%s Line: %d] mutex == NULL refCount = %d owner [%s]",__FILE__,__FUNCTION__,__LINE__,refCount,ownerId.c_str());
throw runtime_error(szBuf); throw runtime_error(szBuf);
} }
SDL_mutexP(mutex); SDL_mutexP(mutex);
@ -111,7 +118,7 @@ void Mutex::p() {
void Mutex::v() { void Mutex::v() {
if(mutex == NULL) { if(mutex == NULL) {
char szBuf[1024]=""; char szBuf[1024]="";
snprintf(szBuf,1023,"In [%s::%s Line: %d] mutex == NULL",__FILE__,__FUNCTION__,__LINE__); snprintf(szBuf,1023,"In [%s::%s Line: %d] mutex == NULL refCount = %d owner [%s]",__FILE__,__FUNCTION__,__LINE__,refCount,ownerId.c_str());
throw runtime_error(szBuf); throw runtime_error(szBuf);
} }
refCount--; refCount--;