[Orxonox-commit 1459] r6177 - in code/branches/presentation2/src/libraries/core: . input

rgrieder at orxonox.net rgrieder at orxonox.net
Sun Nov 29 14:47:54 CET 2009


Author: rgrieder
Date: 2009-11-29 14:47:54 +0100 (Sun, 29 Nov 2009)
New Revision: 6177

Modified:
   code/branches/presentation2/src/libraries/core/IOConsole.cc
   code/branches/presentation2/src/libraries/core/IOConsole.h
   code/branches/presentation2/src/libraries/core/input/InputBuffer.cc
   code/branches/presentation2/src/libraries/core/input/InputBuffer.h
Log:
Performance and robustness improvements for the IOConsole under Windows.
There should only be one way to screw the console now: Change the console properties manually at runtime (right click on the taskbar icon), esp. screen buffer size.
If you can find another bug, please let me know.

Modified: code/branches/presentation2/src/libraries/core/IOConsole.cc
===================================================================
--- code/branches/presentation2/src/libraries/core/IOConsole.cc	2009-11-29 12:36:12 UTC (rev 6176)
+++ code/branches/presentation2/src/libraries/core/IOConsole.cc	2009-11-29 13:47:54 UTC (rev 6177)
@@ -32,6 +32,7 @@
 #include <iomanip>
 #include <iostream>
 
+#include "util/Clock.h"
 #include "util/Math.h"
 #include "core/Game.h"
 #include "core/input/InputBuffer.h"
@@ -60,13 +61,6 @@
         return 0;
     }
 
-    inline bool IOConsole::willPrintStatusLines()
-    {
-        return !this->statusLineWidths_.empty()
-             && this->terminalWidth_  >= this->statusLineMaxWidth_
-             && this->terminalHeight_ >= (this->minOutputLines_ + this->statusLineWidths_.size());
-    }
-
     // ###############################
     // ###  ShellListener methods  ###
     // ###############################
@@ -79,20 +73,6 @@
         // is already in std::cout when we start the IOConsole
     }
 
-    //! Called if the text in the input-line has changed
-    void IOConsole::inputChanged()
-    {
-        this->printInputLine();
-        this->cout_.flush();
-    }
-
-    //! Called if the position of the cursor in the input-line has changed
-    void IOConsole::cursorChanged()
-    {
-        this->printInputLine();
-        this->cout_.flush();
-    }
-
     //! Called if a command is about to be executed
     void IOConsole::executed()
     {
@@ -130,8 +110,8 @@
         : shell_(new Shell("IOConsole", false, true))
         , buffer_(shell_->getInputBuffer())
         , cout_(std::cout.rdbuf())
+        , promptString_("orxonox # ")
         , bStatusPrinted_(false)
-        , promptString_("orxonox # ")
         , originalTerminalSettings_(0)
     {
         this->setTerminalMode();
@@ -303,7 +283,7 @@
         }
     }
 
-    void IOConsole::printLogText(const std::string& text)
+    void IOConsole::printOutputLine(const std::string& text)
     {
         std::string output = text;
         /*int level =*/ this->extractLogLevel(&output);
@@ -418,6 +398,13 @@
         this->terminalHeight_ = 24;
     }
 
+    inline bool IOConsole::willPrintStatusLines()
+    {
+        return !this->statusLineWidths_.empty()
+             && this->terminalWidth_  >= this->statusLineMaxWidth_
+             && this->terminalHeight_ >= (this->minOutputLines_ + this->statusLineWidths_.size());
+    }
+
     // ###############################
     // ###  ShellListener methods  ###
     // ###############################
@@ -430,7 +417,7 @@
         // Erase the line
         this->cout_ << "\033[K";
         // Reprint the last output line
-        this->printLogText(*(this->shell_->getNewestLineIterator()));
+        this->printOutputLine(*(this->shell_->getNewestLineIterator()));
         // Restore cursor
         this->cout_ << "\033[u";
         this->cout_.flush();
@@ -448,7 +435,7 @@
         this->cout_ << "\033[J";
         // Print the new output lines
         for (int i = 0; i < newLines; ++i)
