| 1 | /* | 
|---|
| 2 | *   ORXONOX - the hottest 3D action shooter ever to exist | 
|---|
| 3 | *                    > www.orxonox.net < | 
|---|
| 4 | * | 
|---|
| 5 | * | 
|---|
| 6 | *   License notice: | 
|---|
| 7 | * | 
|---|
| 8 | *   This program is free software; you can redistribute it and/or | 
|---|
| 9 | *   modify it under the terms of the GNU General Public License | 
|---|
| 10 | *   as published by the Free Software Foundation; either version 2 | 
|---|
| 11 | *   of the License, or (at your option) any later version. | 
|---|
| 12 | * | 
|---|
| 13 | *   This program is distributed in the hope that it will be useful, | 
|---|
| 14 | *   but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 15 | *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
| 16 | *   GNU General Public License for more details. | 
|---|
| 17 | * | 
|---|
| 18 | *   You should have received a copy of the GNU General Public License | 
|---|
| 19 | *   along with this program; if not, write to the Free Software | 
|---|
| 20 | *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | 
|---|
| 21 | * | 
|---|
| 22 | *   Author: | 
|---|
| 23 | *      Fabian 'x3n' Landau | 
|---|
| 24 | *   Co-authors: | 
|---|
| 25 | *      Reto Grieder | 
|---|
| 26 | * | 
|---|
| 27 | */ | 
|---|
| 28 |  | 
|---|
| 29 | /** | 
|---|
| 30 | @defgroup ShellConsole Shell and console | 
|---|
| 31 | @ingroup Command | 
|---|
| 32 | */ | 
|---|
| 33 |  | 
|---|
| 34 | /** | 
|---|
| 35 | @file | 
|---|
| 36 | @ingroup Command ShellConsole | 
|---|
| 37 | @brief Declaration of the Shell and ShellListener classes. | 
|---|
| 38 | */ | 
|---|
| 39 |  | 
|---|
| 40 | #ifndef _Shell_H__ | 
|---|
| 41 | #define _Shell_H__ | 
|---|
| 42 |  | 
|---|
| 43 | #include "core/CorePrereqs.h" | 
|---|
| 44 |  | 
|---|
| 45 | #include <list> | 
|---|
| 46 | #include <sstream> | 
|---|
| 47 | #include <string> | 
|---|
| 48 | #include <vector> | 
|---|
| 49 |  | 
|---|
| 50 | #include "util/OutputHandler.h" | 
|---|
| 51 | #include "core/OrxonoxClass.h" | 
|---|
| 52 | #include "core/input/InputBuffer.h" | 
|---|
| 53 |  | 
|---|
| 54 | namespace orxonox | 
|---|
| 55 | { | 
|---|
| 56 | /** | 
|---|
| 57 | @brief An interface, used to get a notification if the state of the Shell changes. | 
|---|
| 58 | */ | 
|---|
| 59 | class _CoreExport ShellListener | 
|---|
| 60 | { | 
|---|
| 61 | friend class Shell; | 
|---|
| 62 |  | 
|---|
| 63 | public: | 
|---|
| 64 | virtual ~ShellListener() {} | 
|---|
| 65 |  | 
|---|
| 66 | private: | 
|---|
| 67 | virtual void linesChanged() {}          ///< Called if all output-lines have changed | 
|---|
| 68 | virtual void onlyLastLineChanged() {}   ///< Called if only the last output-line has changed | 
|---|
| 69 | virtual void lineAdded() {}             ///< Called if a new line was added to the output | 
|---|
| 70 | virtual void inputChanged() {}          ///< Called if the input has changed | 
|---|
| 71 | virtual void cursorChanged() {}         ///< Called if the cursor in the input line has changed | 
|---|
| 72 | virtual void executed() {}              ///< Called if a command from the input line was executed | 
|---|
| 73 | virtual void exit() {}                  ///< Called if the console should be closed | 
|---|
| 74 | }; | 
|---|
| 75 |  | 
|---|
| 76 |  | 
|---|
| 77 | /** | 
|---|
| 78 | @brief The Shell is the logical component of the console that displays output to the user and allows him to enter commands. | 
|---|
| 79 |  | 
|---|
| 80 | The Shell gathers output sent from OutputHandler by inheriting from OutputListener. | 
|---|
| 81 | The output-lines are stored in the shell, so they can be displayed in a graphical | 
|---|
| 82 | console. Additionally the Shell has an InputBuffer which is needed by the user to | 
|---|
| 83 | enter commands. | 
|---|
| 84 |  | 
|---|
| 85 | Different graphical consoles build upon a Shell, for example InGameConsole and IOConsole. | 
|---|
| 86 | */ | 
|---|
| 87 | class _CoreExport Shell : virtual public OrxonoxClass, public OutputListener | 
|---|
| 88 | { | 
|---|
| 89 | public: | 
|---|
| 90 | /// Defines the type of a line of text in the Shell - some types depend on the output level, others are of internal use. | 
|---|
| 91 | enum LineType | 
|---|
| 92 | { | 
|---|
| 93 | None    = OutputLevel::None, | 
|---|
| 94 | Warning = OutputLevel::Warning, | 
|---|
| 95 | Error   = OutputLevel::Error, | 
|---|
| 96 | Info    = OutputLevel::Info, | 
|---|
| 97 | Debug   = OutputLevel::Debug, | 
|---|
| 98 | Verbose = OutputLevel::Verbose, | 
|---|
| 99 | Ultra   = OutputLevel::Ultra, | 
|---|
| 100 | Input, | 
|---|
| 101 | Command, | 
|---|
| 102 | Hint | 
|---|
| 103 | }; | 
|---|
| 104 |  | 
|---|
| 105 | Shell(const std::string& consoleName, bool bScrollable); | 
|---|
| 106 | ~Shell(); | 
|---|
| 107 |  | 
|---|
| 108 | void setConfigValues(); | 
|---|
| 109 | void commandHistoryOffsetChanged(); | 
|---|
| 110 | void commandHistoryLengthChanged(); | 
|---|
| 111 |  | 
|---|
| 112 | void registerListener(ShellListener* listener); | 
|---|
| 113 | void unregisterListener(ShellListener* listener); | 
|---|
| 114 |  | 
|---|
| 115 | /// Returns the input buffer which is needed by the user to enter text into the shell. | 
|---|
| 116 | inline InputBuffer* getInputBuffer() | 
|---|
| 117 | { return this->inputBuffer_; } | 
|---|
| 118 |  | 
|---|
| 119 | void setCursorPosition(unsigned int cursor); | 
|---|
| 120 | /// Returns the current position of the cursor in the input buffer. | 
|---|
| 121 | inline unsigned int getCursorPosition() const | 
|---|
| 122 | { return this->inputBuffer_->getCursorPosition(); } | 
|---|
| 123 |  | 
|---|
| 124 | /// Returns the current content of the input buffer (the text which was entered by the user) | 
|---|
| 125 | inline const std::string& getInput() const | 
|---|
| 126 | { return this->inputBuffer_->get(); } | 
|---|
| 127 |  | 
|---|
| 128 | typedef std::list<std::pair<std::string, LineType> > LineList; | 
|---|
| 129 | LineList::const_iterator getNewestLineIterator() const; | 
|---|
| 130 | LineList::const_iterator getEndIterator() const; | 
|---|
| 131 |  | 
|---|
| 132 | void addOutput(const std::string& text, LineType type = None); | 
|---|
| 133 | void clearOutput(); | 
|---|
| 134 |  | 
|---|
| 135 | /// Returns the number of output-lines that are displayed in the shell. | 
|---|
| 136 | inline unsigned int getNumLines() const | 
|---|
| 137 | { return this->outputLines_.size(); } | 
|---|
| 138 | /// Returns the line which is currently viewed if the user scrolls through the older output-lines in the shell. | 
|---|
| 139 | inline unsigned int getScrollPosition() const | 
|---|
| 140 | { return this->scrollPosition_; } | 
|---|
| 141 |  | 
|---|
| 142 | /// Returns the cache size that is actually used in CommandExecutor, but placed here for better readability of the config file. | 
|---|
| 143 | static inline unsigned int getCacheSize() | 
|---|
| 144 | { return Shell::cacheSize_s; } | 
|---|
| 145 |  | 
|---|
| 146 | private: | 
|---|
| 147 | Shell(const Shell& other); | 
|---|
| 148 |  | 
|---|
| 149 | void addToHistory(const std::string& command); | 
|---|
| 150 | const std::string& getFromHistory() const; | 
|---|
| 151 | void clearInput(); | 
|---|
| 152 | // OutputListener | 
|---|
| 153 | void outputChanged(int level); | 
|---|
| 154 |  | 
|---|
| 155 | void configureInputBuffer(); | 
|---|
| 156 |  | 
|---|
| 157 | // InputBuffer callbacks | 
|---|
| 158 | void inputChanged(); | 
|---|
| 159 | void execute(); | 
|---|
| 160 | void hintAndComplete(); | 
|---|
| 161 | void backspace(); | 
|---|
| 162 | void deleteChar(); | 
|---|
| 163 | void cursorRight(); | 
|---|
| 164 | void cursorLeft(); | 
|---|
| 165 | void cursorEnd(); | 
|---|
| 166 | void cursorHome(); | 
|---|
| 167 | void historyUp(); | 
|---|
| 168 | void historyDown(); | 
|---|
| 169 | void historySearchUp(); | 
|---|
| 170 | void historySearchDown(); | 
|---|
| 171 | void scrollUp(); | 
|---|
| 172 | void scrollDown(); | 
|---|
| 173 | void exit(); | 
|---|
| 174 |  | 
|---|
| 175 | /// Iterates through all registered @ref ShellListener "shell listeners" and calls the function @a F. | 
|---|
| 176 | template <void (ShellListener::*F)()> | 
|---|
| 177 | void updateListeners() | 
|---|
| 178 | { | 
|---|
| 179 | for (std::list<ShellListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ) | 
|---|
| 180 | ((*(it++))->*F)(); | 
|---|
| 181 | } | 
|---|
| 182 |  | 
|---|
| 183 | std::list<ShellListener*> listeners_;           ///< The registered shell listeners | 
|---|
| 184 | InputBuffer*              inputBuffer_;         ///< The input buffer that is needed by the user to enter text | 
|---|
| 185 | std::stringstream         outputBuffer_;        ///< The output buffer that is used to retrieve lines of output from OutputListener | 
|---|
| 186 | bool                      bFinishedLastLine_;   ///< Stores if the most recent output-line was terminated with a line-break or if more output is expected for this line | 
|---|
| 187 | LineList                  outputLines_;         ///< A list of all output-lines that were displayed in the shell so far | 
|---|
| 188 | LineList::const_iterator  scrollIterator_;      ///< An iterator to an entry of the list of output-lines, changes if the user scrolls through the output in the shell | 
|---|
| 189 | unsigned int              scrollPosition_;      ///< The number of the line that is currently being referenced by scrollIterator_ | 
|---|
| 190 | unsigned int              historyPosition_;     ///< If the user scrolls through the history of entered commands (stored in commandHistory_), this contains the currently viewed history entry | 
|---|
| 191 |  | 
|---|
| 192 | const std::string         consoleName_;         ///< The name of this shell - used to define the name of the soft-debug-level config-value | 
|---|
| 193 | const bool                bScrollable_;         ///< If true, the user can scroll through the output-lines | 
|---|
| 194 |  | 
|---|
| 195 | // Config values | 
|---|
| 196 | unsigned int              maxHistoryLength_;    ///< The maximum number of saved commands | 
|---|
| 197 | unsigned int              historyOffset_;       ///< The command history is a circular buffer, this variable defines the current write-offset | 
|---|
| 198 | std::vector<std::string>  commandHistory_;      ///< The history of commands that were entered by the user | 
|---|
| 199 | int                       softDebugLevel_;      ///< The maximum level of output that is displayed in the shell (will be passed to OutputListener to filter output) | 
|---|
| 200 | static unsigned int       cacheSize_s;          ///< The maximum cache size of the CommandExecutor - this is stored here for better readability of the config file and because CommandExecutor is no OrxonoxClass | 
|---|
| 201 | }; | 
|---|
| 202 | } | 
|---|
| 203 |  | 
|---|
| 204 | #endif /* _Shell_H__ */ | 
|---|