Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
May 17, 2008, 3:58:19 AM (16 years ago)
Author:
landauf
Message:
  • implemented Shell, but not yet linked with the graphical console
  • added new features (cursor, OIS::KeyCode listener) to InputBuffer
  • changed some includes to avoid circular header-dependencies in OrxonoxClass and Shell
File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/console/src/core/Shell.cc

    r1312 r1313  
    2727 */
    2828
    29 #include "CorePrereqs.h"
    30 
    31 #include "OrxonoxClass.h"
    32 #include "InputBuffer.h"
    33 #include "OutputBuffer.h"
     29#include "Shell.h"
     30#include "CommandExecutor.h"
     31#include "CoreIncludes.h"
     32#include "ConfigValueIncludes.h"
     33
     34#define SHELL_UPDATE_LISTENERS(function) \
     35    for (std::list<ShellListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it) \
     36        (*it)->function()
    3437
    3538namespace orxonox
     
    3740    Shell::Shell()
    3841    {
     42        RegisterRootObject(Shell);
     43
     44        this->scrollPosition_ = 0;
     45        this->maxHistoryLength_ = 100;
     46        this->historyPosition_ = 0;
     47        this->historyOffset_ = 0;
     48
     49        this->clearLines();
     50
    3951        this->inputBuffer_.registerListener(this, &Shell::inputChanged, true);
    4052        this->inputBuffer_.registerListener(this, &Shell::execute, '\r', false);
    4153        this->inputBuffer_.registerListener(this, &Shell::hintandcomplete, '\t', true);
    42         this->inputBuffer_.registerListener(this, &Shell::clear, '§', true);
    4354        this->inputBuffer_.registerListener(this, &Shell::backspace, '\b', true);
     55        this->inputBuffer_.registerListener(this, &Shell::deletechar, OIS::KC_DELETE);
    4456        this->inputBuffer_.registerListener(this, &Shell::exit, (char)27, true);
    4557        this->inputBuffer_.registerListener(this, &Shell::cursor_right, OIS::KC_RIGHT);
    4658        this->inputBuffer_.registerListener(this, &Shell::cursor_left, OIS::KC_LEFT);
     59        this->inputBuffer_.registerListener(this, &Shell::cursor_end, OIS::KC_END);
     60        this->inputBuffer_.registerListener(this, &Shell::cursor_home, OIS::KC_HOME);
    4761        this->inputBuffer_.registerListener(this, &Shell::history_up, OIS::KC_UP);
    4862        this->inputBuffer_.registerListener(this, &Shell::history_down, OIS::KC_DOWN);
    4963        this->inputBuffer_.registerListener(this, &Shell::scroll_up, OIS::KC_PGUP);
    5064        this->inputBuffer_.registerListener(this, &Shell::scroll_down, OIS::KC_PGDOWN);
     65
     66        this->setConfigValues();
    5167    }
    5268
    5369    Shell& Shell::getInstance()
    5470    {
    55         static instance Shell;
     71        static Shell instance;
    5672        return instance;
    5773    }
    5874
    5975    void Shell::setConfigValues()
     76    {
     77        SetConfigValue(maxHistoryLength_, 100);
     78        SetConfigValue(historyOffset_, 0);
     79        SetConfigValueVector(commandHistory_, std::vector<std::string>(1, ""));
     80
     81        if (this->historyOffset_ >= this->maxHistoryLength_)
     82            this->historyOffset_ = 0;
     83
     84        while (this->commandHistory_.size() > this->maxHistoryLength_)
     85        {
     86            unsigned int index = this->commandHistory_.size() - 1;
     87            this->commandHistory_.erase(this->commandHistory_.begin() + index);
     88            ModifyConfigValue(commandHistory_, remove, index);
     89        }
     90    }
     91
     92    void Shell::registerListener(ShellListener* listener)
     93    {
     94        this->listeners_.insert(this->listeners_.end(), listener);
     95    }
     96
     97    void Shell::unregisterListener(ShellListener* listener)
     98    {
     99        for (std::list<ShellListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); )
     100        {
     101            if ((*it) == listener)
     102                this->listeners_.erase(it++);
     103            else
     104                ++it;
     105        }
     106    }
     107
     108    void Shell::setCursorPosition(unsigned int cursor)
     109    {
     110        this->inputBuffer_.setCursorPosition(cursor);
     111        SHELL_UPDATE_LISTENERS(cursorChanged);
     112    }
     113
     114    void Shell::setInput(const std::string& input)
     115    {
     116        this->inputBuffer_.set(input);
     117        this->inputChanged();
     118    }
     119
     120    void Shell::addLine(const std::string& line, unsigned int level)
     121    {
     122        if ((*this->lines_.begin()) != "")
     123        {
     124            orxonox::OutputHandler::getOutStream().setOutputLevel(level) << std::endl;
     125        }
     126        orxonox::OutputHandler::getOutStream().setOutputLevel(level) << line << std::endl;
     127    }
     128
     129    void Shell::clearLines()
     130    {
     131        this->lines_.clear();
     132        this->lines_.insert(this->lines_.begin(), "");
     133        this->scrollIterator_ = this->lines_.begin();
     134
     135        this->scrollPosition_ = 0;
     136
     137        SHELL_UPDATE_LISTENERS(linesChanged);
     138    }
     139
     140    std::list<std::string>::const_iterator Shell::getNewestLineIterator() const
     141    {
     142        if (this->scrollPosition_)
     143            return this->scrollIterator_;
     144        else
     145            return this->lines_.begin();
     146    }
     147
     148    std::list<std::string>::const_iterator Shell::getEndIterator() const
     149    {
     150        return this->lines_.end();
     151    }
     152
     153    void Shell::addToHistory(const std::string& command)
     154    {
     155        this->historyOffset_ = (this->historyOffset_ + 1) % this->maxHistoryLength_;
     156        ModifyConfigValue(commandHistory_, set, this->historyOffset_, command);
     157        this->commandHistory_[this->historyOffset_] = command;
     158        this->historyPosition_ = 0;
     159    }
     160
     161    std::string Shell::getFromHistory() const
     162    {
     163        return this->commandHistory_[(this->historyOffset_ - this->historyPosition_) % this->maxHistoryLength_];
     164    }
    60165
    61166    void Shell::outputChanged()
     167    {
     168        std::string output;
     169        while (this->outputBuffer_.getLine(&output))
     170        {
     171            (*this->lines_.begin()) += output;
     172            this->lines_.insert(this->lines_.begin(), "");
     173
     174            if (this->scrollPosition_)
     175                this->scrollPosition_++;
     176            else
     177                this->scrollIterator_ = this->lines_.begin();
     178
     179            SHELL_UPDATE_LISTENERS(linesChanged);
     180            SHELL_UPDATE_LISTENERS(lineAdded);
     181        }
     182
     183        (*this->lines_.begin()) += output;
     184        SHELL_UPDATE_LISTENERS(onlyLastLineChanged);
     185    }
     186
    62187    void Shell::inputChanged()
     188    {
     189        SHELL_UPDATE_LISTENERS(inputChanged);
     190        SHELL_UPDATE_LISTENERS(cursorChanged);
     191    }
     192
    63193    void Shell::execute()
     194    {
     195        if (CommandExecutor::execute(this->inputBuffer_.get()))
     196            this->addLine(this->inputBuffer_.get(), 0);
     197        else
     198            this->addLine("Error: Can't execute \"" + this->inputBuffer_.get() + "\".", 1);
     199
     200        this->clear();
     201    }
     202
    64203    void Shell::hintandcomplete()
     204    {
     205        this->addLine(CommandExecutor::hint(this->inputBuffer_.get()), 0);
     206        this->inputBuffer_.set(CommandExecutor::complete(this->inputBuffer_.get()));
     207
     208        this->inputChanged();
     209    }
     210
    65211    void Shell::backspace()
     212    {
     213        this->inputBuffer_.removeBehindCursor();
     214        SHELL_UPDATE_LISTENERS(inputChanged);
     215        SHELL_UPDATE_LISTENERS(cursorChanged);
     216    }
     217
     218    void Shell::deletechar()
     219    {
     220        this->inputBuffer_.removeAtCursor();
     221        SHELL_UPDATE_LISTENERS(inputChanged);
     222    }
     223
    66224    void Shell::clear()
     225    {
     226        this->inputBuffer_.clear();
     227        SHELL_UPDATE_LISTENERS(inputChanged);
     228        SHELL_UPDATE_LISTENERS(cursorChanged);
     229    }
     230
    67231    void Shell::cursor_right()
     232    {
     233        this->inputBuffer_.increaseCursor();
     234        SHELL_UPDATE_LISTENERS(cursorChanged);
     235    }
     236
    68237    void Shell::cursor_left()
     238    {
     239        this->inputBuffer_.decreaseCursor();
     240        SHELL_UPDATE_LISTENERS(cursorChanged);
     241    }
     242
     243    void Shell::cursor_end()
     244    {
     245        this->inputBuffer_.setCursorToEnd();
     246        SHELL_UPDATE_LISTENERS(cursorChanged);
     247    }
     248
     249    void Shell::cursor_home()
     250    {
     251        this->inputBuffer_.setCursorToBegin();
     252        SHELL_UPDATE_LISTENERS(cursorChanged);
     253    }
     254
    69255    void Shell::history_up()
     256    {
     257        if (this->historyPosition_ < (this->commandHistory_.size() - 1))
     258        {
     259            this->historyPosition_++;
     260            this->inputBuffer_.set(this->getFromHistory());
     261        }
     262    }
     263
    70264    void Shell::history_down()
     265    {
     266        if (this->historyPosition_ > 0)
     267        {
     268            this->historyPosition_++;
     269            this->inputBuffer_.set(this->getFromHistory());
     270        }
     271    }
     272
    71273    void Shell::scroll_up()
     274    {
     275        if (this->scrollIterator_ != this->lines_.end())
     276        {
     277            ++this->scrollIterator_;
     278            ++this->scrollPosition_;
     279
     280            SHELL_UPDATE_LISTENERS(linesChanged);
     281        }
     282    }
     283
    72284    void Shell::scroll_down()
     285    {
     286        if (this->scrollIterator_ != this->lines_.begin())
     287        {
     288            --this->scrollIterator_;
     289            --this->scrollPosition_;
     290
     291            SHELL_UPDATE_LISTENERS(linesChanged);
     292        }
     293    }
     294
    73295    void Shell::exit()
     296    {
     297        if (this->inputBuffer_.getSize() > 0)
     298        {
     299            this->clear();
     300            return;
     301        }
     302
     303        this->clear();
     304        SHELL_UPDATE_LISTENERS(exit);
     305    }
    74306}
Note: See TracChangeset for help on using the changeset viewer.