Console.h

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 1997-2001 Id Software, Inc.
00003 Copyright (C) 2002 Ryan Nunn and The Pentagram Team
00004 
00005 This program is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00013 
00014 See the GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with this program; if not, write to the Free Software
00018 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 
00020 */
00021 
00022 #ifndef CONSOLE_H
00023 #define CONSOLE_H
00024 
00025 #include "istring.h"
00026 #include <map>
00027 #include <vector>
00028 #include <cstdarg>
00029 
00030 //
00031 // The Console
00032 //
00033 #define         CON_TEXTSIZE            32768
00034 #define         CON_PUTCHAR_SIZE        256
00035 #define         CON_NUM_TIMES           4
00036 
00037 // For Enable/Disable flags
00038 #define         CON_STDOUT                      0x01
00039 #define         CON_STDERR                      0x02
00040 
00041 class ODataSource;
00042 class RenderSurface;
00043 struct FixedWidthFont;
00044 
00045 enum MsgMask {
00046         /* Output no message(s). For obvious reasons this probably should never need to be used... */
00047         MM_NONE=0x00,
00048         /* general informative messages like the `virtual path "@home"...` stuff.
00049                 non-critical and in the general case non-useful unless trying to debug a problem. */
00050         MM_INFO=0x01,
00051         /* similar in urgency to a general message, except it's just noting a possible, though
00052                 unlikely problem. The:
00053                 `Error mounting virtual path "@data": directory not found: /usr/local/share/pentagram`
00054                 message would be a good example of this, I believe. */
00055         MM_MINOR_WARN=0x02,
00056         /* The compatriot to MINOR_WARN, this one effectively says "there's likely a problem here" */
00057         MM_MAJOR_WARN=0x04,
00058         /* "We had a problem, and we're trying to recover from it, hopefully successfully." */
00059         MM_MINOR_ERR=0x08,
00060         /* A message noting that we encountered a significant problem and that we're going to
00061                 (hopefully!) gracefully terminate the engine... Probably though a call to
00062                 CoreApp::application->ForceQuit();
00063                 "We had a rather significant problem. Shutting down pentagram now..."
00064                 */
00065         MM_MAJOR_ERR=0x10,
00066         /* Significant failures that simply can't be recovered from, since there's either no way to
00067                 recover, or it's likely we'll crash in the final execution of the main loop before everything
00068                 shuts down.
00069                 Effectively things you'll want to be calling `exit(-1);` on, immediately after issuing the
00070                 warning. *grin* */
00071         MM_TERMINAL_ERR=0x20,
00072         /* Displays no matter what the warning level. Only really useful to setup the relevant internal masks. */
00073         MM_ALL=0x3F
00074         /* TODO:
00075                 Thoughts:
00076                 * Maybe there should be a MM_UNINPORTANT for MM_INFO messages that, whilst
00077                         potentially useful, are useful in very, very rare circumstances...
00078                         Would be turned on by a -v flag or something.
00079                 * This is probably too detailed already though.
00080         */
00081 };
00082 
00083 class Console
00084 {
00085         char            text[CON_TEXTSIZE];
00086         sint32          current;                                // line where next message will be printed
00087         sint32          x;                                              // offset in current line for next print
00088         sint32          display;                                // bottom of console displays this line
00089 
00090         sint32          linewidth;                              // characters across screen
00091         sint32          totallines;                             // total lines in console scrollback
00092 
00093         sint32          vislines;
00094 
00095         bool            wordwrap;                               // Enable/Disable word wrapping
00096         bool            cr;                                             // Line feed marker
00097 
00098         sint32          putchar_count;                  // Number of characters that have been putchar'd
00099         char            putchar_buf[CON_PUTCHAR_SIZE];  // The Characters that have been putchar'd
00100 
00101         uint32          std_output_enabled;             
00102 
00103         // stdout and stderr redirection
00104         ODataSource     *stdout_redir;
00105         ODataSource     *stderr_redir;
00106 
00107         // Confont 
00108         FixedWidthFont          *confont;
00109 
00110         void            (*auto_paint)(void);
00111 
00112         MsgMask         msgMask;                                // mask to determine which messages are printed or not
00113 
00114         // Overlay timing
00115         uint32          framenum;
00116         uint32          times[CON_NUM_TIMES];   // framenum the line was generated
00117                                                                                 // for transparent notify lines
00118 public:
00119         enum SpecialChars
00120         {
00121                 Tab                     = '\t',
00122                 Backspace       = '\b',
00123                 Enter           = '\n'
00124         };
00125 
00126 
00127         Console();
00128         ~Console();
00129 
00130         // Clear the buffer
00131         void    Clear();
00132 
00133         // Dump the buffer to a text file
00134         void    Dump (const char *name);
00135 
00136         // Resize the console buffer (on screen change)
00137         void    CheckResize (int scrwidth);
00138 
00139         // Draw the Console
00140         void    DrawConsole (RenderSurface *surf, int height);
00141 
00142         // Draw the Console Notify Overlay
00143         void    DrawConsoleNotify (RenderSurface *surf);
00144 
00145         // Set the console font texture
00146         void    SetConFont(FixedWidthFont *cf) { confont = cf; }
00147 
00148         // Get the console font texture
00149         FixedWidthFont *GetConFont() { return confont; }
00150 
00151         // Autopaint will cause the GUIApp to re-paint everything after a linefeed
00152         void    SetAutoPaint(void (*func)(void)) { auto_paint = func; }
00153 
00154         // Scroll through the console. - is up + is down
00155         void    ScrollConsole(sint32 lines);
00156 
00157         // Redirection
00158         void    RedirectOutputStream(uint32 mask, ODataSource *ds)
00159         {
00160                 if (mask & CON_STDOUT) stdout_redir = ds;
00161                 if (mask & CON_STDERR) stderr_redir = ds;
00162         }
00163 
00164         // Enabling output
00165         void    setOutputEnabled(uint32 mask)
00166         {
00167                 std_output_enabled |= mask;
00168         }
00169 
00170         // Disabling output
00171         void    unsetOutputEnabled(uint32 mask)
00172         {
00173                 std_output_enabled &= ~mask;
00174         }
00175         
00176         // Enabling output
00177         uint32  getOutputEnabled()
00178         {
00179                 return std_output_enabled;
00180         }
00181 
00182         // sets what message types to ignore
00183         void setMsgMask(const MsgMask mm)
00184         {
00185                 msgMask = mm;
00186         }
00187         
00188         void setFrameNum(uint32 f) 
00189         {
00190                 framenum = f;
00191         }
00192 
00193         //
00194         // STDOUT Methods
00195         //
00196 
00197         // Print a text string to the console, and output to stdout
00198         void    Print(const char *txt);
00199         void    Print(const MsgMask mm, const char *txt);
00200 
00201         // printf, and output to stdout
00202         sint32  Printf(const char *fmt, ...);
00203         sint32  Printf(const MsgMask mm, const char *fmt, ...); // with msg filtering
00204         
00205         // printf, and output to stdout (va_list)
00206         int             vPrintf (const char *fmt, va_list);
00207 
00208         // putchar, and output to stdout
00209         void    Putchar (int c);
00210 
00211         // Print a text string to the console, and output to stdout
00212         void    PrintRaw (const char *txt, int n);
00213 
00214 
00215         //
00216         // STDERR Methods
00217         //
00218 
00219         // Print a text string to the console, and output to stderr
00220         void    Print_err(const char *txt);
00221         void    Print_err(const MsgMask mm, const char *txt);
00222 
00223         // printf, and output to stderr
00224         sint32  Printf_err(const char *fmt, ...);
00225         sint32  Printf_err(const MsgMask mm, const char *fmt, ...);
00226 
00227         // printf, and output to stderr (va_list)
00228         int             vPrintf_err (const char *fmt, va_list);
00229 
00230         // putchar, and output to stderr
00231         void    Putchar_err (int c);
00232 
00233         // Print a text string to the console, and output to stderr
00234         void    PrintRaw_err (const char *txt, int n);
00235 
00236 
00237         // Enable/Disable word wrapping
00238         void    EnableWordWrap() { wordwrap = true; }
00239         void    DisableWordWrap() { wordwrap = false; }
00240 
00241         //
00242         // Console Commands
00243         //
00244 
00245         typedef Pentagram::istring ArgsType;
00246         typedef std::vector<ArgsType> ArgvType;
00247         typedef void (*Function)(const ArgvType &argv);
00248 
00252         void                    AddConsoleCommand(const ArgsType &command, Console::Function function);
00253 
00256         void                    RemoveConsoleCommand(Console::Function function);
00257 
00260         void                    ExecuteConsoleCommand(const Console::ArgsType &args);
00261 
00264         void                    ExecuteConsoleCommand(const Console::ArgvType &argv);
00265 
00267         void                    ExecuteCommandBuffer();
00268 
00271         void                    ScrollCommandHistory(int num);
00272 
00274         void                    ClearCommandBuffer();
00275 
00281         void                    AddCharacterToCommandBuffer(int ch);
00282 
00285         void                    DeleteCommandBufferChars(int num);
00286 
00289         void                    MoveCommandCursor(int num);
00290 
00292         void                    ToggleCommandInsert() { commandInsert = !commandInsert; }
00293 
00295         static void             ConCmd_CmdList(const Console::ArgvType &argv);
00296 
00298         static void             ConCmd_CmdHistory(const Console::ArgvType &argv);
00299 
00300 private:
00301 
00302         // Print a text string to the console
00303         void    PrintInternal (const char *txt);
00304 
00305         // Print a text string to the console
00306         void    PrintRawInternal (const char *txt, int n);
00307 
00308         // Put char
00309         void    PutcharInternal (int c);
00310 
00311         // Add a linefeed to the buffer
00312         void    Linefeed ();
00313 
00314         // Print the Putchar data, if possible
00315         void    PrintPutchar();
00316 
00317         // Console Commands
00318         ArgsType                                        commandBuffer;
00319         int                                                     commandCursorPos;
00320         bool                                            commandInsert;
00321         std::vector<ArgsType>           commandHistory;
00322         int                                                     commandHistoryPos;
00323         std::map<ArgsType,Function>     ConsoleCommands;
00324 
00325 };
00326 
00327 // Console object
00328 extern  Console         con;
00329 
00330 //
00331 // Console Ouput Streams
00332 //
00333 
00334 #include <ostream>
00335 
00336 //
00337 // Standard Output Streambuf
00338 //
00339 template<class _E, class _Tr = std::char_traits<_E> >
00340 class console_streambuf : public std::basic_streambuf<_E, _Tr>
00341 {
00342 public:
00343         console_streambuf() : std::basic_streambuf<_E, _Tr>() { }
00344         virtual ~console_streambuf() { }
00345         typedef typename _Tr::int_type int_type;
00346         typedef typename _Tr::char_type char_type;
00347 
00348 protected:
00349 
00350         // Output a character
00351         virtual int_type overflow(int_type c = _Tr::eof())
00352         {
00353                 if (!_Tr::eq_int_type(_Tr::eof(), c)) con.Putchar(_Tr::to_char_type(c));
00354                 return (_Tr::not_eof(c));
00355         }
00356 
00357         // Flush
00358         virtual int sync()
00359         {
00360                 return 0;
00361         }
00362 };
00363 
00364 //
00365 // Standard Output Stream
00366 //
00367 template<class _E, class _Tr = std::char_traits<_E> >
00368 class console_ostream : public std::basic_ostream<_E, _Tr>
00369 {
00370 //#ifndef SAFE_CONSOLE_STREAMS
00371         console_streambuf<_E, _Tr> _Fb;
00372 //#endif
00373 
00374 public: 
00375         console_ostream() : std::basic_ostream<_E, _Tr>(&_Fb), _Fb() {}
00376         console_ostream(console_streambuf<_E, _Tr> *Fb) : std::basic_ostream<_E, _Tr>(Fb) {}
00377         virtual ~console_ostream() { }
00378 
00379 #if defined(MACOSX) && defined(__GNUC__)
00380         // Work around a bug in Apple GCC 3.x which incorrectly tries to inline this method
00381         int __attribute__ ((noinline)) printf (const char *fmt, ...)
00382 #else
00383         int printf (const char *fmt, ...)
00384 #endif
00385         {
00386                 va_list argptr;
00387                 va_start (argptr,fmt);
00388                 int ret = con.vPrintf(fmt, argptr);
00389                 va_end (argptr);
00390                 return ret;
00391         }
00392 };
00393 
00394 //
00395 // Standard Output Stream Object
00396 //
00397 #ifndef SAFE_CONSOLE_STREAMS
00398 extern console_ostream<char>            pout;
00399 extern console_ostream<char>            *ppout;
00400 #else
00401 #define pout (*ppout)
00402 extern console_ostream<char>            *ppout;
00403 #endif
00404 
00405 //
00406 // Error Output Streambuf
00407 //
00408 template<class _E, class _Tr = std::char_traits<_E> >
00409 class console_err_streambuf : public std::basic_streambuf<_E, _Tr>
00410 {
00411 public:
00412         console_err_streambuf() : std::basic_streambuf<_E, _Tr>() { }
00413         virtual ~console_err_streambuf() { }
00414         typedef typename _Tr::int_type int_type;
00415         typedef typename _Tr::char_type char_type;
00416 
00417 protected:
00418 
00419         // Output a character
00420         virtual int_type overflow(int_type c = _Tr::eof())
00421         {
00422                 if (!_Tr::eq_int_type(_Tr::eof(), c)) con.Putchar_err(_Tr::to_char_type(c));
00423                 return (_Tr::not_eof(c));
00424         }
00425 
00426         // Flush
00427         virtual int sync()
00428         {
00429                 return 0;
00430         }
00431 };
00432 
00433 //
00434 // Error Output Stream
00435 //
00436 template<class _E, class _Tr = std::char_traits<_E> >
00437 class console_err_ostream : public std::basic_ostream<_E, _Tr>
00438 {
00439 //#ifndef SAFE_CONSOLE_STREAMS
00440         console_err_streambuf<_E, _Tr> _Fb;
00441 //#endif
00442 
00443 public: 
00444         console_err_ostream() : std::basic_ostream<_E, _Tr>(&_Fb), _Fb() {}
00445         console_err_ostream(console_err_streambuf<_E, _Tr> *Fb) : std::basic_ostream<_E, _Tr>(Fb) {}
00446         virtual ~console_err_ostream() { }
00447 
00448 #if defined(MACOSX) && defined(__GNUC__)
00449         // Work around a bug in Apple GCC 3.x which incorrectly tries to inline this method
00450         int __attribute__ ((noinline)) printf (const char *fmt, ...)
00451 #else
00452         int printf (const char *fmt, ...)
00453 #endif
00454         {
00455                 va_list argptr;
00456                 va_start (argptr,fmt);
00457                 int ret = con.vPrintf_err(fmt, argptr);
00458                 va_end (argptr);
00459                 return ret;
00460         }
00461 
00462 };
00463 
00464 //
00465 // Error Output Stream Object
00466 //
00467 #ifndef SAFE_CONSOLE_STREAMS
00468 extern console_err_ostream<char>        perr;
00469 extern console_err_ostream<char>        *pperr;
00470 #else
00471 #define perr (*pperr)
00472 extern console_err_ostream<char>        *pperr;
00473 #endif
00474 
00475 #endif // CONSOLE_H

Generated on Fri Jul 27 22:27:11 2007 for pentagram by  doxygen 1.4.7