-            this->printLogText(this->shell_->getNewestLineIterator()->substr(i*this->terminalWidth_, this->terminalWidth_));
+            this->printOutputLine(this->shell_->getNewestLineIterator()->substr(i*this->terminalWidth_, this->terminalWidth_));
         // Move cursor down
         this->cout_ << "\033[1B\033[1G";
         // Print status and input lines
@@ -456,6 +443,20 @@
         this->printStatusLines();
         this->cout_.flush();
     }
+
+    //! Called if the text in the input-line has changed
+    void IOConsole::inputChanged()
+    {
+        this->printInputLine();
+        this->cout_.flush();
+    }
+
+    //! Called if the position of the cursor in the input-line has changed
+    void IOConsole::cursorChanged()
+    {
+        this->printInputLine();
+        this->cout_.flush();
+    }
 }
 
 #elif defined(ORXONOX_PLATFORM_WINDOWS)
@@ -471,46 +472,71 @@
         : shell_(new Shell("IOConsole", false, true))
         , buffer_(shell_->getInputBuffer())
         , cout_(std::cout.rdbuf())
-        , bStatusPrinted_(false)
         , promptString_("orxonox # ")
+        , statusLines_(1)
+        , inputLineHeight_(1)
+        , lastOutputLineHeight_(1)
     {
-        this->setTerminalMode();
-        this->shell_->registerListener(this);
-
-        // Manually set the widths of the individual status lines
-        this->statusLineWidths_.push_back(29);
-        this->statusLineMaxWidth_ = 29;
-
-        this->getTerminalSize();
-        this->lastTerminalWidth_ = this->terminalWidth_;
-        this->lastTerminalHeight_ = this->terminalHeight_;
-
         // Disable standard this->cout_ logging
         OutputHandler::getInstance().disableCout();
         // Redirect std::cout to an ostringstream
         // (Other part is in the initialiser list)
         std::cout.rdbuf(this->origCout_.rdbuf());
 
-        // Make sure we make way for the status lines
+        this->setTerminalMode();
+        CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo;
+        GetConsoleScreenBufferInfo(this->stdOutHandle_, &screenBufferInfo);
+        this->terminalWidth_  = screenBufferInfo.dwSize.X;
+        this->terminalHeight_ = screenBufferInfo.dwSize.Y;
+        this->lastTerminalWidth_  = this->terminalWidth_;
+        this->lastTerminalHeight_ = this->terminalHeight_;
+        // Determines where we are in respect to output already written with std::cout
+        this->inputLineRow_ = screenBufferInfo.dwCursorPosition.Y;
+
+        // Cursor already at the end of the screen buffer?
+        // (assuming the current input line height is 1)
+        if (this->inputLineRow_ >= (int)this->terminalHeight_ - (int)this->statusLines_)
+            this->moveCursor(0, -this->inputLineRow_ + this->terminalHeight_ - this->statusLines_ - 1);
+
+        // Prevent input line from overflowing
+        int maxInputLength = (this->terminalHeight_ - this->statusLines_) * this->terminalWidth_ - 1 - this->promptString_.size();
+        // Consider that the echo of a command might include the command plus some other characters (assumed max 80)
+        // Also put a minimum so the config file parser is not overwhelmed with the command history
+        this->shell_->getInputBuffer()->setMaxLength(std::min(8192, (maxInputLength - 80) / 2));
+
+        // Print input and status line and position cursor
+        this->lastRefreshTime_ = Game::getInstance().getGameClock().getRealMicroseconds();
         this->update(Game::getInstance().getGameClock());
+        this->inputChanged();
+        this->cursorChanged();
+
+        this->shell_->registerListener(this);
     }
 
     IOConsole::~IOConsole()
     {
+        this->shell_->unregisterListener(this);
         // Empty all buffers
         this->update(Game::getInstance().getGameClock());
 
-        resetTerminalMode();
-        this->shell_->destroy();
+        // Erase input and status lines
+        COORD pos = {0, this->inputLineRow_};
+        this->writeText(std::string((this->inputLineHeight_ + this->statusLines_) * this->terminalWidth_, ' '), pos);
+        // Move cursor to the beginning of the line
+        SetConsoleCursorPosition(stdOutHandle_, pos);
 
         // Restore this->cout_ redirection
         std::cout.rdbuf(this->cout_.rdbuf());
         // Enable standard this->cout_ logging again
         OutputHandler::getInstance().enableCout();
+
+        resetTerminalMode();
+        this->shell_->destroy();
     }
 
     void IOConsole::update(const Clock& time)
     {
+        // Process input
         while (true)
         {
             DWORD count;
@@ -538,8 +564,8 @@
                 switch (inrec.Event.KeyEvent.wVirtualKeyCode)
                 {
                 case VK_BACK:   this->buffer_->buttonPressed(KeyEvent(KeyCode::Back,     asciiChar, modifiersOut)); break;
-                case VK_TAB:    this->buffer_->buttonPressed(KeyEvent(KeyCode::Back,     asciiChar, modifiersOut)); break;
-                case VK_RETURN: this->buffer_->buttonPressed(KeyEvent(KeyCode::Back,     asciiChar, modifiersOut)); break;
+                case VK_TAB:    this->buffer_->buttonPressed(KeyEvent(KeyCode::Tab,      asciiChar, modifiersOut)); break;
+                case VK_RETURN: this->buffer_->buttonPressed(KeyEvent(KeyCode::Return,   asciiChar, modifiersOut)); break;
                 case VK_PAUSE:  this->buffer_->buttonPressed(KeyEvent(KeyCode::Pause,    asciiChar, modifiersOut)); break;
                 case VK_ESCAPE: this->buffer_->buttonPressed(KeyEvent(KeyCode::Escape,   asciiChar, modifiersOut)); break;
                 case VK_SPACE:  this->buffer_->buttonPressed(KeyEvent(KeyCode::Space,    asciiChar, modifiersOut)); break;
@@ -558,11 +584,22 @@
             }
         }
 
-        // Get info about cursor and terminal size
-        this->getTerminalSize();
+        // TODO: Respect screen buffer size changes
+        // The user can manually adjust the screen buffer size on Windows
+        // And we don't want to screw the console because of that
+        //this->lastTerminalWidth_ = this->terminalWidth_;
+        //this->lastTerminalHeight_ = this->terminalHeight_;
+        //this->getTerminalSize(); // Also sets this->inputLineRow_ according to the cursor position
+        // Is there still enough space below the cursor for the status line(s)?
+        //if (this->inputLineRow_ >= this->terminalHeight_ - this->statusLines_)
+        //    this->moveCursor(0, -this->inputLineRow_ + this->terminalHeight_ - this->statusLines_ - 1);
 
-        // Refresh status line
-        this->printStatusLines();
+        // Refresh status line 5 times per second
+        if (time.getMicroseconds() > this->lastRefreshTime_ + 1000000)
+        {
+            this->printStatusLines();
+            this->lastRefreshTime_ = time.getMicroseconds();
+        }
 
         // Process output written to std::cout
         if (!this->origCout_.str().empty())
@@ -570,63 +607,38 @@
             this->shell_->addOutputLine(this->origCout_.str());
             this->origCout_.str("");
         }
