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