- 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,104 +5108,109 @@ 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();
infoStr+= lang.get("OpenGlInfo")+":\n"; if(this->masterserverMode == false) {
infoStr+= " "+lang.get("OpenGlVersion")+": "; infoStr+= lang.get("OpenGlInfo")+":\n";
infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n"; infoStr+= " "+lang.get("OpenGlVersion")+": ";
infoStr+= " "+lang.get("OpenGlRenderer")+": "; infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n";
infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n"; infoStr+= " "+lang.get("OpenGlRenderer")+": ";
infoStr+= " "+lang.get("OpenGlVendor")+": "; infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n";
infoStr+= string((getGlVendor() != NULL ? getGlVendor() : "?"))+"\n"; infoStr+= " "+lang.get("OpenGlVendor")+": ";
infoStr+= " "+lang.get("OpenGlMaxLights")+": "; infoStr+= string((getGlVendor() != NULL ? getGlVendor() : "?"))+"\n";
infoStr+= intToStr(getGlMaxLights())+"\n"; infoStr+= " "+lang.get("OpenGlMaxLights")+": ";
infoStr+= " "+lang.get("OpenGlMaxTextureSize")+": "; infoStr+= intToStr(getGlMaxLights())+"\n";
infoStr+= intToStr(getGlMaxTextureSize())+"\n"; infoStr+= " "+lang.get("OpenGlMaxTextureSize")+": ";
infoStr+= " "+lang.get("OpenGlMaxTextureUnits")+": "; infoStr+= intToStr(getGlMaxTextureSize())+"\n";
infoStr+= intToStr(getGlMaxTextureUnits())+"\n"; infoStr+= " "+lang.get("OpenGlMaxTextureUnits")+": ";
infoStr+= " "+lang.get("OpenGlModelviewStack")+": "; infoStr+= intToStr(getGlMaxTextureUnits())+"\n";
infoStr+= intToStr(getGlModelviewMatrixStackDepth())+"\n"; infoStr+= " "+lang.get("OpenGlModelviewStack")+": ";
infoStr+= " "+lang.get("OpenGlProjectionStack")+": "; infoStr+= intToStr(getGlModelviewMatrixStackDepth())+"\n";
infoStr+= intToStr(getGlProjectionMatrixStackDepth())+"\n"; infoStr+= " "+lang.get("OpenGlProjectionStack")+": ";
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();
//gl extensions if(this->masterserverMode == false) {
infoStr+= lang.get("OpenGlExtensions")+":\n "; //gl extensions
infoStr+= lang.get("OpenGlExtensions")+":\n ";
string extensions= getGlExtensions(); string extensions= getGlExtensions();
int charCount= 0; int charCount= 0;
for(int i=0; i<extensions.size(); ++i){ for(int i=0; i<extensions.size(); ++i){
infoStr+= extensions[i]; infoStr+= extensions[i];
if(charCount>120 && extensions[i]==' '){ if(charCount>120 && extensions[i]==' '){
infoStr+= "\n "; infoStr+= "\n ";
charCount= 0; charCount= 0;
}
++charCount;
} }
++charCount;
}
//platform extensions //platform extensions
infoStr+= "\n\n"; infoStr+= "\n\n";
infoStr+= lang.get("OpenGlPlatformExtensions")+":\n "; infoStr+= lang.get("OpenGlPlatformExtensions")+":\n ";
charCount= 0; charCount= 0;
string platformExtensions= getGlPlatformExtensions(); string platformExtensions= getGlPlatformExtensions();
for(int i=0; i<platformExtensions.size(); ++i){ for(int i=0; i<platformExtensions.size(); ++i){
infoStr+= platformExtensions[i]; infoStr+= platformExtensions[i];
if(charCount>120 && platformExtensions[i]==' '){ if(charCount>120 && platformExtensions[i]==' '){
infoStr+= "\n "; infoStr+= "\n ";
charCount= 0; charCount= 0;
}
++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"); bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow");
bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow");
//3D textures //3D textures
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);
}
else{
shadows= shadowsToStr(sProjected);
}
} }
else{ else{
shadows= shadowsToStr(sProjected); shadows=shadowsToStr(sDisabled);
} }
} config.setString("Shadows", shadows);
else{
shadows=shadowsToStr(sDisabled);
}
config.setString("Shadows", shadows);
//lights //lights
config.setInt("MaxLights", atiCard? 1: 4); config.setInt("MaxLights", atiCard? 1: 4);
//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();
renderer.clearBuffers(); if(renderer.isMasterserverMode() == false) {
renderer.reset2d(); renderer.clearBuffers();
renderer.renderMessageBox(program->getMsgBox()); renderer.reset2d();
renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim); renderer.renderMessageBox(program->getMsgBox());
renderer.swapBuffers(); renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim);
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) {