-        this->cout_.flush();
     }
 
-    void IOConsole::printLogText(const std::string& text)
+    void IOConsole::printOutputLine(const std::string& text, const COORD& pos)
     {
         std::string output = text;
         int level = this->extractLogLevel(&output);
 
         // Colour line
+        WORD colour = 0;
         switch (level)
         {
-        case  1: SetConsoleTextAttribute(stdOutHandle_, FOREGROUND_RED | FOREGROUND_INTENSITY); break;
-        case  2: SetConsoleTextAttribute(stdOutHandle_, FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); break;
-        case  3: SetConsoleTextAttribute(stdOutHandle_, FOREGROUND_INTENSITY); break;
-        case  4: SetConsoleTextAttribute(stdOutHandle_, FOREGROUND_INTENSITY); break;
-        default: break;
+        case  1: colour = FOREGROUND_RED | FOREGROUND_INTENSITY; break;
+        case  2: colour = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; break;
+        case  3: colour = FOREGROUND_INTENSITY; break;
+        case  4: colour = FOREGROUND_INTENSITY; break;
+        default: colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN; break;
         }
 
         // Print output line
-        this->cout_ << output;
-
-        // Reset colour to white
-        SetConsoleTextAttribute(stdOutHandle_, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN);
+        this->writeText(output, pos, colour);
     }
 
