- added support for proper quiting and console input/output in headless mode. Type: quit followed by return into the console to properly shutdown in headless mode.

This commit is contained in:
Mark Vejvoda 2011-09-27 10:16:09 +00:00
parent 9caff9dac3
commit 2a86cb4f7d
11 changed files with 158 additions and 85 deletions

View File

@ -106,6 +106,11 @@ Game::Game(Program *program, const GameSettings *gameSettings,bool masterserverM
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
this->masterserverMode = masterserverMode; this->masterserverMode = masterserverMode;
if(this->masterserverMode == true) {
printf("Starting a new game...\n");
}
this->program = program; this->program = program;
Unit::setGame(this); Unit::setGame(this);
gameStarted = false; gameStarted = false;
@ -930,6 +935,10 @@ void Game::init(bool initForPreviewOnly)
gameStarted = true; gameStarted = true;
if(this->masterserverMode == true) {
printf("New game has started...\n");
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ==== START GAME ==== getCurrentPixelByteCount() = %llu\n",__FILE__,__FUNCTION__,__LINE__,(long long unsigned int)renderer.getCurrentPixelByteCount()); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ==== START GAME ==== getCurrentPixelByteCount() = %llu\n",__FILE__,__FUNCTION__,__LINE__,(long long unsigned int)renderer.getCurrentPixelByteCount());
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"==== START GAME ====\n"); if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"==== START GAME ====\n");
} }

View File

