- 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__);
this->masterserverMode = masterserverMode;
if(this->masterserverMode == true) {
printf("Starting a new game...\n");
}
this->program = program;
Unit::setGame(this);
gameStarted = false;
@ -930,6 +935,10 @@ void Game::init(bool initForPreviewOnly)
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::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"==== START GAME ====\n");
}

View File

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

View File

@ -5108,104 +5108,109 @@ void Renderer::renderShadowsToTexture(const int renderFps){
// ==================== gl wrap ====================
string Renderer::getGlInfo(){
string infoStr;
string infoStr="";
Lang &lang= Lang::getInstance();
infoStr+= lang.get("OpenGlInfo")+":\n";
infoStr+= " "+lang.get("OpenGlVersion")+": ";
infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n";
infoStr+= " "+lang.get("OpenGlRenderer")+": ";
infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n";
infoStr+= " "+lang.get("OpenGlVendor")+": ";
infoStr+= string((getGlVendor() != NULL ? getGlVendor() : "?"))+"\n";
infoStr+= " "+lang.get("OpenGlMaxLights")+": ";
infoStr+= intToStr(getGlMaxLights())+"\n";
infoStr+= " "+lang.get("OpenGlMaxTextureSize")+": ";
infoStr+= intToStr(getGlMaxTextureSize())+"\n";
infoStr+= " "+lang.get("OpenGlMaxTextureUnits")+": ";
infoStr+= intToStr(getGlMaxTextureUnits())+"\n";
infoStr+= " "+lang.get("OpenGlModelviewStack")+": ";
infoStr+= intToStr(getGlModelviewMatrixStackDepth())+"\n";
infoStr+= " "+lang.get("OpenGlProjectionStack")+": ";
infoStr+= intToStr(getGlProjectionMatrixStackDepth())+"\n";
if(this->masterserverMode == false) {
infoStr+= lang.get("OpenGlInfo")+":\n";
infoStr+= " "+lang.get("OpenGlVersion")+": ";
infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n";
infoStr+= " "+lang.get("OpenGlRenderer")+": ";
infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n";
infoStr+= " "+lang.get("OpenGlVendor")+": ";
infoStr+= string((getGlVendor() != NULL ? getGlVendor() : "?"))+"\n";
infoStr+= " "+lang.get("OpenGlMaxLights")+": ";
infoStr+= intToStr(getGlMaxLights())+"\n";
infoStr+= " "+lang.get("OpenGlMaxTextureSize")+": ";
infoStr+= intToStr(getGlMaxTextureSize())+"\n";
infoStr+= " "+lang.get("OpenGlMaxTextureUnits")+": ";
infoStr+= intToStr(getGlMaxTextureUnits())+"\n";
infoStr+= " "+lang.get("OpenGlModelviewStack")+": ";
infoStr+= intToStr(getGlModelviewMatrixStackDepth())+"\n";
infoStr+= " "+lang.get("OpenGlProjectionStack")+": ";
infoStr+= intToStr(getGlProjectionMatrixStackDepth())+"\n";
}
return infoStr;
}
string Renderer::getGlMoreInfo(){
string infoStr;
string infoStr="";
Lang &lang= Lang::getInstance();
//gl extensions
infoStr+= lang.get("OpenGlExtensions")+":\n ";
if(this->masterserverMode == false) {
//gl extensions
infoStr+= lang.get("OpenGlExtensions")+":\n ";
string extensions= getGlExtensions();
int charCount= 0;
for(int i=0; i<extensions.size(); ++i){
infoStr+= extensions[i];
if(charCount>120 && extensions[i]==' '){
infoStr+= "\n ";
charCount= 0;
string extensions= getGlExtensions();
int charCount= 0;
for(int i=0; i<extensions.size(); ++i){
infoStr+= extensions[i];
if(charCount>120 && extensions[i]==' '){
infoStr+= "\n ";
charCount= 0;
}
++charCount;
}
++charCount;
}
//platform extensions
infoStr+= "\n\n";
infoStr+= lang.get("OpenGlPlatformExtensions")+":\n ";
//platform extensions
infoStr+= "\n\n";
infoStr+= lang.get("OpenGlPlatformExtensions")+":\n ";
charCount= 0;
string platformExtensions= getGlPlatformExtensions();
for(int i=0; i<platformExtensions.size(); ++i){
infoStr+= platformExtensions[i];
if(charCount>120 && platformExtensions[i]==' '){
infoStr+= "\n ";
charCount= 0;
charCount= 0;
string platformExtensions= getGlPlatformExtensions();
for(int i=0; i<platformExtensions.size(); ++i){
infoStr+= platformExtensions[i];
if(charCount>120 && platformExtensions[i]==' '){
infoStr+= "\n ";
charCount= 0;
}
++charCount;
}
++charCount;
}
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 atiCard= toLower(getGlVendor()).find("ati")!=string::npos;
//bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow") && isGlExtensionSupported("GL_ARB_shadow_ambient");
bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow");
bool nvidiaCard= toLower(getGlVendor()).find("nvidia")!=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");
//3D textures
config.setBool("Textures3D", isGlExtensionSupported("GL_EXT_texture3D"));
//3D textures
config.setBool("Textures3D", isGlExtensionSupported("GL_EXT_texture3D"));
//shadows
string shadows;
if(getGlMaxTextureUnits()>=3){
if(nvidiaCard && shadowExtensions){
shadows= shadowsToStr(sShadowMapping);
//shadows
string shadows="";
if(getGlMaxTextureUnits()>=3){
if(nvidiaCard && shadowExtensions){
shadows= shadowsToStr(sShadowMapping);
}
else{
shadows= shadowsToStr(sProjected);
}
}
else{
shadows= shadowsToStr(sProjected);
shadows=shadowsToStr(sDisabled);
}
}
else{
shadows=shadowsToStr(sDisabled);
}
config.setString("Shadows", shadows);
config.setString("Shadows", shadows);
//lights
config.setInt("MaxLights", atiCard? 1: 4);
//lights
config.setInt("MaxLights", atiCard? 1: 4);
//filter
config.setString("Filter", "Bilinear");
//filter
config.setString("Filter", "Bilinear");
}
}
void Renderer::clearBuffers(){
void Renderer::clearBuffers() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void Renderer::clearZBuffer(){
void Renderer::clearZBuffer() {
glClear(GL_DEPTH_BUFFER_BIT);
}

View File

@ -64,6 +64,8 @@
#include "leak_dumper.h"
#ifndef WIN32
#include <poll.h>
#define stricmp strcasecmp
#define strnicmp strncasecmp
#define _strnicmp strncasecmp
@ -623,7 +625,7 @@ void handleSIGSEGV(int sig) {
// class MainWindow
// =====================================================
MainWindow::MainWindow(Program *program){
MainWindow::MainWindow(Program *program) : WindowGl() {
this->program= program;
}
@ -3450,8 +3452,47 @@ int glestMain(int argc, char** argv) {
//printf("[%s]",test.c_str());
//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
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();
// Because OpenGL really doesn't do multi-threading well
// 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__);
cleanupCRCThread();

View File

@ -84,11 +84,13 @@ void ProgramState::render() {
canRender();
incrementFps();
renderer.clearBuffers();
renderer.reset2d();
renderer.renderMessageBox(program->getMsgBox());
renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim);
renderer.swapBuffers();
if(renderer.isMasterserverMode() == false) {
renderer.clearBuffers();
renderer.reset2d();
renderer.renderMessageBox(program->getMsgBox());
renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim);
renderer.swapBuffers();
}
}
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 {
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 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__);
int X = 0;
int Y = 0;
SDL_GetMouseState(&X,&Y);
programState->setStartXY(X,Y);
programStateNew->setStartXY(X,Y);
Logger::getInstance().setProgress(0);
Logger::getInstance().setState("");
@ -447,7 +449,7 @@ void Program::setState(ProgramState *programState, bool cleanupOldState)
}
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__);
delete this->programState;
@ -471,13 +473,13 @@ void Program::setState(ProgramState *programState, bool cleanupOldState)
updateTimer.init(GameConstants::updateFps, maxTimes);
updateCameraTimer.init(GameConstants::cameraFps, maxTimes);
this->programState= programState;
assert(programState != NULL);
programState->load();
this->programState= programStateNew;
assert(programStateNew != NULL);
programStateNew->load();
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__);
@ -492,7 +494,7 @@ void Program::setState(ProgramState *programState, bool cleanupOldState)
}
sleep(0);
if(dynamic_cast<Intro *>(programState) != NULL && msgBoxEnabled == true) {
if(dynamic_cast<Intro *>(programStateNew) != NULL && msgBoxEnabled == true) {
showCursor(true);
}
}

View File

@ -173,7 +173,7 @@ public:
bool isMessageShowing();
//misc
void setState(ProgramState *programState,bool cleanupOldState=true);
void setState(ProgramState *programStateNew,bool cleanupOldState=true);
ProgramState * getState() { return programState;}
WindowGl * getWindow() { return window; }
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")
{
this->masterserverMode = masterserverMode;
if(this->masterserverMode == true) {
printf("Waiting for players to join and start a game...\n");
}
this->lastMasterServerSettingsUpdateCount = 0;
this->masterserverModeMinimalResources = true;

View File

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

View File

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

View File

@ -207,6 +207,7 @@ private:
public:
BroadCastSocketThread();
virtual ~BroadCastSocketThread();
virtual void execute();
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__);
}
BroadCastSocketThread::~BroadCastSocketThread() {
}
bool BroadCastSocketThread::canShutdown(bool deleteSelfIfShutdownDelayed) {
bool ret = (getExecutingTask() == false);
if(ret == false && deleteSelfIfShutdownDelayed == true) {