-    void IOConsole::printInputLine()
-    {
-        SetConsoleTextAttribute(stdOutHandle_, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
-        this->moveCursorYAndHome(0);
-        this->clearCurrentLine();
-        this->cout_ << this->promptString_ << this->shell_->getInput();
-        this->moveCursorYAndHome(0);
-        this->moveCursor(this->promptString_.size() + this->buffer_->getCursorPosition(), 0);
-        SetConsoleTextAttribute(stdOutHandle_, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN);
-    }
-
     void IOConsole::printStatusLines()
     {
-        if (this->willPrintStatusLines())
-        {
-            SetConsoleTextAttribute(stdOutHandle_, FOREGROUND_GREEN);
-            this->bStatusPrinted_ = true;
-            // Put cursor on home position, one line down the input line
-            this->moveCursorYAndHome(1);
-            this->cout_ << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, ";
-            this->cout_ <<               std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms tick time";
-            // Clear rest of the line
-            CONSOLE_SCREEN_BUFFER_INFO info;
-            GetConsoleScreenBufferInfo(this->stdOutHandle_, &info);
-            this->cout_ << std::string(info.dwSize.X - info.dwCursorPosition.X - 1, ' ');
-            // Restore cursor position
-            this->moveCursorYAndHome(-1);
-            this->moveCursor(this->promptString_.size() + this->buffer_->getCursorPosition(), 0);
-            SetConsoleTextAttribute(stdOutHandle_, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN);
-        }
-        else
-            this->bStatusPrinted_ = false;
+        // Prepare text to be written
+        std::ostringstream oss;
+        oss << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, ";
+        oss <<               std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms tick time";
+        // Clear rest of the line by inserting spaces
+        oss << std::string(this->terminalWidth_ - oss.str().size(), ' ');
+        COORD pos = {0, this->inputLineRow_ + this->inputLineHeight_};
+        this->writeText(oss.str(), pos, FOREGROUND_GREEN);
     }
 
     void IOConsole::setTerminalMode()
@@ -649,8 +661,7 @@
         SetConsoleMode(this->stdInHandle_, this->originalTerminalSettings_);
     }
 
-    //! Moves the console cursor around and inserts new lines when reaching the end.
-    //! Moving out on the right is just clamped though.
+    //! Moves the console cursor around and clamps its position to fit into the screen buffer
     void IOConsole::moveCursor(int dx, int dy)
     {
         CONSOLE_SCREEN_BUFFER_INFO info;
@@ -658,73 +669,129 @@
         SHORT& x = info.dwCursorPosition.X;
         x = clamp(x + dx, 0, info.dwSize.X - 1);
         SHORT& y = info.dwCursorPosition.Y;
-        if (y + dy >= info.dwSize.Y)
-        {
-            // Insert new lines
-            this->cout_ << std::string(y + dy - info.dwSize.Y + 1, 'n');
-            y = info.dwSize.Y - 1;
-        }
-        else if (y < 0)
-            y = 0;
-        else
-            y += dy;
+        y = clamp(y + dy, 0, info.dwSize.Y - 1);
         SetConsoleCursorPosition(this->stdOutHandle_, info.dwCursorPosition);
     }
 
-    void IOConsole::moveCursorYAndHome(int dy)
+    void IOConsole::getTerminalSize()
     {
-        CONSOLE_SCREEN_BUFFER_INFO info;
-        GetConsoleScreenBufferInfo(this->stdOutHandle_, &info);
-        this->moveCursor(-info.dwCursorPosition.X, dy);
+        CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo;
+        GetConsoleScreenBufferInfo(this->stdOutHandle_, &screenBufferInfo);
+        this->terminalWidth_  = screenBufferInfo.dwSize.X;
+        this->terminalHeight_ = screenBufferInfo.dwSize.Y;
     }
 