@ -40,7 +40,8 @@ CoreData &CoreData::getInstance() {
} }
CoreData::~CoreData() { CoreData::~CoreData() {
deleteValues(waterSounds.getSounds().begin(), waterSounds.getSounds().end()); deleteValues(waterSounds.getSoundsPtr()->begin(), waterSounds.getSoundsPtr()->end());
waterSounds.getSoundsPtr()->clear();
} }
void CoreData::load() { void CoreData::load() {

View File

@ -5108,9 +5108,10 @@ void Renderer::renderShadowsToTexture(const int renderFps){
// ==================== gl wrap ==================== // ==================== gl wrap ====================
string Renderer::getGlInfo(){ string Renderer::getGlInfo(){
string infoStr; string infoStr="";
Lang &lang= Lang::getInstance(); Lang &lang= Lang::getInstance();
if(this->masterserverMode == false) {
infoStr+= lang.get("OpenGlInfo")+":\n"; infoStr+= lang.get("OpenGlInfo")+":\n";
infoStr+= " "+lang.get("OpenGlVersion")+": "; infoStr+= " "+lang.get("OpenGlVersion")+": ";
infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n"; infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n";
@ -5128,14 +5129,15 @@ string Renderer::getGlInfo(){
infoStr+= intToStr(getGlModelviewMatrixStackDepth())+"\n"; infoStr+= intToStr(getGlModelviewMatrixStackDepth())+"\n";
infoStr+= " "+lang.get("OpenGlProjectionStack")+": "; infoStr+= " "+lang.get("OpenGlProjectionStack")+": ";
infoStr+= intToStr(getGlProjectionMatrixStackDepth())+"\n"; infoStr+= intToStr(getGlProjectionMatrixStackDepth())+"\n";
}
return infoStr; return infoStr;
} }
string Renderer::getGlMoreInfo(){ string Renderer::getGlMoreInfo(){
string infoStr; string infoStr="";
Lang &lang= Lang::getInstance(); Lang &lang= Lang::getInstance();
if(this->masterserverMode == false) {
//gl extensions //gl extensions
infoStr+= lang.get("OpenGlExtensions")+":\n "; infoStr+= lang.get("OpenGlExtensions")+":\n ";
@ -5164,13 +5166,15 @@ string Renderer::getGlMoreInfo(){
} }
++charCount; ++charCount;
} }
}
return infoStr; return infoStr;
} }
void Renderer::autoConfig(){ void Renderer::autoConfig() {
if(this->masterserverMode == false) {
Config &config= Config::getInstance(); Config &config= Config::getInstance();
bool nvidiaCard= toLower(getGlVendor()).find("nvidia")!=string::npos; bool nvidiaCard= toLower(getGlVendor()).find("nvidia")!=string::npos;
bool atiCard= toLower(getGlVendor()).find("ati")!=string::npos; bool atiCard= toLower(getGlVendor()).find("ati")!=string::npos;
//bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow") && isGlExtensionSupported("GL_ARB_shadow_ambient"); //bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow") && isGlExtensionSupported("GL_ARB_shadow_ambient");
@ -5180,7 +5184,7 @@ void Renderer::autoConfig(){
config.setBool("Textures3D", isGlExtensionSupported("GL_EXT_texture3D")); config.setBool("Textures3D", isGlExtensionSupported("GL_EXT_texture3D"));
//shadows //shadows
string shadows; string shadows="";
if(getGlMaxTextureUnits()>=3){ if(getGlMaxTextureUnits()>=3){
if(nvidiaCard && shadowExtensions){ if(nvidiaCard && shadowExtensions){
shadows= shadowsToStr(sShadowMapping); shadows= shadowsToStr(sShadowMapping);
@ -5199,13 +5203,14 @@ void Renderer::autoConfig(){
//filter //filter
config.setString("Filter", "Bilinear"); config.setString("Filter", "Bilinear");
}
} }
void Renderer::clearBuffers(){ void Renderer::clearBuffers() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} }
void Renderer::clearZBuffer(){ void Renderer::clearZBuffer() {
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
} }

View File

@ -64,6 +64,8 @@
#include "leak_dumper.h" #include "leak_dumper.h"
#ifndef WIN32 #ifndef WIN32
#include <poll.h>
#define stricmp strcasecmp #define stricmp strcasecmp
#define strnicmp strncasecmp #define strnicmp strncasecmp
#define _strnicmp strncasecmp #define _strnicmp strncasecmp
@ -623,7 +625,7 @@ void handleSIGSEGV(int sig) {
// class MainWindow // class MainWindow
// ===================================================== // =====================================================
MainWindow::MainWindow(Program *program){ MainWindow::MainWindow(Program *program) : WindowGl() {
this->program= program; this->program= program;
} }
@ -3450,8 +3452,47 @@ int glestMain(int argc, char** argv) {
//printf("[%s]",test.c_str()); //printf("[%s]",test.c_str());
//time_t lastTextureLoadEvent = time(NULL); //time_t lastTextureLoadEvent = time(NULL);
// Check for commands being input from stdin
string command="";
#ifndef WIN32
pollfd cinfd[1];
// Theoretically this should always be 0, but one fileno call isn't going to hurt, and if
// we try to run somewhere that stdin isn't fd 0 then it will still just work
cinfd[0].fd = fileno(stdin);
cinfd[0].events = POLLIN;
#else
HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
#endif
if(isMasterServerModeEnabled == true) {
printf("Headless server is now running...\n");
}
//main loop //main loop
while(Window::handleEvent()) { while(Window::handleEvent()) {
if(isMasterServerModeEnabled == true) {
#ifndef WIN32
if(poll(cinfd, 1, 0))
#else
// This is problematic because input on Windows is not line-buffered so this will return
// even if getline may block. I haven't found a good way to fix it, so for the moment
// I just strongly suggest only running the server from the Python frontend, which does
// line buffer input. This does work okay as long as the user doesn't enter characters
// without pressing enter, and then try to end the server another way (say a remote
// console command), in which case we'll still be waiting for the stdin EOL and hang.
if (WaitForSingleObject(h, 0) == WAIT_OBJECT_0)
#endif
{
getline(cin, command);
printf("server command [%s]\n",command.c_str());
if(command == "quit") {
break;
}
}
//printf("looping\n");
}
program->loop(); program->loop();
// Because OpenGL really doesn't do multi-threading well // Because OpenGL really doesn't do multi-threading well
// if(difftime(time(NULL),lastTextureLoadEvent) >= 3) { // if(difftime(time(NULL),lastTextureLoadEvent) >= 3) {
@ -3468,6 +3509,10 @@ int glestMain(int argc, char** argv) {
// } // }
} }
if(isMasterServerModeEnabled == true) {
printf("\nHeadless server is about to quit...\n");
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] starting normal application shutdown\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] starting normal application shutdown\n",__FILE__,__FUNCTION__,__LINE__);
cleanupCRCThread(); cleanupCRCThread();

View File

@ -84,11 +84,13 @@ void ProgramState::render() {
canRender(); canRender();
incrementFps(); incrementFps();
if(renderer.isMasterserverMode() == false) {
renderer.clearBuffers(); renderer.clearBuffers();
renderer.reset2d(); renderer.reset2d();
renderer.renderMessageBox(program->getMsgBox()); renderer.renderMessageBox(program->getMsgBox());
renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim); renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim);
renderer.swapBuffers(); renderer.swapBuffers();
}
} }
void ProgramState::update() { void ProgramState::update() {
@ -419,7 +421,7 @@ void Program::renderProgramMsgBox() {
} }
} }
void Program::setState(ProgramState *programState, bool cleanupOldState) void Program::setState(ProgramState *programStateNew, bool cleanupOldState)
{ {
try { try {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -427,13 +429,13 @@ void Program::setState(ProgramState *programState, bool cleanupOldState)
bool msgBoxEnabled = msgBox.getEnabled(); bool msgBoxEnabled = msgBox.getEnabled();
bool showingOSCursor = isCursorShowing(); bool showingOSCursor = isCursorShowing();
if(dynamic_cast<Game *>(programState) != NULL) { if(dynamic_cast<Game *>(programStateNew) != NULL) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
int X = 0; int X = 0;
int Y = 0; int Y = 0;
SDL_GetMouseState(&X,&Y); SDL_GetMouseState(&X,&Y);
programState->setStartXY(X,Y); programStateNew->setStartXY(X,Y);
Logger::getInstance().setProgress(0); Logger::getInstance().setProgress(0);
Logger::getInstance().setState(""); Logger::getInstance().setState("");
@ -447,7 +449,7 @@ void Program::setState(ProgramState *programState, bool cleanupOldState)
} }
if(cleanupOldState == true) { if(cleanupOldState == true) {
if(this->programState != programState) { if(this->programState != programStateNew) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete this->programState; delete this->programState;
@ -471,13 +473,13 @@ void Program::setState(ProgramState *programState, bool cleanupOldState)
updateTimer.init(GameConstants::updateFps, maxTimes); updateTimer.init(GameConstants::updateFps, maxTimes);
updateCameraTimer.init(GameConstants::cameraFps, maxTimes); updateCameraTimer.init(GameConstants::cameraFps, maxTimes);
this->programState= programState; this->programState= programStateNew;
assert(programState != NULL); assert(programStateNew != NULL);
programState->load(); programStateNew->load();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
programState->init(); programStateNew->init();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -492,7 +494,7 @@ void Program::setState(ProgramState *programState, bool cleanupOldState)
} }
sleep(0); sleep(0);
if(dynamic_cast<Intro *>(programState) != NULL && msgBoxEnabled == true) { if(dynamic_cast<Intro *>(programStateNew) != NULL && msgBoxEnabled == true) {
showCursor(true); showCursor(true);
} }
} }

View File

@ -173,7 +173,7 @@ public:
bool isMessageShowing(); bool isMessageShowing();
//misc //misc
void setState(ProgramState *programState,bool cleanupOldState=true); void setState(ProgramState *programStateNew,bool cleanupOldState=true);
ProgramState * getState() { return programState;} ProgramState * getState() { return programState;}
WindowGl * getWindow() { return window; } WindowGl * getWindow() { return window; }
void init(WindowGl *window, bool initSound=true, bool toggleFullScreen=false); void init(WindowGl *window, bool initSound=true, bool toggleFullScreen=false);

View File

@ -53,6 +53,10 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu,
MenuState(program, mainMenu, "new-game") MenuState(program, mainMenu, "new-game")
{ {
this->masterserverMode = masterserverMode; this->masterserverMode = masterserverMode;
if(this->masterserverMode == true) {
printf("Waiting for players to join and start a game...\n");
}
this->lastMasterServerSettingsUpdateCount = 0; this->lastMasterServerSettingsUpdateCount = 0;
this->masterserverModeMinimalResources = true; this->masterserverModeMinimalResources = true;

View File

@ -45,6 +45,7 @@ public:
StaticSound *&operator[](int i) {return sounds[i];} StaticSound *&operator[](int i) {return sounds[i];}
const Sounds &getSounds() const {return sounds;} const Sounds &getSounds() const {return sounds;}
Sounds *getSoundsPtr() {return &sounds;}
StaticSound *getRandSound() const; StaticSound *getRandSound() const;
}; };

View File

@ -40,7 +40,7 @@ namespace Glest{ namespace Game{
const int UnitPathBasic::maxBlockCount= GameConstants::updateFps / 2; const int UnitPathBasic::maxBlockCount= GameConstants::updateFps / 2;
UnitPathBasic::UnitPathBasic() { UnitPathBasic::UnitPathBasic() : UnitPathInterface() {
this->blockCount = 0; this->blockCount = 0;
this->pathQueue.clear(); this->pathQueue.clear();
this->lastPathCacheQueue.clear(); this->lastPathCacheQueue.clear();
@ -249,6 +249,7 @@ set<Unit*> Unit::livingUnitsp;
Game *Unit::game = NULL; Game *Unit::game = NULL;
Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing):id(id) { Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing):id(id) {
lastSynchDataString="";
modelFacing = CardinalDir::NORTH; modelFacing = CardinalDir::NORTH;
lastStuckFrame = 0; lastStuckFrame = 0;
lastStuckPos = Vec2i(0,0); lastStuckPos = Vec2i(0,0);

View File

@ -207,6 +207,7 @@ private:
public: public:
BroadCastSocketThread(); BroadCastSocketThread();
virtual ~BroadCastSocketThread();
virtual void execute(); virtual void execute();
virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false); virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false);
}; };

View File

@ -2288,6 +2288,10 @@ BroadCastSocketThread::BroadCastSocketThread() : BaseThread() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
} }
BroadCastSocketThread::~BroadCastSocketThread() {
}
bool BroadCastSocketThread::canShutdown(bool deleteSelfIfShutdownDelayed) { bool BroadCastSocketThread::canShutdown(bool deleteSelfIfShutdownDelayed) {
bool ret = (getExecutingTask() == false); bool ret = (getExecutingTask() == false);
if(ret == false && deleteSelfIfShutdownDelayed == true) { if(ret == false && deleteSelfIfShutdownDelayed == true) {