Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Nov 20, 2009, 4:55:40 PM (15 years ago)
Author:
rgrieder
Message:

Merged console branch back to trunk.

Location:
code/trunk
Files:
21 edited
2 copied

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/core/CMakeLists.txt

    r6021 r6105  
    2929  GraphicsManager.cc
    3030  GUIManager.cc
     31  IOConsole.cc
    3132  Language.cc
    3233  LuaState.cc
  • code/trunk/src/libraries/core/ConfigFileManager.h

    r5738 r6105  
    5454    };
    5555
    56     bool config(const std::string& classname, const std::string& varname, const std::string& value);
    57     bool tconfig(const std::string& classname, const std::string& varname, const std::string& value);
    58     void reloadConfig();
    59     void saveConfig();
    60     void cleanConfig();
    61     void loadSettings(const std::string& filename);
     56    _CoreExport bool config(const std::string& classname, const std::string& varname, const std::string& value);
     57    _CoreExport bool tconfig(const std::string& classname, const std::string& varname, const std::string& value);
     58    _CoreExport void reloadConfig();
     59    _CoreExport void saveConfig();
     60    _CoreExport void cleanConfig();
     61    _CoreExport void loadSettings(const std::string& filename);
    6262
    6363
  • code/trunk/src/libraries/core/ConfigValueIncludes.h

    r5738 r6105  
    4747    @param defvalue The default-value of the variable
    4848*/
    49 #define SetConfigValueGeneric(type, varname, defvalue) \
     49#define SetConfigValueGeneric(type, varname, entryname, sectionname, defvalue) \
    5050    static orxonox::Identifier* identifier##varname = this->getIdentifier(); \
    51     orxonox::ConfigValueContainer* container##varname = identifier##varname->getConfigValueContainer(#varname); \
     51    orxonox::ConfigValueContainer* container##varname = identifier##varname->getConfigValueContainer(entryname); \
    5252    if (!container##varname) \
    5353    { \
    54         container##varname = new orxonox::ConfigValueContainer(type, identifier##varname, identifier##varname->getName(), #varname, defvalue, varname); \
    55         identifier##varname->addConfigValueContainer(#varname, container##varname); \
     54        container##varname = new orxonox::ConfigValueContainer(type, identifier##varname, sectionname, entryname, defvalue, varname); \
     55        identifier##varname->addConfigValueContainer(entryname, container##varname); \
    5656    } \
    5757    container##varname->getValue(&varname, this)
    5858
    59 #define SetConfigValue(varname, defvalue) SetConfigValueGeneric(ConfigFileType::Settings, varname, defvalue)
     59#define SetConfigValue(varname, defvalue) SetConfigValueGeneric(ConfigFileType::Settings, varname, #varname, identifier##varname->getName(), defvalue)
    6060
    6161
  • code/trunk/src/libraries/core/ConsoleCommandCompilation.cc

    r5781 r6105  
    8686    std::string echo(const std::string& text)
    8787    {
    88         std::cout << text << std::endl;
    8988        return text;
    9089    }
  • code/trunk/src/libraries/core/Core.cc

    r6021 r6105  
    6464#include "Identifier.h"
    6565#include "Language.h"
     66#include "IOConsole.h"
    6667#include "LuaState.h"
    6768#include "ScopedSingletonManager.h"
    68 #include "Shell.h"
    6969#include "TclBind.h"
    7070#include "TclThreadManager.h"
     
    105105        void setConfigValues()
    106106        {
    107 #ifdef NDEBUG
    108             const unsigned int defaultLevelConsole = 1;
    109             const unsigned int defaultLevelLogfile = 3;
    110             const unsigned int defaultLevelShell   = 1;
     107#ifdef ORXONOX_RELEASE
     108            const unsigned int defaultLevelLogFile = 3;
    111109#else
    112             const unsigned int defaultLevelConsole = 3;
    113             const unsigned int defaultLevelLogfile = 4;
    114             const unsigned int defaultLevelShell   = 3;
    115 #endif
    116             SetConfigValue(softDebugLevelConsole_, defaultLevelConsole)
    117                 .description("The maximal level of debug output shown in the console")
    118                 .callback(this, &CoreConfiguration::debugLevelChanged);
    119             SetConfigValue(softDebugLevelLogfile_, defaultLevelLogfile)
    120                 .description("The maximal level of debug output shown in the logfile")
    121                 .callback(this, &CoreConfiguration::debugLevelChanged);
    122             SetConfigValue(softDebugLevelShell_, defaultLevelShell)
    123                 .description("The maximal level of debug output shown in the ingame shell")
    124                 .callback(this, &CoreConfiguration::debugLevelChanged);
     110            const unsigned int defaultLevelLogFile = 4;
     111#endif
     112            SetConfigValueGeneric(ConfigFileType::Settings, softDebugLevelLogFile_, "softDebugLevelLogFile", "OutputHandler", defaultLevelLogFile)
     113                .description("The maximum level of debug output shown in the log file");
     114            OutputHandler::getInstance().setSoftDebugLevel(OutputHandler::logFileOutputListenerName_s, this->softDebugLevelLogFile_);
    125115
    126116            SetConfigValue(language_, Language::getInstance().defaultLanguage_)
    127                 .description("The language of the ingame text")
     117                .description("The language of the in game text")
    128118                .callback(this, &CoreConfiguration::languageChanged);
    129119            SetConfigValue(bInitializeRandomNumberGenerator_, true)
    130120                .description("If true, all random actions are different each time you start the game")
    131121                .callback(this, &CoreConfiguration::initializeRandomNumberGenerator);
    132         }
    133 
    134         /**
    135             @brief Callback function if the debug level has changed.
    136         */
    137         void debugLevelChanged()
    138         {
    139             // softDebugLevel_ is the maximum of the 3 variables
    140             this->softDebugLevel_ = this->softDebugLevelConsole_;
    141             if (this->softDebugLevelLogfile_ > this->softDebugLevel_)
    142                 this->softDebugLevel_ = this->softDebugLevelLogfile_;
    143             if (this->softDebugLevelShell_ > this->softDebugLevel_)
    144                 this->softDebugLevel_ = this->softDebugLevelShell_;
    145 
    146             OutputHandler::setSoftDebugLevel(OutputHandler::LD_All,     this->softDebugLevel_);
    147             OutputHandler::setSoftDebugLevel(OutputHandler::LD_Console, this->softDebugLevelConsole_);
    148             OutputHandler::setSoftDebugLevel(OutputHandler::LD_Logfile, this->softDebugLevelLogfile_);
    149             OutputHandler::setSoftDebugLevel(OutputHandler::LD_Shell,   this->softDebugLevelShell_);
    150122        }
    151123
     
    178150        }
    179151
    180         int softDebugLevel_;                            //!< The debug level
    181         int softDebugLevelConsole_;                     //!< The debug level for the console
    182         int softDebugLevelLogfile_;                     //!< The debug level for the logfile
    183         int softDebugLevelShell_;                       //!< The debug level for the ingame shell
     152        int softDebugLevelLogFile_;                     //!< The debug level for the log file (belongs to OutputHandler)
    184153        std::string language_;                          //!< The language
    185154        bool bInitializeRandomNumberGenerator_;         //!< If true, srand(time(0)) is called
     
    221190        this->pathConfig_->setConfigurablePaths();
    222191
    223         // create a signal handler (only active for linux)
     192        // create a signal handler (only active for Linux)
    224193        // This call is placed as soon as possible, but after the directories are set
    225194        this->signalHandler_.reset(new SignalHandler());
    226195        this->signalHandler_->doCatch(PathConfig::getExecutablePathString(), PathConfig::getLogPathString() + "orxonox_crash.log");
    227196
    228         // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used
    229         OutputHandler::getOutStream().setLogPath(PathConfig::getLogPathString());
     197        // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% (Windows) was used
     198        OutputHandler::getInstance().setLogPath(PathConfig::getLogPathString());
    230199
    231200        // Parse additional options file now that we know its path
     
    249218        this->languageInstance_.reset(new Language());
    250219
     220        // create persistent io console
     221        this->ioConsole_.reset(new IOConsole());
     222
    251223        // creates the class hierarchy for all classes with factories
    252224        Identifier::createClassHierarchy();
     
    262234        this->tclBind_.reset(new TclBind(PathConfig::getDataPathString()));
    263235        this->tclThreadManager_.reset(new TclThreadManager(tclBind_->getTclInterpreter()));
    264 
    265         // create a shell
    266         this->shell_.reset(new Shell());
    267236
    268237        // Create singletons that always exist (in other libraries)
     
    325294        bGraphicsLoaded_ = false;
    326295        GameMode::bShowsGraphics_s = false;
    327     }
    328 
    329     /**
    330         @brief Returns the softDebugLevel for the given device (returns a default-value if the class is right about to be created).
    331         @param device The device
    332         @return The softDebugLevel
    333     */
    334     /*static*/ int Core::getSoftDebugLevel(OutputHandler::OutputDevice device)
    335     {
    336         switch (device)
    337         {
    338         case OutputHandler::LD_All:
    339             return Core::getInstance().configuration_->softDebugLevel_;
    340         case OutputHandler::LD_Console:
    341             return Core::getInstance().configuration_->softDebugLevelConsole_;
    342         case OutputHandler::LD_Logfile:
    343             return Core::getInstance().configuration_->softDebugLevelLogfile_;
    344         case OutputHandler::LD_Shell:
    345             return Core::getInstance().configuration_->softDebugLevelShell_;
    346         default:
    347             assert(0);
    348             return 2;
    349         }
    350     }
    351 
    352      /**
    353         @brief Sets the softDebugLevel for the given device. Please use this only temporary and restore the value afterwards, as it overrides the configured value.
    354         @param device The device
    355         @param level The level
    356     */
    357     /*static*/ void Core::setSoftDebugLevel(OutputHandler::OutputDevice device, int level)
    358     {
    359         if (device == OutputHandler::LD_All)
    360             Core::getInstance().configuration_->softDebugLevel_ = level;
    361         else if (device == OutputHandler::LD_Console)
    362             Core::getInstance().configuration_->softDebugLevelConsole_ = level;
    363         else if (device == OutputHandler::LD_Logfile)
    364             Core::getInstance().configuration_->softDebugLevelLogfile_ = level;
    365         else if (device == OutputHandler::LD_Shell)
    366             Core::getInstance().configuration_->softDebugLevelShell_ = level;
    367 
    368         OutputHandler::setSoftDebugLevel(device, level);
    369296    }
    370297
     
    444371            ScopedSingletonManager::update<ScopeID::Graphics>(time);
    445372        }
     373        // process console text
     374        this->ioConsole_->update(time);
    446375        // process thread commands
    447376        this->tclThreadManager_->update(time);
  • code/trunk/src/libraries/core/Core.h

    r5929 r6105  
    6969            void setConfigValues();
    7070
    71             static int   getSoftDebugLevel(OutputHandler::OutputDevice device = OutputHandler::LD_All);
    72             static void  setSoftDebugLevel(OutputHandler::OutputDevice device, int level);
    7371            static const std::string& getLanguage();
    7472            static void  resetLanguage();
     
    9391            scoped_ptr<ConfigFileManager> configFileManager_;
    9492            scoped_ptr<Language>          languageInstance_;
     93            scoped_ptr<IOConsole>         ioConsole_;
    9594            scoped_ptr<CoreConfiguration> configuration_;
    9695            scoped_ptr<TclBind>           tclBind_;
    9796            scoped_ptr<TclThreadManager>  tclThreadManager_;
    98             scoped_ptr<Shell>             shell_;
    9997            // graphical
    10098            scoped_ptr<GraphicsManager>   graphicsManager_;     //!< Interface to OGRE
  • code/trunk/src/libraries/core/CorePrereqs.h

    r6021 r6105  
    148148    class GUIManager;
    149149    class Identifier;
     150    class IOConsole;
    150151    class IRC;
    151152    template <class T>
  • code/trunk/src/libraries/core/GUIManager.cc

    r5929 r6105  
    5353#include "util/Exception.h"
    5454#include "util/OrxAssert.h"
    55 #include "Core.h"
    5655#include "LuaState.h"
    5756#include "PathConfig.h"
     
    7574                default: OrxAssert(false, "CEGUI log level out of range, inpect immediately!");
    7675            }
    77             OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
     76            OutputHandler::getOutStream(orxonoxLevel)
    7877                << "CEGUI: " << message << std::endl;
    7978
     
    121120        // set the log level according to ours (translate by subtracting 1)
    122121        ceguiLogger->setLoggingLevel(
    123             static_cast<LoggingLevel>(Core::getSoftDebugLevel(OutputHandler::LD_Logfile) - 1));
     122            static_cast<LoggingLevel>(OutputHandler::getInstance().getSoftDebugLevel("logFile") - 1));
    124123        this->ceguiLogger_ = ceguiLogger.release();
    125124
     
    127126        guiSystem_.reset(new System(guiRenderer_.get(), resourceProvider_, 0, scriptModule_.get()));
    128127
    129         // Initialise the basic lua code
     128        // Initialise the basic Lua code
    130129        rootFileInfo_ = Resource::getInfo("InitialiseGUI.lua", "GUI");
    131130        this->luaState_->doFile("InitialiseGUI.lua", "GUI", false);
     
    134133        guiSystem_->injectMousePosition(mousePosition.first, mousePosition.second);
    135134
    136         // Hide the mouse cursor unless playing in fullscreen mode
     135        // Hide the mouse cursor unless playing in full screen mode
    137136        if (!bFullScreen)
    138137            CEGUI::MouseCursor::getSingleton().hide();
     
    280279        code of the mouse button as it is used by CEGUI
    281280
    282         Simple convertion from mouse event code in Orxonox to the one used in CEGUI.
     281        Simple conversion from mouse event code in Orxonox to the one used in CEGUI.
    283282     */
    284283    static inline CEGUI::MouseButton convertButton(MouseButtonCode::ByEnum button)
  • code/trunk/src/libraries/core/GraphicsManager.cc

    r6075 r6105  
    409409            orxonoxLevel = 0;
    410410        }
    411         OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
     411        OutputHandler::getOutStream(orxonoxLevel)
    412412            << "Ogre: " << message << std::endl;
    413413    }
  • code/trunk/src/libraries/core/GraphicsManager.h

    r5929 r6105  
    106106
    107107        // config values
    108         std::string         ogreConfigFile_;           //!< ogre config file name
     108        std::string         ogreConfigFile_;           //!< ogre config filename
    109109        std::string         ogrePluginsDirectory_;     //!< Directory where the Ogre plugins are located
    110110        std::string         ogrePlugins_;              //!< Comma separated list of all plugins to load
    111         std::string         ogreLogFile_;              //!< log file name for Ogre log messages
    112         int                 ogreLogLevelTrivial_;      //!< Corresponding Orxonx debug level for LL_TRIVIAL
    113         int                 ogreLogLevelNormal_;       //!< Corresponding Orxonx debug level for LL_NORMAL
    114         int                 ogreLogLevelCritical_;     //!< Corresponding Orxonx debug level for LL_CRITICAL
     111        std::string         ogreLogFile_;              //!< log filename for Ogre log messages
     112        int                 ogreLogLevelTrivial_;      //!< Corresponding Orxonox debug level for LL_TRIVIAL
     113        int                 ogreLogLevelNormal_;       //!< Corresponding Orxonox debug level for LL_NORMAL
     114        int                 ogreLogLevelCritical_;     //!< Corresponding Orxonox debug level for LL_CRITICAL
    115115
    116116        // console commands
  • code/trunk/src/libraries/core/IOConsole.cc

    r6103 r6105  
    160160        // Erase input and status lines
    161161        this->cout_ << "\033[1G\033[J";
     162        // Move cursor to the bottom
     163        this->cout_ << "\033[" << this->statusLineWidths_.size() << 'B';
     164        // Scroll terminal to compensate for erased lines
     165        this->cout_ << "\033[" << this->statusLineWidths_.size() << 'T';
    162166
    163167        resetTerminalMode();
  • code/trunk/src/libraries/core/LuaState.cc

    r5929 r6105  
    182182    void LuaState::luaLog(unsigned int level, const std::string& message)
    183183    {
    184         OutputHandler::getOutStream().setOutputLevel(level) << message << std::endl;
     184        OutputHandler::getOutStream(level) << message << std::endl;
    185185    }
    186186
  • code/trunk/src/libraries/core/OrxonoxClass.cc

    r5929 r6105  
    3434#include "OrxonoxClass.h"
    3535
     36#include <cassert>
    3637#include "MetaObjectList.h"
    3738#include "Identifier.h"
     
    7273    void OrxonoxClass::destroy()
    7374    {
     75        assert(this); // Just in case someone tries to delete a NULL pointer
    7476        this->requestedDestruction_ = true;
    7577        if (this->referenceCount_ == 0)
  • code/trunk/src/libraries/core/OrxonoxClass.h

    r5929 r6105  
    4242#include <set>
    4343#include <vector>
     44
     45/**
     46@def CCOUT
     47    Acts almost exactly like COUT(x), but prepends "ClassName: "
     48*/
     49#define CCOUT(level) \
     50    COUT(level) << this->getIdentifier()->getName() << ": "
    4451
    4552namespace orxonox
  • code/trunk/src/libraries/core/PathConfig.cc

    r6021 r6105  
    263263        putenv(const_cast<char*>(("PATH=" + pathVariable + ";" + modulePath_.string()).c_str()));
    264264
     265        // Make sure the path exists, otherwise don't load modules
     266        if (!boost::filesystem::exists(modulePath_))
     267            return modulePaths;
     268
    265269        boost::filesystem::directory_iterator file(modulePath_);
    266270        boost::filesystem::directory_iterator end;
  • code/trunk/src/libraries/core/Shell.cc

    r5929 r6105  
    2323 *      Fabian 'x3n' Landau
    2424 *   Co-authors:
    25  *      ...
     25 *      Reto Grieder
    2626 *
    2727 */
     
    3030
    3131#include "util/OutputHandler.h"
     32#include "util/StringUtils.h"
     33#include "util/SubString.h"
    3234#include "CommandExecutor.h"
    3335#include "CoreIncludes.h"
    3436#include "ConfigValueIncludes.h"
    35 #include "Core.h"
    3637#include "ConsoleCommand.h"
    37 
    38 #define SHELL_UPDATE_LISTENERS(function) \
    39     for (std::list<ShellListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ) \
    40         (*(it++))->function()
    4138
    4239namespace orxonox
    4340{
    44     SetConsoleCommand(Shell, clearShell, true);
    45     SetConsoleCommand(Shell, history, true);
    46 
    4741    SetConsoleCommandShortcut(OutputHandler, log);
    4842    SetConsoleCommandShortcut(OutputHandler, error);
     
    5145    SetConsoleCommandShortcut(OutputHandler, debug);
    5246
    53     Shell* Shell::singletonPtr_s = 0;
    54 
    55     Shell::Shell()
    56     {
    57         int level = Core::getSoftDebugLevel(OutputHandler::LD_Shell);
    58         Core::setSoftDebugLevel(OutputHandler::LD_Shell, -1);
    59 
     47    Shell::Shell(const std::string& consoleName, bool bScrollable, bool bPrependOutputLevel)
     48        : OutputListener(consoleName)
     49        , inputBuffer_(new InputBuffer())
     50        , consoleName_(consoleName)
     51        , bPrependOutputLevel_(bPrependOutputLevel)
     52        , bScrollable_(bScrollable)
     53    {
    6054        RegisterRootObject(Shell);
    6155
     
    6458        this->historyPosition_ = 0;
    6559        this->historyOffset_ = 0;
    66         this->finishedLastLine_ = true;
    67         this->bAddOutputLevel_ = false;
    68 
    69         this->clearLines();
    70 
    71         this->inputBuffer_ = new InputBuffer();
     60        this->bFinishedLastLine_ = true;
     61
     62        this->clearOutput();
    7263        this->configureInputBuffer();
    73 
    74         this->outputBuffer_.registerListener(this);
    75         OutputHandler::getOutStream().setOutputBuffer(&this->outputBuffer_);
    7664
    7765        // Get a config file for the command history
     
    7967        ConfigFileManager::getInstance().setFilename(this->commandHistoryConfigFileType_, "commandHistory.ini");
    8068
     69        // Use a stringstream object to buffer the output and get it line by line in update()
     70        this->outputStream_ = &this->outputBuffer_;
     71
    8172        this->setConfigValues();
    8273
    83         Core::setSoftDebugLevel(OutputHandler::LD_Shell, level);
     74        // Get the previous output and add it to the Shell
     75        for (OutputHandler::OutputVectorIterator it = OutputHandler::getInstance().getOutputVectorBegin();
     76            it != OutputHandler::getInstance().getOutputVectorEnd(); ++it)
     77        {
     78            if (it->first <= this->getSoftDebugLevel())
     79            {
     80                this->outputBuffer_ << it->second;
     81                this->outputChanged(it->first);
     82            }
     83        }
     84
     85        // Register the shell as output listener
     86        OutputHandler::getInstance().registerOutputListener(this);
    8487    }
    8588
    8689    Shell::~Shell()
    8790    {
    88         OutputHandler::getOutStream().setOutputBuffer(0);
    89         if (this->inputBuffer_)
    90             this->inputBuffer_->destroy();
     91        OutputHandler::getInstance().unregisterOutputListener(this);
     92        this->inputBuffer_->destroy();
    9193    }
    9294
    9395    void Shell::setConfigValues()
    9496    {
    95         SetConfigValueGeneric(commandHistoryConfigFileType_, maxHistoryLength_, 100)
     97        SetConfigValue(maxHistoryLength_, 100)
    9698            .callback(this, &Shell::commandHistoryLengthChanged);
    97         SetConfigValueGeneric(commandHistoryConfigFileType_, historyOffset_, 0)
     99        SetConfigValue(historyOffset_, 0)
    98100            .callback(this, &Shell::commandHistoryOffsetChanged);
    99101        SetConfigValueVectorGeneric(commandHistoryConfigFileType_, commandHistory_, std::vector<std::string>());
     102
     103#ifdef ORXONOX_RELEASE
     104        const unsigned int defaultLevel = 1;
     105#else
     106        const unsigned int defaultLevel = 3;
     107#endif
     108        SetConfigValueGeneric(ConfigFileType::Settings, softDebugLevel_, "softDebugLevel" + this->consoleName_, "OutputHandler", defaultLevel)
     109            .description("The maximal level of debug output shown in the Shell");
     110        this->setSoftDebugLevel(this->softDebugLevel_);
    100111    }
    101112
     
    121132    {
    122133        this->inputBuffer_->registerListener(this, &Shell::inputChanged, true);
    123         this->inputBuffer_->registerListener(this, &Shell::execute, '\r', false);
    124         this->inputBuffer_->registerListener(this, &Shell::hintandcomplete, '\t', true);
    125         this->inputBuffer_->registerListener(this, &Shell::backspace, '\b', true);
    126         this->inputBuffer_->registerListener(this, &Shell::deletechar, KeyCode::Delete);
    127         this->inputBuffer_->registerListener(this, &Shell::exit, static_cast<char>(27), true);
    128         this->inputBuffer_->registerListener(this, &Shell::cursor_right, KeyCode::Right);
    129         this->inputBuffer_->registerListener(this, &Shell::cursor_left, KeyCode::Left);
    130         this->inputBuffer_->registerListener(this, &Shell::cursor_end, KeyCode::End);
    131         this->inputBuffer_->registerListener(this, &Shell::cursor_home, KeyCode::Home);
    132         this->inputBuffer_->registerListener(this, &Shell::history_up, KeyCode::Up);
    133         this->inputBuffer_->registerListener(this, &Shell::history_down, KeyCode::Down);
    134         this->inputBuffer_->registerListener(this, &Shell::scroll_up, KeyCode::PageUp);
    135         this->inputBuffer_->registerListener(this, &Shell::scroll_down, KeyCode::PageDown);
    136     }
    137 
    138     void Shell::clearShell()
    139     {
    140         Shell::getInstance().clearLines();
    141     }
    142 
     134        this->inputBuffer_->registerListener(this, &Shell::execute,         '\r',   false);
     135        this->inputBuffer_->registerListener(this, &Shell::execute,         '\n',   false);
     136        this->inputBuffer_->registerListener(this, &Shell::hintAndComplete, '\t',   true);
     137        this->inputBuffer_->registerListener(this, &Shell::backspace,       '\b',   true);
     138        this->inputBuffer_->registerListener(this, &Shell::backspace,       '\177', true);
     139        this->inputBuffer_->registerListener(this, &Shell::exit,            '\033', true); // escape
     140        this->inputBuffer_->registerListener(this, &Shell::deleteChar,      KeyCode::Delete);
     141        this->inputBuffer_->registerListener(this, &Shell::cursorRight,     KeyCode::Right);
     142        this->inputBuffer_->registerListener(this, &Shell::cursorLeft,      KeyCode::Left);
     143        this->inputBuffer_->registerListener(this, &Shell::cursorEnd,       KeyCode::End);
     144        this->inputBuffer_->registerListener(this, &Shell::cursorHome,      KeyCode::Home);
     145        this->inputBuffer_->registerListener(this, &Shell::historyUp,       KeyCode::Up);
     146        this->inputBuffer_->registerListener(this, &Shell::historyDown,     KeyCode::Down);
     147        if (this->bScrollable_)
     148        {
     149            this->inputBuffer_->registerListener(this, &Shell::scrollUp,    KeyCode::PageUp);
     150            this->inputBuffer_->registerListener(this, &Shell::scrollDown,  KeyCode::PageDown);
     151        }
     152        else
     153        {
     154            this->inputBuffer_->registerListener(this, &Shell::historySearchUp,   KeyCode::PageUp);
     155            this->inputBuffer_->registerListener(this, &Shell::historySearchDown, KeyCode::PageDown);
     156        }
     157    }
     158
     159    /*
    143160    void Shell::history()
    144161    {
     
    146163
    147164        for (unsigned int i = instance.historyOffset_; i < instance.commandHistory_.size(); ++i)
    148             instance.addLine(instance.commandHistory_[i], -1);
     165            instance.addOutputLine(instance.commandHistory_[i], -1);
    149166        for (unsigned int i =  0; i < instance.historyOffset_; ++i)
    150             instance.addLine(instance.commandHistory_[i], -1);
    151     }
     167            instance.addOutputLine(instance.commandHistory_[i], -1);
     168    }
     169    */
    152170
    153171    void Shell::registerListener(ShellListener* listener)
    154172    {
    155         this->listeners_.insert(this->listeners_.end(), listener);
     173        this->listeners_.push_back(listener);
    156174    }
    157175
     
    161179        {
    162180            if ((*it) == listener)
    163                 this->listeners_.erase(it++);
     181                it = this->listeners_.erase(it);
    164182            else
    165183                ++it;
     
    170188    {
    171189        this->inputBuffer_->setCursorPosition(cursor);
    172         SHELL_UPDATE_LISTENERS(cursorChanged);
    173     }
    174 
    175     void Shell::setInput(const std::string& input)
    176     {
    177         this->inputBuffer_->set(input);
    178         this->inputChanged();
    179     }
    180 
    181     void Shell::addLine(const std::string& line, int level)
    182     {
    183         int original_level = OutputHandler::getOutStream().getOutputLevel();
    184         OutputHandler::getOutStream().setOutputLevel(level);
    185 
    186         if (!this->finishedLastLine_)
    187             this->outputBuffer_ << std::endl;
    188 
    189         this->outputBuffer_ << line << std::endl;
    190         OutputHandler::getOutStream().setOutputLevel(original_level);
    191     }
    192 
    193     void Shell::clearLines()
    194     {
    195         this->lines_.clear();
    196         this->scrollIterator_ = this->lines_.begin();
     190        this->updateListeners<&ShellListener::cursorChanged>();
     191    }
     192
     193    void Shell::addOutputLine(const std::string& line, int level)
     194    {
     195        // Make sure we really only have one line per line (no new lines!)
     196        SubString lines(line, '\n');
     197        for (unsigned i = 0; i < lines.size(); ++i)
     198        {
     199            if (level <= this->softDebugLevel_)
     200                this->outputLines_.push_front(lines[i]);
     201            this->updateListeners<&ShellListener::lineAdded>();
     202        }
     203    }
     204
     205    void Shell::clearOutput()
     206    {
     207        this->outputLines_.clear();
     208        this->scrollIterator_ = this->outputLines_.begin();
    197209
    198210        this->scrollPosition_ = 0;
    199         this->finishedLastLine_ = true;
    200 
    201         SHELL_UPDATE_LISTENERS(linesChanged);
     211        this->bFinishedLastLine_ = true;
     212
     213        this->updateListeners<&ShellListener::linesChanged>();
    202214    }
    203215
     
    207219            return this->scrollIterator_;
    208220        else
    209             return this->lines_.begin();
     221            return this->outputLines_.begin();
    210222    }
    211223
    212224    std::list<std::string>::const_iterator Shell::getEndIterator() const
    213225    {
    214         return this->lines_.end();
     226        return this->outputLines_.end();
    215227    }
    216228
     
    231243    }
    232244
    233     void Shell::outputChanged()
    234     {
    235         std::string output;
    236         bool newline;
     245    void Shell::outputChanged(int level)
     246    {
     247        bool newline = false;
    237248        do
    238249        {
    239             newline = this->outputBuffer_.getLine(&output);
     250            std::string output;
     251            std::getline(this->outputBuffer_, output);
     252
     253            bool eof = this->outputBuffer_.eof();
     254            bool fail = this->outputBuffer_.fail();
     255            if (eof)
     256                this->outputBuffer_.flush();
     257            if (eof || fail)
     258                this->outputBuffer_.clear();
     259            newline = (!eof && !fail);
    240260
    241261            if (!newline && output == "")
    242262                break;
    243263
    244             if (this->finishedLastLine_)
     264            if (this->bFinishedLastLine_)
    245265            {
    246                 if (this->bAddOutputLevel_)
    247                     output.insert(0, 1, static_cast<char>(OutputHandler::getOutStream().getOutputLevel()));
    248 
    249                 this->lines_.insert(this->lines_.begin(), output);
     266                if (this->bPrependOutputLevel_)
     267                    output.insert(0, 1, static_cast<char>(level));
     268
     269                this->outputLines_.push_front(output);
    250270
    251271                if (this->scrollPosition_)
    252272                    this->scrollPosition_++;
    253273                else
    254                     this->scrollIterator_ = this->lines_.begin();
    255 
    256                 this->finishedLastLine_ = newline;
     274                    this->scrollIterator_ = this->outputLines_.begin();
     275
     276                this->bFinishedLastLine_ = newline;
    257277
    258278                if (!this->scrollPosition_)
    259279                {
    260                     SHELL_UPDATE_LISTENERS(lineAdded);
     280                    this->updateListeners<&ShellListener::lineAdded>();
    261281                }
    262282            }
    263283            else
    264284            {
    265                 (*this->lines_.begin()) += output;
    266                 this->finishedLastLine_ = newline;
    267                 SHELL_UPDATE_LISTENERS(onlyLastLineChanged);
     285                (*this->outputLines_.begin()) += output;
     286                this->bFinishedLastLine_ = newline;
     287                this->updateListeners<&ShellListener::onlyLastLineChanged>();
    268288            }
    269289
     
    271291    }
    272292
    273     void Shell::inputChanged()
    274     {
    275         SHELL_UPDATE_LISTENERS(inputChanged);
    276         SHELL_UPDATE_LISTENERS(cursorChanged);
    277     }
    278 
    279     void Shell::execute()
    280     {
    281         this->addToHistory(this->inputBuffer_->get());
    282         this->addLine(this->inputBuffer_->get(), 0);
    283 
    284         if (!CommandExecutor::execute(this->inputBuffer_->get()))
    285             this->addLine("Error: Can't execute \"" + this->inputBuffer_->get() + "\".", 1);
    286 
    287         this->clear();
    288     }
    289 
    290     void Shell::hintandcomplete()
    291     {
    292         this->inputBuffer_->set(CommandExecutor::complete(this->inputBuffer_->get()));
    293         this->addLine(CommandExecutor::hint(this->inputBuffer_->get()), -1);
    294 
    295         this->inputChanged();
    296     }
    297 
    298     void Shell::backspace()
    299     {
    300         this->inputBuffer_->removeBehindCursor();
    301         SHELL_UPDATE_LISTENERS(inputChanged);
    302         SHELL_UPDATE_LISTENERS(cursorChanged);
    303     }
    304 
    305     void Shell::deletechar()
    306     {
    307         this->inputBuffer_->removeAtCursor();
    308         SHELL_UPDATE_LISTENERS(inputChanged);
    309     }
    310 
    311     void Shell::clear()
     293    void Shell::clearInput()
    312294    {
    313295        this->inputBuffer_->clear();
    314296        this->historyPosition_ = 0;
    315         SHELL_UPDATE_LISTENERS(inputChanged);
    316         SHELL_UPDATE_LISTENERS(cursorChanged);
    317     }
    318 
    319     void Shell::cursor_right()
     297        this->updateListeners<&ShellListener::inputChanged>();
     298        this->updateListeners<&ShellListener::cursorChanged>();
     299    }
     300
     301    void Shell::setPromptPrefix(const std::string& str)
     302    {
     303    }
     304
     305
     306    // ##########################################
     307    // ###   InputBuffer callback functions   ###
     308    // ##########################################
     309
     310    void Shell::inputChanged()
     311    {
     312        this->updateListeners<&ShellListener::inputChanged>();
     313        this->updateListeners<&ShellListener::cursorChanged>();
     314    }
     315
     316    void Shell::execute()
     317    {
     318        this->addToHistory(this->inputBuffer_->get());
     319        this->updateListeners<&ShellListener::executed>();
     320
     321        if (!CommandExecutor::execute(this->inputBuffer_->get()))
     322            this->addOutputLine("Error: Can't execute \"" + this->inputBuffer_->get() + "\".", 1);
     323
     324        this->clearInput();
     325    }
     326
     327    void Shell::hintAndComplete()
     328    {
     329        this->inputBuffer_->set(CommandExecutor::complete(this->inputBuffer_->get()));
     330        this->addOutputLine(CommandExecutor::hint(this->inputBuffer_->get()), -1);
     331
     332        this->inputChanged();
     333    }
     334
     335    void Shell::backspace()
     336    {
     337        this->inputBuffer_->removeBehindCursor();
     338        this->updateListeners<&ShellListener::inputChanged>();
     339        this->updateListeners<&ShellListener::cursorChanged>();
     340    }
     341
     342    void Shell::exit()
     343    {
     344        if (this->inputBuffer_->getSize() > 0)
     345        {
     346            this->clearInput();
     347            return;
     348        }
     349
     350        this->clearInput();
     351        this->scrollPosition_ = 0;
     352        this->scrollIterator_ = this->outputLines_.begin();
     353
     354        this->updateListeners<&ShellListener::exit>();
     355    }
     356
     357    void Shell::deleteChar()
     358    {
     359        this->inputBuffer_->removeAtCursor();
     360        this->updateListeners<&ShellListener::inputChanged>();
     361    }
     362
     363    void Shell::cursorRight()
    320364    {
    321365        this->inputBuffer_->increaseCursor();
    322         SHELL_UPDATE_LISTENERS(cursorChanged);
    323     }
    324 
    325     void Shell::cursor_left()
     366        this->updateListeners<&ShellListener::cursorChanged>();
     367    }
     368
     369    void Shell::cursorLeft()
    326370    {
    327371        this->inputBuffer_->decreaseCursor();
    328         SHELL_UPDATE_LISTENERS(cursorChanged);
    329     }
    330 
    331     void Shell::cursor_end()
     372        this->updateListeners<&ShellListener::cursorChanged>();
     373    }
     374
     375    void Shell::cursorEnd()
    332376    {
    333377        this->inputBuffer_->setCursorToEnd();
    334         SHELL_UPDATE_LISTENERS(cursorChanged);
    335     }
    336 
    337     void Shell::cursor_home()
     378        this->updateListeners<&ShellListener::cursorChanged>();
     379    }
     380
     381    void Shell::cursorHome()
    338382    {
    339383        this->inputBuffer_->setCursorToBegin();
    340         SHELL_UPDATE_LISTENERS(cursorChanged);
    341     }
    342 
    343     void Shell::history_up()
     384        this->updateListeners<&ShellListener::cursorChanged>();
     385    }
     386
     387    void Shell::historyUp()
    344388    {
    345389        if (this->historyPosition_ < this->commandHistory_.size())
     
    350394    }
    351395
    352     void Shell::history_down()
     396    void Shell::historyDown()
    353397    {
    354398        if (this->historyPosition_ > 0)
     
    359403    }
    360404
    361     void Shell::scroll_up()
    362     {
    363         if (this->scrollIterator_ != this->lines_.end())
     405    void Shell::historySearchUp()
     406    {
     407        if (this->historyPosition_ == this->historyOffset_)
     408            return;
     409        unsigned int cursorPosition = this->getCursorPosition();
     410        std::string input_str(this->getInput().substr(0, cursorPosition)); // only search for the expression from the beginning of the inputline until the cursor position
     411        for (unsigned int newPos = this->historyPosition_ + 1; newPos <= this->historyOffset_; newPos++)
     412        {
     413            if (getLowercase(this->commandHistory_[this->historyOffset_ - newPos]).find(getLowercase(input_str)) == 0) // search case insensitive
     414            {
     415                this->historyPosition_ = newPos;
     416                this->inputBuffer_->set(this->getFromHistory());
     417                this->setCursorPosition(cursorPosition);
     418                return;
     419            }
     420        }
     421    }
     422
     423    void Shell::historySearchDown()
     424    {
     425        if (this->historyPosition_ == 0)
     426            return;
     427        unsigned int cursorPosition = this->getCursorPosition();
     428        std::string input_str(this->getInput().substr(0, cursorPosition)); // only search for the expression from the beginning
     429        for (unsigned int newPos = this->historyPosition_ - 1; newPos > 0; newPos--)
     430        {
     431            if (getLowercase(this->commandHistory_[this->historyOffset_ - newPos]).find(getLowercase(input_str)) == 0) // sear$
     432            {
     433                this->historyPosition_ = newPos;
     434                this->inputBuffer_->set(this->getFromHistory());
     435                this->setCursorPosition(cursorPosition);
     436                return;
     437            }
     438        }
     439    }
     440
     441    void Shell::scrollUp()
     442    {
     443        if (this->scrollIterator_ != this->outputLines_.end())
    364444        {
    365445            ++this->scrollIterator_;
    366446            ++this->scrollPosition_;
    367447
    368             SHELL_UPDATE_LISTENERS(linesChanged);
    369         }
    370     }
    371 
    372     void Shell::scroll_down()
    373     {
    374         if (this->scrollIterator_ != this->lines_.begin())
     448            this->updateListeners<&ShellListener::linesChanged>();
     449        }
     450    }
     451
     452    void Shell::scrollDown()
     453    {
     454        if (this->scrollIterator_ != this->outputLines_.begin())
    375455        {
    376456            --this->scrollIterator_;
    377457            --this->scrollPosition_;
    378458
    379             SHELL_UPDATE_LISTENERS(linesChanged);
    380         }
    381     }
    382 
    383     void Shell::exit()
    384     {
    385         if (this->inputBuffer_->getSize() > 0)
    386         {
    387             this->clear();
    388             return;
    389         }
    390 
    391         this->clear();
    392         this->scrollPosition_ = 0;
    393         this->scrollIterator_ = this->lines_.begin();
    394 
    395         SHELL_UPDATE_LISTENERS(exit);
     459            this->updateListeners<&ShellListener::linesChanged>();
     460        }
    396461    }
    397462}
  • code/trunk/src/libraries/core/Shell.h

    r5781 r6105  
    2323 *      Fabian 'x3n' Landau
    2424 *   Co-authors:
    25  *      ...
     25 *      Reto Grieder
    2626 *
    2727 */
     
    3232#include "CorePrereqs.h"
    3333
    34 #include <cassert>
    3534#include <list>
     35#include <sstream>
    3636#include <string>
    3737#include <vector>
    3838
    39 #include "util/OutputBuffer.h"
    40 #include "input/InputBuffer.h"
     39#include "util/OutputHandler.h"
    4140#include "OrxonoxClass.h"
    4241#include "ConfigFileManager.h"
     42#include "input/InputBuffer.h"
    4343
    4444namespace orxonox
     
    5757            virtual void inputChanged() {}
    5858            virtual void cursorChanged() {}
     59            virtual void executed() {}
    5960            virtual void exit() {}
    6061    };
    6162
    62     class _CoreExport Shell : public Singleton<Shell>, virtual public OrxonoxClass, public OutputBufferListener
     63
     64    class _CoreExport Shell : virtual public OrxonoxClass, public OutputListener
    6365    {
    64         friend class Singleton<Shell>;
    6566        public:
    66             Shell();
    67             virtual ~Shell();
     67            Shell(const std::string& consoleName, bool bScrollable, bool bPrependOutputLevel = false);
     68            ~Shell();
    6869
    69             static void clearShell();
    70             static void history();
    71 
    72             virtual void setConfigValues();
     70            void setConfigValues();
    7371            void commandHistoryOffsetChanged();
    7472            void commandHistoryLengthChanged();
     
    7977            inline InputBuffer* getInputBuffer()
    8078                { return this->inputBuffer_; }
    81             inline OutputBuffer& getOutputBuffer()
    82                 { return this->outputBuffer_; }
    8379
    8480            void setCursorPosition(unsigned int cursor);
     
    8682                { return this->inputBuffer_->getCursorPosition(); }
    8783
    88             void setInput(const std::string& input);
    89 
    90             inline void clearInput()
    91                 { this->setInput(""); }
    9284            inline std::string getInput() const
    9385                { return this->inputBuffer_->get(); }
     
    9688            std::list<std::string>::const_iterator getEndIterator() const;
    9789
    98             void addLine(const std::string& line, int level = 0);
    99             void clearLines();
     90            void addOutputLine(const std::string& line, int level = 0);
     91            void clearOutput();
    10092
    10193            inline unsigned int getNumLines() const
    102                 { return this->lines_.size(); }
     94                { return this->outputLines_.size(); }
    10395            inline unsigned int getScrollPosition() const
    10496                { return this->scrollPosition_; }
    10597
    106             inline void addOutputLevel(bool bAddOutputLevel)
    107                 { this->bAddOutputLevel_ = bAddOutputLevel; }
     98            inline const std::string& getPromptPrefix() const { return this->promptPrefix_; }
     99            void setPromptPrefix(const std::string& str);
    108100
    109101        private:
    110102            Shell(const Shell& other);
    111103
     104            void addToHistory(const std::string& command);
     105            std::string getFromHistory() const;
     106            void clearInput();
     107            // OutputListener
     108            void outputChanged(int level);
     109
    112110            void configureInputBuffer();
    113111
    114             void addToHistory(const std::string& command);
    115             std::string getFromHistory() const;
    116 
    117             virtual void outputChanged();
     112            // InputBuffer callbacks
    118113            void inputChanged();
    119114            void execute();
    120             void hintandcomplete();
     115            void hintAndComplete();
    121116            void backspace();
    122             void deletechar();
    123             void clear();
    124             void cursor_right();
    125             void cursor_left();
    126             void cursor_end();
    127             void cursor_home();
    128             void history_up();
    129             void history_down();
    130             void scroll_up();
    131             void scroll_down();
     117            void deleteChar();
     118            void cursorRight();
     119            void cursorLeft();
     120            void cursorEnd();
     121            void cursorHome();
     122            void historyUp();
     123            void historyDown();
     124            void historySearchUp();
     125            void historySearchDown();
     126            void scrollUp();
     127            void scrollDown();
    132128            void exit();
    133129
     130            template <void (ShellListener::*F)()>
     131            void updateListeners()
     132            {
     133                for (std::list<ShellListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); )
     134                    ((*(it++))->*F)();
     135            }
     136
    134137            std::list<ShellListener*> listeners_;
    135             InputBuffer* inputBuffer_;
    136             OutputBuffer outputBuffer_;
    137             bool finishedLastLine_;
    138             std::list<std::string> lines_;
     138            InputBuffer*              inputBuffer_;
     139            std::stringstream        outputBuffer_;
     140            bool                      bFinishedLastLine_;
     141            std::list<std::string>    outputLines_;
    139142            std::list<std::string>::const_iterator scrollIterator_;
    140             unsigned int scrollPosition_;
    141             std::vector<std::string> commandHistory_;
    142             unsigned int maxHistoryLength_;
    143             unsigned int historyPosition_;
    144             unsigned int historyOffset_;
    145             bool bAddOutputLevel_;
     143            unsigned int              scrollPosition_;
     144            unsigned int              historyPosition_;
     145            ConfigFileType            commandHistoryConfigFileType_;
    146146
    147             ConfigFileType commandHistoryConfigFileType_;
     147            std::string               promptPrefix_;
     148            const std::string         consoleName_;
     149            const bool                bPrependOutputLevel_;
     150            const bool                bScrollable_;
    148151
    149             static Shell* singletonPtr_s;
     152            // Config values
     153            unsigned int              maxHistoryLength_;
     154            unsigned int              historyOffset_;
     155            std::vector<std::string>  commandHistory_;
     156            int                       softDebugLevel_;
    150157    };
    151158}
  • code/trunk/src/libraries/core/input/InputBuffer.cc

    r5781 r6105  
    8080    void InputBuffer::setConfigValues()
    8181    {
    82         SetConfigValue(keyRepeatDeleay_, 0.4).description("Key repeat deleay of the input buffer");
     82        SetConfigValue(keyRepeatDeleay_, 0.4).description("Key repeat delay of the input buffer");
    8383        SetConfigValue(keyRepeatTime_, 0.022).description("Key repeat time of the input buffer");
    8484
     
    186186    void InputBuffer::processKey(const KeyEvent& evt)
    187187    {
     188        // Prevent disaster when switching applications
    188189        if (evt.isModifierDown(KeyboardModifier::Alt) && evt.getKeyCode() == KeyCode::Tab)
    189190            return;
     
    222223
    223224    /**
    224         @brief This update() function is called by the InputManager if the InputBuffer is active.
     225        @brief This update() function is called by the InputState if the InputBuffer is active.
    225226        @param dt Delta time
    226227    */
  • code/trunk/src/libraries/core/input/InputBuffer.h

    r5781 r6105  
    162162                { if (this->cursor_ > 0) { --this->cursor_; } }
    163163
     164            void buttonPressed(const KeyEvent& evt);
     165
    164166        private:
    165167            bool charIsAllowed(const char& input);
    166168
    167             void buttonPressed(const KeyEvent& evt);
    168169            void buttonHeld   (const KeyEvent& evt);
    169170            void processKey   (const KeyEvent& evt);
  • code/trunk/src/libraries/core/input/InputHandler.h

    r5781 r6105  
    7373            , modifiers_(0)
    7474        { }
     75        KeyEvent(KeyCode::ByEnum key, unsigned int text, int modifiers)
     76            : key_(key)
     77            , text_(text)
     78            , modifiers_(modifiers)
     79        { }
    7580        bool operator==(const KeyEvent& rhs) const
    7681            { return rhs.key_ == key_; }
     
    97102
    98103        Derive from this class if you wish to receive input events.
    99         But keep in mind that this is pointless wihtout first having an InputState.
     104        But keep in mind that this is pointless without first having an InputState.
    100105    @note
    101106        The definitions for the button events with the weird arguments are simply
    102         to avoid redunant code in the input devices.
     107        to avoid redundant code in the input devices.
    103108    */
    104109    class _CoreExport InputHandler
  • code/trunk/src/libraries/core/input/InputManager.cc

    r6021 r6105  
    190190            // Exception-safety
    191191            Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, oisInputManager_);
    192             CCOUT(ORX_DEBUG) << "Created OIS input manager." << std::endl;
     192            CCOUT(4) << "Created OIS input manager." << std::endl;
    193193
    194194            if (oisInputManager_->getNumberOfDevices(OIS::OISKeyboard) > 0)
     
    232232        }
    233233        else
    234             CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
     234            CCOUT(2) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
    235235    }
    236236
Note: See TracChangeset for help on using the changeset viewer.