-    void IOConsole::clearCurrentLine()
+    void IOConsole::writeText(const std::string& text, const COORD& coord, WORD attributes)
     {
-        CONSOLE_SCREEN_BUFFER_INFO info;
-        GetConsoleScreenBufferInfo(this->stdOutHandle_, &info);
-        info.dwCursorPosition.X = 0;
         DWORD count;
-        FillConsoleOutputCharacter(this->stdOutHandle_, ' ', info.dwSize.X, info.dwCursorPosition, &count);;
+        WriteConsoleOutputCharacter(stdOutHandle_, text.c_str(), text.size(), coord, &count);
+        WORD* attributeBuf = new WORD[text.size()];
+        for (unsigned int i = 0; i < text.size(); ++i)
+            attributeBuf[i] = attributes;
+        WriteConsoleOutputAttribute(stdOutHandle_, attributeBuf, text.size(), coord, &count);
     }
 
-    void IOConsole::getTerminalSize()
+    void IOConsole::createNewOutputLines(unsigned int lines)
     {
-        CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo;
-        GetConsoleScreenBufferInfo(this->stdOutHandle_, &screenBufferInfo);
-        // dwSize is the maximum size. If you resize you will simply see scroll bars.
-        // And if you want to write outside these boundaries, you can't.
-        this->terminalWidth_  = screenBufferInfo.dwSize.X;
-        this->terminalHeight_ = screenBufferInfo.dwSize.Y;
+        CHAR_INFO fillChar = {' ', FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED};
+        // Check whether we're already at the bottom
+        if (this->inputLineRow_ + lines > this->terminalHeight_ - this->statusLines_ - this->inputLineHeight_)
+        {
+            // Scroll output up
+            SMALL_RECT oldRect = {0, lines, this->terminalWidth_ - 1, this->inputLineRow_ - 1};
+            COORD newPos = {0, 0};
+            ScrollConsoleScreenBuffer(stdOutHandle_, &oldRect, NULL, newPos, &fillChar);
+        }
+        else
+        {
+            // Scroll input and status lines down
+            SMALL_RECT oldRect = {0, this->inputLineRow_, this->terminalWidth_ - 1, this->inputLineRow_ + this->statusLines_ + this->inputLineHeight_ - 1};
+            this->inputLineRow_ += lines;
+            COORD newPos = {0, this->inputLineRow_};
+            ScrollConsoleScreenBuffer(stdOutHandle_, &oldRect, NULL, newPos, &fillChar);
+            // Move cursor down to the new bottom so the user can see the status lines
+            COORD pos = {0, this->inputLineRow_ + this->inputLineHeight_ - 1 + this->statusLines_};
+            SetConsoleCursorPosition(stdOutHandle_, pos);
+            // Get cursor back to the right position
+            this->cursorChanged();
+        }
     }
 
     // ###############################
     // ###  ShellListener methods  ###
     // ###############################
 
