- better error handling, try to display proper error message and restore state as best as possible

This commit is contained in:
Mark Vejvoda 2012-04-02 01:45:13 +00:00
parent 7f0aaebf50
commit fce4d55dd5
8 changed files with 228 additions and 124 deletions

View File

@ -578,6 +578,9 @@ int Commander::getReplayCommandListForFrameCount() const {
}
void Commander::updateNetwork(Game *game) {
if(world == NULL) {
return;
}
NetworkManager &networkManager= NetworkManager::getInstance();
//check that this is a keyframe

View File

@ -1160,7 +1160,7 @@ void Game::update() {
}
if(this->masterserverMode == false) {
if(world.getThisFaction()->getFirstSwitchTeamVote() != NULL) {
if(world.getFactionCount() > 0 && world.getThisFaction()->getFirstSwitchTeamVote() != NULL) {
const SwitchTeamVote *vote = world.getThisFaction()->getFirstSwitchTeamVote();
GameSettings *settings = world.getGameSettingsPtr();

View File

@ -1026,10 +1026,28 @@ string Config::findValidLocalFileFromPath(string fileName) {
string result = fileName;
// /home/user1/SCM/megaglest-trunk/mk/linux//techs/megapack/factions/tech/units/blacksmith/images/particle.bmp
// /home/user1/SCM/megaglest-trunk/mk/linux//tutorials/3_advanced_tutorial/3_advanced_tutorial.xml
size_t pos = fileName.find("techs/");
if(pos != fileName.npos ) {
string fileNamePart = fileName.substr(pos+6);
if(fileName.find("maps/") != fileName.npos ) {
size_t pos = fileName.find("maps/");
string fileNamePart = fileName.substr(pos+5);
Config &config = Config::getInstance();
vector<string> dirList = config.getPathListForType(ptMaps);
replaceFileWithLocalFile(dirList, fileNamePart, result);
printf("Found file [%s] @ %lu [%s]\nNew File [%s]\n",fileName.c_str(),pos,fileNamePart.c_str(),result.c_str());
}
else if(fileName.find("tilesets/") != fileName.npos ) {
size_t pos = fileName.find("tilesets/");
string fileNamePart = fileName.substr(pos+9);
Config &config = Config::getInstance();
vector<string> dirList = config.getPathListForType(ptTilesets);
replaceFileWithLocalFile(dirList, fileNamePart, result);
printf("Found file [%s] @ %lu [%s]\nNew File [%s]\n",fileName.c_str(),pos,fileNamePart.c_str(),result.c_str());
}
else if(fileName.find("techs/") != fileName.npos ) {
size_t pos = fileName.find("techs/");
string fileNamePart = fileName.substr(pos+6);
Config &config = Config::getInstance();
vector<string> dirList = config.getPathListForType(ptTechs);
replaceFileWithLocalFile(dirList, fileNamePart, result);
@ -1037,10 +1055,8 @@ string Config::findValidLocalFileFromPath(string fileName) {
printf("Found file [%s] @ %lu [%s]\nNew File [%s]\n",fileName.c_str(),pos,fileNamePart.c_str(),result.c_str());
}
else if(fileName.find("scenarios/") != fileName.npos) {
pos = fileName.find("scenarios/");
size_t pos = fileName.find("scenarios/");
string fileNamePart = fileName.substr(pos+10);
Config &config = Config::getInstance();
vector<string> dirList = config.getPathListForType(ptScenarios);
replaceFileWithLocalFile(dirList, fileNamePart, result);
@ -1048,10 +1064,8 @@ string Config::findValidLocalFileFromPath(string fileName) {
printf("Found file [%s] @ %lu [%s]\nNew File [%s]\n",fileName.c_str(),pos,fileNamePart.c_str(),result.c_str());
}
else if(fileName.find("tutorials/") != fileName.npos) {
pos = fileName.find("tutorials/");
size_t pos = fileName.find("tutorials/");
string fileNamePart = fileName.substr(pos+10);
Config &config = Config::getInstance();
vector<string> dirList = config.getPathListForType(ptTutorials);
replaceFileWithLocalFile(dirList, fileNamePart, result);

View File

@ -2148,6 +2148,11 @@ void Renderer::renderResourceStatus() {
const Metrics &metrics= Metrics::getInstance();
const World *world= game->getWorld();
if(world->getThisFactionIndex() < 0 || world->getThisFactionIndex() >= world->getFactionCount()) {
return;
}
const Faction *thisFaction= world->getFaction(world->getThisFactionIndex());
const Vec4f fontColor = game->getGui()->getDisplay()->getColor();
assertGl();
@ -2400,10 +2405,11 @@ void Renderer::renderText(const string &text, Font2D *font, float alpha, int x,
Vec2f Renderer::getCentered3DPos(const string &text, Font3D *font, Vec2f &pos, int w, int h,bool centeredW, bool centeredH) {
if(centeredW == true) {
if(font == NULL) {
throw runtime_error("font == NULL");
//abort();
throw runtime_error("font == NULL (5)");
}
else if(font->getTextHandler() == NULL) {
throw runtime_error("font->getTextHandler() == NULL");
throw runtime_error("font->getTextHandler() == NULL (5)");
}
float lineWidth = (font->getTextHandler()->Advance(text.c_str()) * Font::scaleFontValue);
@ -2414,10 +2420,10 @@ Vec2f Renderer::getCentered3DPos(const string &text, Font3D *font, Vec2f &pos, i
if(centeredH) {
if(font == NULL) {
throw runtime_error("font == NULL");
throw runtime_error("font == NULL (6)");
}
else if(font->getTextHandler() == NULL) {
throw runtime_error("font->getTextHandler() == NULL");
throw runtime_error("font->getTextHandler() == NULL (6)");
}
//const Metrics &metrics= Metrics::getInstance();
@ -3236,93 +3242,115 @@ void Renderer::renderMessageBox(GraphicMessageBox *messageBox) {
return;
}
if(messageBox->getVisible() == false) {
return;
try {
if(messageBox->getVisible() == false) {
return;
}
if((renderText3DEnabled == false && messageBox->getFont() == NULL) ||
(renderText3DEnabled == true && messageBox->getFont3D() == NULL)) {
messageBox->setFont(CoreData::getInstance().getMenuFontNormal());
messageBox->setFont3D(CoreData::getInstance().getMenuFontNormal3D());
}
//background
glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
glEnable(GL_BLEND);
glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ;
glBegin(GL_TRIANGLE_STRIP);
glVertex2i(messageBox->getX(), messageBox->getY()+9*messageBox->getH()/10);
glVertex2i(messageBox->getX(), messageBox->getY());
glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + 9*messageBox->getH()/10);
glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY());
glEnd();
glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ;
glBegin(GL_TRIANGLE_STRIP);
glVertex2i(messageBox->getX(), messageBox->getY()+messageBox->getH());
glVertex2i(messageBox->getX(), messageBox->getY()+9*messageBox->getH()/10);
glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + messageBox->getH());
glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY()+9*messageBox->getH()/10);
glEnd();
glBegin(GL_LINE_LOOP);
glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
glVertex2i(messageBox->getX(), messageBox->getY());
glColor4f(0.0f, 0.0f, 0.0f, 0.25f) ;
glVertex2i(messageBox->getX()+ messageBox->getW(), messageBox->getY());
glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
glVertex2i(messageBox->getX()+ messageBox->getW(), messageBox->getY() + messageBox->getH());
glColor4f(0.25f, 0.25f, 0.25f, 0.25f) ;
glVertex2i(messageBox->getX(), messageBox->getY() + messageBox->getH());
glEnd();
glBegin(GL_LINE_STRIP);
glColor4f(1.0f, 1.0f, 1.0f, 0.25f) ;
glVertex2i(messageBox->getX(), messageBox->getY() + 90*messageBox->getH()/100);
glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
glVertex2i(messageBox->getX()+ messageBox->getW(), messageBox->getY() + 90*messageBox->getH()/100);
glEnd();
glPopAttrib();
//buttons
for(int i=0; i<messageBox->getButtonCount();i++){
if((renderText3DEnabled == false && messageBox->getButton(i)->getFont() == NULL) ||
(renderText3DEnabled == true && messageBox->getButton(i)->getFont3D() == NULL)) {
messageBox->getButton(i)->setFont(CoreData::getInstance().getMenuFontNormal());
messageBox->getButton(i)->setFont3D(CoreData::getInstance().getMenuFontNormal3D());
}
renderButton(messageBox->getButton(i));
}
Vec4f fontColor;
//if(game!=NULL){
// fontColor=game->getGui()->getDisplay()->getColor();
//}
//else {
// white shadowed is default ( in the menu for example )
fontColor=Vec4f(1.f, 1.f, 1.f, 1.0f);
//}
if(renderText3DEnabled == true) {
//text
renderTextShadow3D(
messageBox->getText(), messageBox->getFont3D(), fontColor,
messageBox->getX()+15, messageBox->getY()+7*messageBox->getH()/10,
false );
renderTextShadow3D(
messageBox->getHeader(), messageBox->getFont3D(),fontColor,
messageBox->getX()+15, messageBox->getY()+93*messageBox->getH()/100,
false );
}
else {
//text
renderTextShadow(
messageBox->getText(), messageBox->getFont(), fontColor,
messageBox->getX()+15, messageBox->getY()+7*messageBox->getH()/10,
false );
renderTextShadow(
messageBox->getHeader(), messageBox->getFont(),fontColor,
messageBox->getX()+15, messageBox->getY()+93*messageBox->getH()/100,
false );
}
}
catch(const exception &e) {
char szBuf[8096]="";
sprintf(szBuf,"In [%s::%s Line: %d]\nError [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
//background
glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
glEnable(GL_BLEND);
glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ;
glBegin(GL_TRIANGLE_STRIP);
glVertex2i(messageBox->getX(), messageBox->getY()+9*messageBox->getH()/10);
glVertex2i(messageBox->getX(), messageBox->getY());
glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + 9*messageBox->getH()/10);
glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY());
glEnd();
glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ;
glBegin(GL_TRIANGLE_STRIP);
glVertex2i(messageBox->getX(), messageBox->getY()+messageBox->getH());
glVertex2i(messageBox->getX(), messageBox->getY()+9*messageBox->getH()/10);
glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + messageBox->getH());
glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY()+9*messageBox->getH()/10);
glEnd();
glBegin(GL_LINE_LOOP);
glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
glVertex2i(messageBox->getX(), messageBox->getY());
glColor4f(0.0f, 0.0f, 0.0f, 0.25f) ;
glVertex2i(messageBox->getX()+ messageBox->getW(), messageBox->getY());
glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
glVertex2i(messageBox->getX()+ messageBox->getW(), messageBox->getY() + messageBox->getH());
glColor4f(0.25f, 0.25f, 0.25f, 0.25f) ;
glVertex2i(messageBox->getX(), messageBox->getY() + messageBox->getH());
glEnd();
glBegin(GL_LINE_STRIP);
glColor4f(1.0f, 1.0f, 1.0f, 0.25f) ;
glVertex2i(messageBox->getX(), messageBox->getY() + 90*messageBox->getH()/100);
glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
glVertex2i(messageBox->getX()+ messageBox->getW(), messageBox->getY() + 90*messageBox->getH()/100);
glEnd();
glPopAttrib();
//buttons
for(int i=0; i<messageBox->getButtonCount();i++){
renderButton(messageBox->getButton(i));
}
Vec4f fontColor;
//if(game!=NULL){
// fontColor=game->getGui()->getDisplay()->getColor();
//}
//else {
// white shadowed is default ( in the menu for example )
fontColor=Vec4f(1.f, 1.f, 1.f, 1.0f);
//}
if(renderText3DEnabled == true) {
//text
renderTextShadow3D(
messageBox->getText(), messageBox->getFont3D(), fontColor,
messageBox->getX()+15, messageBox->getY()+7*messageBox->getH()/10,
false );
renderTextShadow3D(
messageBox->getHeader(), messageBox->getFont3D(),fontColor,
messageBox->getX()+15, messageBox->getY()+93*messageBox->getH()/100,
false );
}
else {
//text
renderTextShadow(
messageBox->getText(), messageBox->getFont(), fontColor,
messageBox->getX()+15, messageBox->getY()+7*messageBox->getH()/10,
false );
renderTextShadow(
messageBox->getHeader(), messageBox->getFont(),fontColor,
messageBox->getX()+15, messageBox->getY()+93*messageBox->getH()/100,
false );
throw runtime_error(szBuf);
}
}
@ -3842,6 +3870,9 @@ void Renderer::renderSurface(const int renderFps) {
float coordStep= world->getTileset()->getSurfaceAtlas()->getCoordStep();
const Texture2D *fowTex= world->getMinimap()->getFowTexture();
if(fowTex == NULL) {
return;
}
glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_FOG_BIT | GL_TEXTURE_BIT);
@ -4344,6 +4375,11 @@ void Renderer::renderWater() {
const World *world= game->getWorld();
const Map *map= world->getMap();
const Texture2D *fowTex= world->getMinimap()->getFowTexture();
if(fowTex == NULL) {
return;
}
float waterAnim= world->getWaterEffects()->getAmin();
//assert
@ -4372,7 +4408,7 @@ void Renderer::renderWater() {
assertGl();
//fog of War texture Unit
const Texture2D *fowTex= world->getMinimap()->getFowTexture();
//const Texture2D *fowTex= world->getMinimap()->getFowTexture();
glActiveTexture(fowTexUnit);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(fowTex)->getHandle());
@ -4990,6 +5026,11 @@ void Renderer::renderMinimap(){
const World *world= game->getWorld();
const Minimap *minimap= world->getMinimap();
if(minimap == NULL || minimap->getTexture() == NULL) {
return;
}
const GameCamera *gameCamera= game->getGameCamera();
const Pixmap2D *pixmap= minimap->getTexture()->getPixmapConst();
const Metrics &metrics= Metrics::getInstance();

View File

@ -122,7 +122,8 @@ Program::ShowMessageProgramState::ShowMessageProgramState(Program *program, cons
if(msg) {
fprintf(stderr, "%s\n", msg);
msgBox.setText(msg);
} else {
}
else {
msgBox.setText("Mega-Glest has crashed.");
}
@ -174,6 +175,8 @@ Program::Program() {
//this->masterserverMode = false;
this->shutdownApplicationEnabled = false;
this->skipRenderFrameCount = 0;
this->messageBoxIsSystemError = false;
this->programStateOldSystemError = NULL;
this->programState= NULL;
this->singleton = this;
this->soundThreadManager = NULL;
@ -297,6 +300,16 @@ Program::~Program(){
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
}
void Program::restoreStateFromSystemError() {
messageBoxIsSystemError = false;
if(this->programStateOldSystemError == NULL) {
setState(new Intro(this));
}
else {
setState(this->programStateOldSystemError);
}
}
void Program::keyDown(SDL_KeyboardEvent key) {
if(msgBox.getEnabled()) {
//SDL_keysym keystate = Window::getKeystate();
@ -309,7 +322,9 @@ void Program::keyDown(SDL_KeyboardEvent key) {
//printf("---> keystate [%d]\n",keystate);
msgBox.setEnabled(false);
if(messageBoxIsSystemError == true) {
restoreStateFromSystemError();
}
}
}
//delegate event
@ -331,6 +346,9 @@ void Program::mouseDownLeft(int x, int y) {
//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//close message box
msgBox.setEnabled(false);
if(messageBoxIsSystemError == true) {
restoreStateFromSystemError();
}
}
}
}
@ -485,11 +503,11 @@ void Program::renderProgramMsgBox() {
}
void Program::setState(ProgramState *programStateNew, bool cleanupOldState)
{
void Program::setState(ProgramState *programStateNew, bool cleanupOldState) {
try {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
this->programStateOldSystemError = this->programState;
bool msgBoxEnabled = msgBox.getEnabled();
bool showingOSCursor = isCursorShowing();
@ -516,6 +534,7 @@ void Program::setState(ProgramState *programStateNew, bool cleanupOldState)
if(this->programState != programStateNew) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
this->programStateOldSystemError = NULL;
delete this->programState;
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
@ -563,14 +582,28 @@ void Program::setState(ProgramState *programStateNew, bool cleanupOldState)
}
}
this->programStateOldSystemError = NULL;
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
}
catch(const exception &e){
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
char szBuf[8096]="";
sprintf(szBuf,"In [%s::%s Line: %d]\nError [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
//abort();
messageBoxIsSystemError = true;
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
if(dynamic_cast<Game *>(programStateNew) != NULL) {
Game *game = dynamic_cast<Game *>(programStateNew);
Renderer &renderer= Renderer::getInstance();
renderer.initGame(game,game->getGameCameraPtr());
}
}
this->showMessage(e.what());
setState(new Intro(this));
//setState(new Intro(this));
}
}
@ -752,6 +785,12 @@ void Program::showMessage(const char *msg) {
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
printf("Message:\n%s\n",msg);
if(messageBoxIsSystemError == true) {
messageBoxIsSystemError = false;
//setState(new Intro(this));
initServer(window,false,true,true);
}
}
}

View File

@ -147,6 +147,9 @@ private:
GraphicMessageBox msgBox;
int skipRenderFrameCount;
bool messageBoxIsSystemError;
ProgramState *programStateOldSystemError;
//bool masterserverMode;
bool shutdownApplicationEnabled;
static bool wantShutdownApplicationAfterGame;
@ -213,6 +216,7 @@ private:
void setDisplaySettings();
void restoreDisplaySettings();
void restoreStateFromSystemError();
};
}} //end namespace

View File

@ -1829,7 +1829,8 @@ string Map::getMapPath(const string &mapName, string scenarioDir, bool errorOnNo
}
if(errorOnNotFound == true) {
throw runtime_error("Map [" + mapName + "] not found, scenarioDir [" + scenarioDir + "]");
//abort();
throw runtime_error("Map not found [" + mapName + "]\nScenario [" + scenarioDir + "]");
}
return "";

View File

@ -539,26 +539,28 @@ void World::update(){
updateAllTilesetObjects();
//units
updateAllFactionUnits();
if(getFactionCount() > 0) {
updateAllFactionUnits();
//undertake the dead
underTakeDeadFactionUnits();
//}
//undertake the dead
underTakeDeadFactionUnits();
//}
//food costs
updateAllFactionConsumableCosts();
//food costs
updateAllFactionConsumableCosts();
//fow smoothing
if(fogOfWarSmoothing && ((frameCount+1) % (fogOfWarSmoothingFrameSkip+1))==0) {
float fogFactor= static_cast<float>(frameCount % GameConstants::updateFps) / GameConstants::updateFps;
minimap.updateFowTex(clamp(fogFactor, 0.f, 1.f));
}
//fow smoothing
if(fogOfWarSmoothing && ((frameCount+1) % (fogOfWarSmoothingFrameSkip+1))==0) {
float fogFactor= static_cast<float>(frameCount % GameConstants::updateFps) / GameConstants::updateFps;
minimap.updateFowTex(clamp(fogFactor, 0.f, 1.f));
}
//tick
bool needToTick = canTickWorld();
if(needToTick == true) {
//printf("=========== World is about to be updated, current frameCount = %d\n",frameCount);
tick();
//tick
bool needToTick = canTickWorld();
if(needToTick == true) {
//printf("=========== World is about to be updated, current frameCount = %d\n",frameCount);
tick();
}
}
}