lugre_main.cpp

Go to the documentation of this file.
00001 #include "lugre_prefix.h"
00002 #include "lugre_shell.h"
00003 #include "lugre_game.h"
00004 #include "lugre_robstring.h"
00005 #include "lugre_findpath.h"
00006 #include <Ogre.h>
00007 
00008 
00009 #if LUGRE_PLATFORM == LUGRE_PLATFORM_WIN32
00010 #define WIN32_LEAN_AND_MEAN
00011 #include "windows.h"
00012 #include <io.h>
00013 #endif
00014 
00015 #include <time.h>
00016 #include <signal.h> // seems to be crossplatform
00017 #include <stdio.h>
00018 #include <fcntl.h>
00019 #include <iostream>
00020 #include <string>
00021 #include <vector>
00022 #include <stdexcept>
00023 /*
00024 #include <ctype.h>
00025 #include <iostream>
00026 #include "OgreException.h"
00027 */
00028 
00029 #include <string>
00030 
00031 #ifdef ENABLE_THREADS
00032 #include <boost/thread/thread.hpp>
00033 #endif
00034 
00035 namespace Lugre {
00036     
00037 std::string sLuaMainPath;
00038 std::string sLugreLuaPath;
00039 std::string sMainWorkingDir;
00040 std::string sCrashText;
00041     
00042 #ifdef ENABLE_THREADS
00043 boost::thread::id   gLugre_MainThreadID; // only access globals in mainthread, otherwise there will be raceconditions
00044 bool    Lugre_IsMainThread () { return gLugre_MainThreadID == boost::this_thread::get_id(); }
00045 #else
00046 bool    Lugre_IsMainThread () { return true; }
00047 #endif
00048     
00049 void    PrintExceptionTipps (std::string sDescr);
00050     
00051     
00052 bool    gbCustomWin32ConsoleOpen = false;
00053 bool    gbLugreStarted = false;
00054     
00055 void DisplayNotice          (const char* szMsg);
00056 void DisplayErrorMessage    (const char* szMsg);
00057 void MySignalHandler        (int a);
00058 void MySignalHandlerAbort   (int a);
00059 void MyCrash                (const char* szMessage);
00060 
00062 void    PrintLuaStackTrace      ();
00063 void    PrintLuaStackTrace      (const char *filename);
00064 
00065 
00066 
00067 void DisplayNotice (const char* szMsg) {
00068     printf("NOTICE : %s\n",szMsg);
00069     #ifdef WIN32
00070         // MessageBox requires user32.lib in linker settings for libraries
00071         MessageBox( NULL,szMsg, "Notice", MB_OK | MB_ICONERROR | MB_TASKMODAL);
00072     #endif
00073 }
00074 
00075 void DisplayErrorMessage (const char* szMsg) {
00076     printf("ERROR : %s\n",szMsg);
00077     #ifdef WIN32
00078         // MessageBox requires user32.lib in linker settings for libraries
00079         MessageBox( NULL,szMsg, "Error!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
00080     #endif
00081 }
00082 
00083 bool gbCrashHandlerRunning = false;
00085 void MySignalHandler        (int a) {
00086     if (gbCrashHandlerRunning) return;
00087     gbCrashHandlerRunning = true;
00088     // print on screen
00089     MyCrash("SegFault Detected");
00090 }
00092 void MySignalHandlerAbort       (int a) {
00093     if (gbCrashHandlerRunning) return;
00094     gbCrashHandlerRunning = true;
00095     // print on screen
00096     MyCrash("Abort Signal Detected");
00097 }
00098 
00099 void    MyCrash     (const char* szMessage,const char* szFile,unsigned int iLine,const char* szFunction) {
00100     MyCrash(strprintf("%s:%d: (in function %s): %s",szFile,iLine,szFunction,szMessage).c_str());
00101 }
00102 
00103 void    MyCrash     (const char* szMessage) {
00104     if (!Lugre_IsMainThread()) printf("MyCrash called from non-main-thread!\n");
00105     MyShowError(szMessage);
00106     abort();
00107 }
00108 
00109 void    MyShowError     (const char* szMessage,const char* szFile,unsigned int iLine,const char* szFunction) {
00110     MyShowError(strprintf("%s:%d: (in function %s): %s",szFile,iLine,szFunction,szMessage).c_str());
00111 }
00112 
00113 void    MyShowError     (const char* szMessage) {
00114     if (!Lugre_IsMainThread()) { printf("MyShowError called from non-mainthread! (stacktrace not possible)\n"); }
00115     PROFILE_PRINT_STACKTRACE
00116     PrintLuaStackTrace();
00117     
00118     const char *filename = "stacktrace.log";
00119     // print to file
00120     {
00121         // time
00122         struct tm *ptr;
00123         time_t tm;
00124         tm = time(NULL);
00125         ptr = localtime(&tm);
00126         FILE *f = fopen(filename,"a");
00127         if(f){
00128             fprintf(f,"\n\n:: %s\n%s\n",asctime(ptr),szMessage);
00129             fclose(f);
00130         }
00131     }
00132     PROFILE_PRINT_STACKTRACE_TOFILE(filename)
00133     PrintLuaStackTrace(filename);
00134     
00135     std::string s(szMessage);
00136     s += "\n";
00137     s += sCrashText;
00138     DisplayErrorMessage(s.c_str());
00139 }
00140 
00141 void    Lugre_SetCrashText          (const char* szCrashText) { sCrashText = szCrashText; }
00142 
00143 void    Lugre_ShowWin32Console  () {
00144     #ifdef WIN32
00145     #ifdef SET_TERM_HANDLER
00146     SET_TERM_HANDLER;
00147     #endif
00148     gbCustomWin32ConsoleOpen = true;
00149     static const WORD MAX_CONSOLE_LINES = 500;
00150     int hConHandle;
00151     long lStdHandle;
00152     CONSOLE_SCREEN_BUFFER_INFO coninfo;
00153     FILE *fp;
00154     // allocate a console for this app
00155     AllocConsole();
00156     // set the screen buffer to be big enough to let us scroll text
00157     GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
00158     coninfo.dwSize.Y = MAX_CONSOLE_LINES;
00159     SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
00160     coninfo.dwSize);
00161     // redirect unbuffered STDOUT to the console
00162     lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
00163     hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
00164     fp = _fdopen( hConHandle, "w" );
00165     *stdout = *fp;
00166     setvbuf( stdout, NULL, _IONBF, 0 );
00167     // redirect unbuffered STDIN to the console
00168     lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
00169     hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
00170     fp = _fdopen( hConHandle, "r" );
00171     *stdin = *fp;
00172     setvbuf( stdin, NULL, _IONBF, 0 );
00173     // redirect unbuffered STDERR to the console
00174     lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
00175     hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
00176     fp = _fdopen( hConHandle, "w" );
00177     *stderr = *fp;
00178     setvbuf( stderr, NULL, _IONBF, 0 );
00179     // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
00180     // point to console as well
00181     std::ios::sync_with_stdio();
00182     #endif
00183 }
00184 
00185 
00186 #ifdef WIN32
00187 #define strdup _strdup
00188 #endif
00189 
00190 char**  Lugre_ParseWinCommandLine   (int& argc) {
00191     #ifdef WIN32
00192     //generate posix like argc/argv
00193     const char* szCommandLineWithProgrammName = GetCommandLine();
00194     //printf("parsing cmdline: %s\n",GetCommandLine());
00195     std::vector<std::string> myCmdLineParams;
00196     const char* szCmdLineSep = " \t";
00197     for (const char* r=szCommandLineWithProgrammName;*r;) {
00198         int len = strcspn(r,szCmdLineSep);
00199         myCmdLineParams.push_back(std::string(r,len));
00200         r += len;
00201         r += strspn(r,szCmdLineSep);
00202     }
00203 
00204     argc = myCmdLineParams.size();
00205     char** argv = (char**)malloc(argc * sizeof(char*));
00206     for (int i=0;i<argc;++i) argv[i] = strdup(myCmdLineParams[i].c_str());
00207     //for (i=0;i<argc;++i) printf("cmdline %d = %s\n",i,argv[i]);
00208     return argv;
00209     #else
00210     argc = 0;
00211     return 0;
00212     #endif
00213 }
00214 
00215 void    PrintOgreExceptionAndTipps(Ogre::Exception& e) {
00216     printf("OgreException:\n");
00217     printf(" errorcode=%d\n",e.getNumber());
00218     printf(" source=%s\n",e.getSource().c_str());
00219     printf(" file=%s\n",e.getFile().c_str());
00220     printf(" line=%ld\n",e.getLine());
00221     printf(" descr=%s\n",e.getDescription().c_str());
00222     printf(" fulldescription=%s\n",e.getFullDescription().c_str());
00223     PrintExceptionTipps(e.getFullDescription().c_str());
00224 }
00225 
00226 
00227 std::string GetLugreLuaPath         (){
00228     return sLugreLuaPath;
00229 }
00230 std::string GetMainWorkingDir       (){
00231     return sMainWorkingDir;
00232 }
00233 
00234 void    Lugre_Run   (int argc, char* argv[]) { PROFILE
00235     #ifdef ENABLE_THREADS
00236     gLugre_MainThreadID = boost::this_thread::get_id();
00237     #endif
00238     gbLugreStarted = true;
00239 
00240     try {
00241         FindBasePaths paths;
00242 
00243         sLuaMainPath = paths.getMainLuaPath();
00244         sLugreLuaPath = paths.getLugreLuaPath();
00245         sMainWorkingDir = paths.getMainWorkingDir();
00246         
00247     }catch(...){
00248         printf("no paths found, fallback to default settings\n");
00249         sLuaMainPath = "lua/main.lua";
00250         sLugreLuaPath = "lugre/lua/";
00251         sMainWorkingDir = "./";
00252     }
00253 
00254     printf("lua main file: %s\n",sLuaMainPath.c_str());
00255     printf("lua lugre dir: %s\n",sLugreLuaPath.c_str());
00256     printf("main working dir: %s\n",sMainWorkingDir.c_str());
00257 
00258     // see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_signal.asp for details
00259     signal(SIGSEGV,MySignalHandler); // seems to be cross platform
00260     signal(SIGABRT,MySignalHandlerAbort); // cross platform ?
00261 
00262     try {
00263         cShell& shell = cShell::GetSingleton();
00264 
00265         shell.Init(argc,argv);
00266 
00267         cGame::GetSingleton().Run(argc,argv);
00268         
00269         shell.DeInit();
00270 
00271     } catch( Ogre::Exception& e ) {
00272         printf("ogre::exception\n");
00273         PrintOgreExceptionAndTipps(e);
00274         MyCrash((std::string("Ogre::exception occurred, see console\n") + e.getFullDescription()).c_str());
00275     } catch( std::exception& e ) {
00276         printf("std::exception\n");
00277         printf(" %s\n",e.what());
00278         PrintExceptionTipps(e.what());
00279         MyCrash((std::string("std::exception occurred, see console\n") + e.what()).c_str());
00280     } catch(...) {
00281         printf("unknown exception\n");
00282         MyCrash("unknown exception occurred\n");
00283     }
00284     
00285     #ifdef WIN32
00286     if (gbCustomWin32ConsoleOpen) FreeConsole();
00287     #endif
00288 }
00289 
00290 };

Generated on Wed May 23 06:00:14 2012 for cpp by  doxygen 1.5.6