+    //! Called if the text in the input-line has changed
+    void IOConsole::inputChanged()
+    {
+        int inputLineLength = this->promptString_.size() + this->shell_->getInput().size();
+        int lineHeight = 1 + inputLineLength / this->terminalWidth_;
+        int newLines = lineHeight - this->inputLineHeight_;
+        if (newLines > 0)
+        {
+            // Abuse this function to scroll the console
+            this->createNewOutputLines(newLines);
+            this->inputLineRow_ -= newLines; // Undo
+        }
+        else if (newLines < 0)
+        {
+            // Scroll status lines up
+            SMALL_RECT oldRect = {0, this->inputLineRow_ + this->inputLineHeight_, this->terminalWidth_ - 1, this->inputLineRow_ + this->inputLineHeight_ + this->statusLines_};
+            COORD newPos = {0, this->inputLineRow_ + this->inputLineHeight_ + newLines};
+            CHAR_INFO fillChar = {' ', FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED};
+            ScrollConsoleScreenBuffer(stdOutHandle_, &oldRect, NULL, newPos, &fillChar);
+            // Clear potential leftovers
+            if (-newLines - this->statusLines_ > 0)
+            {
+                COORD pos = {0, this->inputLineRow_ + lineHeight + this->statusLines_};
+                this->writeText(std::string((-newLines - this->statusLines_) * this->terminalWidth_, ' '), pos);
+            }
+        }
+        this->inputLineHeight_ = lineHeight;
+
+        // Print the whole line, including spaces to erase leftovers
+        COORD pos = {0, this->inputLineRow_};
+        WORD colour = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
+        this->writeText(this->promptString_ + this->shell_->getInput() + std::string(this->terminalWidth_ - inputLineLength % this->terminalWidth_, ' '), pos, colour);
+        // If necessary, move cursor
+        if (newLines != 0)
+            this->cursorChanged();
+    }
+
+    //! Called if the position of the cursor in the input-line has changed
+    void IOConsole::cursorChanged()
+    {
+        COORD pos;
+        unsigned int total = this->promptString_.size() + this->buffer_->getCursorPosition();
+        // Compensate for cursor further to the right than the terminal width
+        pos.X = total % this->terminalWidth_;
+        pos.Y = this->inputLineRow_ + total / this->terminalWidth_;
+        SetConsoleCursorPosition(stdOutHandle_, pos);
+    }
+
     //! Called if only the last output-line has changed
     void IOConsole::onlyLastLineChanged()
     {
-        this->moveCursorYAndHome(-1);
-        this->clearCurrentLine();
-        this->printLogText(*(this->shell_->getNewestLineIterator()));
-        this->moveCursorYAndHome(1);
-        this->moveCursor(this->promptString_.size() + this->shell_->getInput().size(), 0);
-        this->cout_.flush();
+        int lineHeight = 1 + this->shell_->getNewestLineIterator()->size() / this->terminalWidth_;
+        int newLines = lineHeight - this->lastOutputLineHeight_;
+        this->lastOutputLineHeight_ = lineHeight;
+        if (newLines > 0)
+            this->createNewOutputLines(newLines);
+        // Write text (assuming it is longer than the previous text)
+        assert(newLines >= 0);
+        COORD pos = {0, this->inputLineRow_ - lineHeight};
+        this->printOutputLine(*(this->shell_->getNewestLineIterator()), pos);
     }
 
     //! Called if a new output-line was added
     void IOConsole::lineAdded()
     {
-        // Move cursor to the beginning of the new (last) output line
-        this->moveCursorYAndHome(0);
-        // Print the new output lines
-        this->printLogText(*(this->shell_->getNewestLineIterator()));
-        // Move cursor down
-        this->moveCursorYAndHome(1);
-        // Print status and input lines
-        this->printInputLine();
-        this->printStatusLines();
-        this->cout_.flush();
+        this->lastOutputLineHeight_ = 1 + this->shell_->getNewestLineIterator()->size() / this->terminalWidth_;
+        if (this->lastOutputLineHeight_ > 0)
+            this->createNewOutputLines(this->lastOutputLineHeight_);
+        // Write the text
+        COORD pos = {0, this->inputLineRow_ - this->lastOutputLineHeight_};
+        this->printOutputLine(*(this->shell_->getNewestLineIterator()), pos);
     }
 }
 

Modified: code/branches/presentation2/src/libraries/core/IOConsole.h
===================================================================
--- code/branches/presentation2/src/libraries/core/IOConsole.h	2009-11-29 12:36:12 UTC (rev 6176)
+++ code/branches/presentation2/src/libraries/core/IOConsole.h	2009-11-29 13:47:54 UTC (rev 6177)
@@ -42,6 +42,7 @@
 struct termios;
 #elif defined(ORXONOX_PLATFORM_WINDOWS)
 #define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
 #include <windows.h>
 #endif
 
@@ -59,13 +60,9 @@
 
     private:
         void setTerminalMode();
-        static void resetTerminalMode();
         void getTerminalSize();
-        bool willPrintStatusLines();
         int extractLogLevel(std::string* text);
 
-        void printLogText(const std::string& line);
-        void printInputLine();
         void printStatusLines();
 
         // Methods from ShellListener
@@ -84,23 +81,36 @@
         unsigned int            terminalHeight_;
         unsigned int            lastTerminalWidth_;
         unsigned int            lastTerminalHeight_;
