| 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/output/BaseWriter.h" | 
|---|
| 51 | #include "core/Core.h" | 
|---|
| 52 |  | 
|---|
| 53 | namespace orxonox | 
|---|
| 54 | { | 
|---|
| 55 | /** | 
|---|
| 56 | @brief An interface, used to get a notification if the state of the Shell changes. | 
|---|
| 57 | */ | 
|---|
| 58 | class _CoreExport ShellListener | 
|---|
| 59 | { | 
|---|
| 60 | friend class Shell; | 
|---|
| 61 |  | 
|---|
| 62 | public: | 
|---|
| 63 | virtual ~ShellListener() {} | 
|---|
| 64 |  | 
|---|
| 65 | private: | 
|---|
| 66 | virtual void linesChanged() {}          ///< Called if all output-lines have changed | 
|---|
| 67 | virtual void lineAdded() {}             ///< Called if a new line was added to the output | 
|---|
| 68 | virtual void inputChanged() {}          ///< Called if the input has changed | 
|---|
| 69 | virtual void cursorChanged() {}         ///< Called if the cursor in the input line has changed | 
|---|
| 70 | virtual void executed() {}              ///< Called if a command from the input line was executed | 
|---|
| 71 | virtual void exit() {}                  ///< Called if the console should be closed | 
|---|
| 72 | }; | 
|---|
| 73 |  | 
|---|
| 74 |  | 
|---|
| 75 | /** | 
|---|
| 76 | @brief The Shell is the logical component of the console that displays output to the user and allows him to enter commands. | 
|---|
| 77 |  | 
|---|
| 78 | The Shell gathers output sent from OutputManager by inheriting from BaseWriter. | 
|---|
| 79 | The output-lines are stored in the shell, so they can be displayed in a graphical | 
|---|
| 80 | console. Additionally the Shell has an InputBuffer which is needed by the user to | 
|---|
| 81 | enter commands. | 
|---|
| 82 |  | 
|---|
| 83 | Different graphical consoles build upon a Shell, for example InGameConsole and IOConsole. | 
|---|
| 84 | */ | 
|---|
| 85 | class _CoreExport Shell : public BaseWriter, public DevModeListener | 
|---|
| 86 | { | 
|---|
| 87 | public: | 
|---|
| 88 | /// Defines the type of a line of text in the Shell - some types depend on the output level, others are of internal use. | 
|---|
| 89 | enum LineType | 
|---|
| 90 | { | 
|---|
| 91 | DebugOutput     = debug_output, | 
|---|
| 92 | Message         = message, | 
|---|
| 93 | UserError       = user_error, | 
|---|
| 94 | UserWarning     = user_warning, | 
|---|
| 95 | UserStatus      = user_status, | 
|---|
| 96 | UserInfo        = user_info, | 
|---|
| 97 | InternalError   = internal_error, | 
|---|
| 98 | InternalWarning = internal_warning, | 
|---|
| 99 | InternalStatus  = internal_status, | 
|---|
| 100 | InternalInfo    = internal_info, | 
|---|
| 101 | Verbose         = verbose, | 
|---|
| 102 | VerboseMore     = verbose_more, | 
|---|
| 103 | VerboseUltra    = verbose_ultra, | 
|---|
| 104 | Cout, | 
|---|
| 105 | Input, | 
|---|
| 106 | Command, | 
|---|
| 107 | Result, | 
|---|
| 108 | Hint | 
|---|
| 109 | }; | 
|---|
| 110 |  | 
|---|
| 111 | Shell(const std::string& consoleName = "", bool bScrollable = true); | 
|---|
| 112 | ~Shell(); | 
|---|
| 113 |  | 
|---|
| 114 | void setConfigValues(); | 
|---|
| 115 | void commandHistoryOffsetChanged(); | 
|---|
| 116 | void commandHistoryLengthChanged(); | 
|---|
| 117 |  | 
|---|
| 118 | void registerListener(ShellListener* listener); | 
|---|
| 119 | void unregisterListener(ShellListener* listener); | 
|---|
| 120 |  | 
|---|
| 121 | /// Returns the input buffer which is needed by the user to enter text into the shell. | 
|---|
| 122 | inline InputBuffer* getInputBuffer() | 
|---|
| 123 | { return this->inputBuffer_; } | 
|---|
| 124 |  | 
|---|
| 125 | void setCursorPosition(unsigned int cursor); | 
|---|
| 126 | unsigned int getCursorPosition() const; | 
|---|
| 127 |  | 
|---|
| 128 | const std::string& getInput() const; | 
|---|
| 129 |  | 
|---|
| 130 | typedef std::list<std::pair<std::string, LineType> > LineList; | 
|---|
| 131 | LineList::const_iterator getNewestLineIterator() const; | 
|---|
| 132 | LineList::const_iterator getEndIterator() const; | 
|---|
| 133 |  | 
|---|
| 134 | void addOutput(const std::string& text, LineType type = DebugOutput); | 
|---|
| 135 | void addLine(const std::string& line, LineType type = DebugOutput); | 
|---|
| 136 | void clearOutput(); | 
|---|
| 137 |  | 
|---|
| 138 | /// Returns the number of output-lines that are displayed in the shell. | 
|---|
| 139 | inline unsigned int getNumLines() const | 
|---|
| 140 | { return this->outputLines_.size(); } | 
|---|
| 141 | /// Returns the line which is currently viewed if the user scrolls through the older output-lines in the shell. | 
|---|
| 142 | inline unsigned int getScrollPosition() const | 
|---|
| 143 | { return this->scrollPosition_; } | 
|---|
| 144 |  | 
|---|
| 145 | /// Returns the cache size that is actually used in CommandExecutor, but placed here for better readability of the config file. | 
|---|
| 146 | static inline unsigned int getCacheSize() | 
|---|
| 147 | { return Shell::cacheSize_s; } | 
|---|
| 148 |  | 
|---|
| 149 | private: | 
|---|
| 150 | Shell(const Shell& other); | 
|---|
| 151 |  | 
|---|
| 152 | // DevModeListener | 
|---|
| 153 | void devModeChanged(bool value); | 
|---|
| 154 |  | 
|---|
| 155 | void addToHistory(const std::string& command); | 
|---|
| 156 | const std::string& getFromHistory() const; | 
|---|
| 157 | void clearInput(); | 
|---|
| 158 | // BaseWriter | 
|---|
| 159 | virtual void printLine(const std::string& line, OutputLevel level); | 
|---|
| 160 |  | 
|---|
| 161 | void configureInputBuffer(); | 
|---|
| 162 |  | 
|---|
| 163 | // InputBuffer callbacks | 
|---|
| 164 | void inputChanged(); | 
|---|
| 165 | void execute(); | 
|---|
| 166 | void hintAndComplete(); | 
|---|
| 167 | void backspace(); | 
|---|
| 168 | void deleteChar(); | 
|---|
| 169 | void cursorRight(); | 
|---|
| 170 | void cursorLeft(); | 
|---|
| 171 | void cursorEnd(); | 
|---|
| 172 | void cursorHome(); | 
|---|
| 173 | void historyUp(); | 
|---|
| 174 | void historyDown(); | 
|---|
| 175 | void historySearchUp(); | 
|---|
| 176 | void historySearchDown(); | 
|---|
| 177 | void scrollUp(); | 
|---|
| 178 | void scrollDown(); | 
|---|
| 179 | void exit(); | 
|---|
| 180 |  | 
|---|
| 181 | /// Iterates through all registered @ref ShellListener "shell listeners" and calls the function @a F. | 
|---|
| 182 | template <void (ShellListener::*F)()> | 
|---|
| 183 | void updateListeners() | 
|---|
| 184 | { | 
|---|
| 185 | for (std::list<ShellListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ) | 
|---|
| 186 | ((*(it++))->*F)(); | 
|---|
| 187 | } | 
|---|
| 188 |  | 
|---|
| 189 | std::list<ShellListener*> listeners_;           ///< The registered shell listeners | 
|---|
| 190 | InputBuffer*              inputBuffer_;         ///< The input buffer that is needed by the user to enter text | 
|---|
| 191 | LineList                  outputLines_;         ///< A list of all output-lines that were displayed in the shell so far | 
|---|
| 192 | 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 | 
|---|
| 193 | unsigned int              scrollPosition_;      ///< The number of the line that is currently being referenced by scrollIterator_ | 
|---|
| 194 | unsigned int              historyPosition_;     ///< If the user scrolls through the history of entered commands (stored in commandHistory_), this contains the currently viewed history entry | 
|---|
| 195 | const bool                bScrollable_;         ///< If true, the user can scroll through the output-lines | 
|---|
| 196 |  | 
|---|
| 197 | // Config values | 
|---|
| 198 | unsigned int              maxHistoryLength_;    ///< The maximum number of saved commands | 
|---|
| 199 | unsigned int              historyOffset_;       ///< The command history is a circular buffer, this variable defines the current write-offset | 
|---|
| 200 | std::vector<std::string>  commandHistory_;      ///< The history of commands that were entered by the user | 
|---|
| 201 | 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 not configurable | 
|---|
| 202 | }; | 
|---|
| 203 | } | 
|---|
| 204 |  | 
|---|
| 205 | #endif /* _Shell_H__ */ | 
|---|