console.cpp

Go to the documentation of this file.
00001 /* MAINTAINER: Bernard CURRENT_EDITOR: Bernard */
00002 
00003 // #define WANT_TRACE
00004 
00005 
00006 #include "SDL.h"
00007 #include "SDL_opengl.h"
00008 
00009 #include <sstream>
00010 #include <string>
00011 #include <iostream>
00012 #include <vector>
00013 
00014 #include "globals_client.h"
00015 #include "log.h"
00016 #include "console.h"
00017 #include "platform.h"
00018 #include "settings.h"
00019 #include "application_client.h"
00020 #include "conversions.h"
00021 #include "translator.h"
00022 
00023 #include "font_manager.h"
00024 
00025 using namespace std;
00026 
00027 const int  CONSOLE_ONOFF = SDLK_BACKQUOTE;
00028 const float CONSOLE_TOP  = 10.0f;
00029 const float CONSOLE_LEFT = 20.0f;
00030 
00031 Console::Console()
00032 {
00033         mPriority = IA_PRIORITY_CONSOLE;
00034         mActive = false;
00035         
00036         mFont = 0;
00037         mLineWrap = true;
00038 
00039         mTitle = 0; // some default value
00040         
00041         mInHistory = g_settings.getInt(SETTING_CONSOLE_LINES);
00042 
00043         // TODO: Load from settings
00044         mLogForwarding = true;
00045 
00046         mHistoryIgnore = false;
00047 }
00048 
00049 Console::~Console()
00050 {
00051         TIN
00052 }
00053 
00054 
00055 void Console::init()
00056 {
00057         TIN
00058 
00059         // registration to input manager
00060         getAppClient().getInputManager().setKeyReceiver(CONSOLE_ONOFF, this);
00061         getAppClient().getInputManager().addInputAcceptor(*this);
00062 
00063                 
00064         // Loading font
00065         mFont = FontManager::getRef().get("FreeMono.ttf", 20);
00066         if (!mFont)
00067         {
00068                 LOGE << "Loading font failed!" << endl;
00069                 DIE();
00070         }
00071         
00072         // register as log acceptor
00073         registerLog();
00074 
00075         // This is for testing :-) 
00076         mTitle = LNG_CACHE_("-- Console --");
00077 }
00078 
00079 void Console::clean()
00080 {
00081         TIN
00082 
00083         // unregister from input
00084         getAppClient().getInputManager().setKeyReceiver(CONSOLE_ONOFF, 0);
00085         getAppClient().getInputManager().removeInputAcceptor(*this);
00086 
00087         // Clean font
00088         mFont = 0; 
00089 
00090         // clean registration to log system
00091         g_log.setAcceptor(0); 
00092 
00093 
00094         LNG_UNCACHE(mTitle);
00095 }
00096 
00097 
00098 bool Console::wantKey(const SDL_keysym &keysym)
00099 {
00100         // SDLK_BACKQUOTE == ` 
00101         if (keysym.sym == CONSOLE_ONOFF) return true;
00102                 
00103         return mActive;
00104 }
00105 
00106 bool  Console::keyDown(const SDL_keysym &keysym)
00107 {
00108         TIN 
00109 
00110         if (keysym.sym == CONSOLE_ONOFF) 
00111         {
00112                 mActive = !mActive;
00113                 getAppClient().getInputManager().WantAllInput(mActive);
00114                 LOGD << " Console is " << mActive << endl;
00115                 return true;
00116         }
00117         
00118         if (!mActive) return false;
00119 
00120         LOGT << "Processing new key " << keysym.sym << " :-)\n";
00121         
00122         switch (keysym.sym) 
00123         {
00124 
00125         // process command & erase commmand line
00126         case SDLK_RETURN:
00127                 processCommand( mInputLine.getLineU() );        
00128 
00129                 mInputLine.clear();
00130                 
00131                 break;
00132         
00133         // something with history of commands - not yet
00134         case SDLK_UP:
00135                 LOGI << "History in console not implemented yet." << endl;
00136                 break;
00137         case SDLK_DOWN:
00138                 LOGI << "History in console not implemented yet." << endl;
00139                 break;  
00140         case SDLK_TAB:
00141                 LOGI << "Completion in console is not implemented." << endl;
00142                 break;  
00143 
00144         // adding one char to commandline
00145         default:
00146         
00147                 mInputLine.processKey(keysym);
00148                 
00149                 break;
00150         }
00151         
00152         return true;
00153 }
00154 
00155 void Console::logLine(const std::string &line)
00156 {
00157         if ( mLogForwarding )
00158                 addConsoleMessage(line);
00159 }
00160 
00161 
00162 void Console::registerLog()
00163 {
00164         if ( mLogForwarding )
00165         {
00166                 g_log.setAcceptor(this);
00167         }
00168         else
00169         {
00170                 g_log.setAcceptor(0);
00171         }
00172 }
00173 
00174 
00175 void Console::render()
00176 {
00177         TIN;
00178         
00179         
00180         assertL(mFont.isValid());
00181         
00182         mFont->RenderUTF8( xtos(getAppClient().getGFX().getFps()),
00183                 (float)(getAppClient().getGFX().getWidth() - 50),
00184                 (float)(getAppClient().getGFX().getHeight() - 30) );
00185 
00186         // if we don't want "slidedown/slideup" :-)
00187         if (!mActive) return;
00188 
00189         // OpenGL init
00190         getAppClient().getGFX().set2DOpenGL();
00191     glLoadIdentity();
00192         glColor3f( 1.0, 1.0, 1.0);
00193 
00194 
00195         // Decorations
00196         mFont->RenderUTF8(
00197                 LNG_GET(mTitle), 
00198                 CONSOLE_LEFT, 
00199                 getAppClient().getGFX().getHeight() - (CONSOLE_TOP + mFont->Ascent())
00200         );
00201 
00202         
00203         
00204         // History (messages) - must be locked
00205         mHistoryMutex.lock();
00206         mHistoryIgnore = true;
00207 
00208         list<string>::iterator it = mMessageHistory.begin();
00209         int i = mInHistory+1;
00210         for(; it != mMessageHistory.end(); ++it, --i)
00211         {
00212                 mFont->RenderUTF8(
00213                         *it,
00214                         CONSOLE_LEFT,
00215                         getAppClient().getGFX().getHeight() - (CONSOLE_TOP + i*mFont->Ascent())
00216                 );
00217         }       
00218 
00219         mHistoryIgnore = false;
00220         mHistoryMutex.unlock();
00221         
00222         // commandline
00223         mFont->RenderUTF8( 
00224                 mInputLine.getLineURender(),
00225                 CONSOLE_LEFT,
00226                 getAppClient().getGFX().getHeight() - (CONSOLE_TOP + (mInHistory+2)*mFont->Ascent())
00227         );
00228 
00229 }
00230 
00231 void Console::addConsoleMessage(const std::string &msg)
00232 {
00233         // DON'T DO ANY LOGGING HERE SICE THIS MAY BE CALLED FROM
00234         // LOG AND THUS IT WOULD DO INFINITE LOOP
00235         
00236         mHistoryMutex.lock();
00237         if (!mHistoryIgnore) 
00238         {
00239                 // Add message to history
00240                 // Line wrapping - the text if first translated to wide chars - we
00241                 // want proper multibyte chars wrapping. Then one by one chars are
00242                 // taken from src (original message) to temporary "line". 
00243                 if (mFont && mLineWrap)
00244                 {
00245                         // maximal width of text in console
00246                         int maxW = getAppClient().getGFX().getWidth()-2*(int)CONSOLE_LEFT-mFont->getWwidth();
00247                 
00248                         wstring src, dst;
00249                         utf8tows(msg.c_str(), src);
00250                         
00251                         while (!src.empty())
00252                         {
00253                                 wchar_t w;
00254                                 
00255                                 w = src[0];
00256                                 src.erase(0,1);
00257                                 dst += w;
00258                                 
00259                                 string dst_utf;
00260                                 wstoutf8(dst, dst_utf);
00261                                 
00262                                 if (mFont->getTextWidth(dst_utf) >= maxW)
00263                                 {
00264                                         mMessageHistory.push_front(dst_utf);
00265                                         dst.erase(0);
00266                                 }
00267                                 
00268                         }
00269                         
00270                         if (!dst.empty())
00271                         {
00272                                 string dst_utf;
00273                                 wstoutf8(dst, dst_utf);
00274                                 mMessageHistory.push_front(dst_utf);
00275                         }
00276                         
00277                 }
00278                 else
00279                 {
00280                         mMessageHistory.push_front(msg);
00281                 }
00282         
00283                 
00284                 // Remove old messages from history
00285                 while ((signed int)mMessageHistory.size() > mInHistory)
00286                 {
00287                         mMessageHistory.pop_back();
00288                 }
00289         }
00290 
00291         mHistoryMutex.unlock();
00292 }
00293 
00294 
00295 void Console::processCommand(const std::string &cmd)
00296 {
00297         TIN
00298         
00299         LOGD << "Console command: " << cmd << endl;
00300 
00301         addConsoleMessage(cmd);
00302         
00303         getAppClient().getCommander().addCommand(cmd);  
00304 }

Generated on Wed Apr 12 13:55:27 2006 for bjs by  doxygen 1.4.5