+        const std::string       promptString_;
+
+#ifdef ORXONOX_PLATFORM_UNIX
+        bool willPrintStatusLines();
+        void printOutputLine(const std::string& line);
+        void printInputLine();
+        static void resetTerminalMode();
+
         bool                    bPrintStatusLine_;
         bool                    bStatusPrinted_;
         std::vector<unsigned>   statusLineWidths_;
         unsigned int            statusLineMaxWidth_;
-        const std::string       promptString_;
         static const unsigned   minOutputLines_ = 3;
+        termios*                originalTerminalSettings_;
 
-#ifdef ORXONOX_PLATFORM_UNIX
-        termios*         originalTerminalSettings_;
 #elif defined(ORXONOX_PLATFORM_WINDOWS)
+        void resetTerminalMode();
         void moveCursor(int dx, int dy);
-        void moveCursorYAndHome(int dy);
-        void clearCurrentLine();
+        void writeText(const std::string& text, const COORD& pos, WORD attributes = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
+        void createNewOutputLines(unsigned int lines);
+        void printOutputLine(const std::string& line, const COORD& pos);
 
         DWORD                   originalTerminalSettings_;
         HANDLE                  stdInHandle_;
         HANDLE                  stdOutHandle_;
+        int                     inputLineRow_;
+        unsigned int            inputLineHeight_;
+        const unsigned int      statusLines_;
+        unsigned int            lastOutputLineHeight_;
+        uint64_t                lastRefreshTime_;
 #endif
 
         static IOConsole* singletonPtr_s;

Modified: code/branches/presentation2/src/libraries/core/input/InputBuffer.cc
===================================================================
--- code/branches/presentation2/src/libraries/core/input/InputBuffer.cc	2009-11-29 12:36:12 UTC (rev 6176)
+++ code/branches/presentation2/src/libraries/core/input/InputBuffer.cc	2009-11-29 13:47:54 UTC (rev 6177)
@@ -40,6 +40,7 @@
 
         this->buffer_ = "";
         this->cursor_ = 0;
+        this->maxLength_ = 1024;
         this->allowedChars_ = "abcdefghijklmnopqrstuvwxyz \
                                ABCDEFGHIJKLMNOPQRSTUVWXYZ \
                                äëïöüÄËÏÖÜáâàéêèíîìóôòúûù \
@@ -58,6 +59,7 @@
     {
         RegisterRootObject(InputBuffer);
 
+        this->maxLength_ = 1024;
         this->allowedChars_ = allowedChars;
         this->buffer_ = "";
         this->cursor_ = 0;
@@ -92,6 +94,13 @@
         }
     }
 
+    void InputBuffer::setMaxLength(unsigned int length)
+    {
+        this->maxLength_ = length;
+        if (this->buffer_.size() > length)
+            this->buffer_.resize(length);
+    }
+
     void InputBuffer::set(const std::string& input, bool update)
     {
         this->clear(false);
@@ -116,6 +125,8 @@
     {
         if (this->charIsAllowed(input))
         {
+            if (this->buffer_.size() >= this->maxLength_)
+                return;
             this->buffer_.insert(this->cursor_, 1, input);
             ++this->cursor_;
         }

Modified: code/branches/presentation2/src/libraries/core/input/InputBuffer.h
===================================================================
--- code/branches/presentation2/src/libraries/core/input/InputBuffer.h	2009-11-29 12:36:12 UTC (rev 6176)
+++ code/branches/presentation2/src/libraries/core/input/InputBuffer.h	2009-11-29 13:47:54 UTC (rev 6177)
@@ -82,6 +82,9 @@
 
             void setConfigValues();
 
+            unsigned int getMaxLength() const { return this->maxLength_; }
+            void setMaxLength(unsigned int length);
+
             template <class T>
             void registerListener(T* listener, void (T::*function)(), bool bOnlySingleInput)
             {
@@ -174,6 +177,7 @@
             std::string buffer_;
             std::list<BaseInputBufferListenerTuple*> listeners_;
             std::string allowedChars_;
+            unsigned int maxLength_;
             unsigned int cursor_;
 
             KeyCode::ByEnum lastKey_;




More information about the Orxonox-commit mailing list