/* https://github.com/peterix/dfhack Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #pragma once #include "Pragma.h" #include "Export.h" #include "ColorText.h" #include #include #include #include #include namespace tthread { class mutex; class recursive_mutex; class condition_variable; class thread; } namespace DFHack { class CommandHistory { public: CommandHistory(std::size_t capacity = 100) { this->capacity = capacity; } bool load (const char * filename) { std::string reader; std::ifstream infile(filename); if(infile.bad()) return false; std::string s; while(std::getline(infile, s)) { if(s.empty()) continue; history.push_back(s); } return true; } bool save (const char * filename) { std::ofstream outfile (filename); //fprintf(stderr,"Save: Initialized stream\n"); if(outfile.bad()) return false; //fprintf(stderr,"Save: Iterating...\n"); for(auto iter = history.begin();iter < history.end(); iter++) { //fprintf(stderr,"Save: Dumping %s\n",(*iter).c_str()); outfile << *iter << std::endl; //fprintf(stderr,"Save: Flushing\n"); outfile.flush(); } //fprintf(stderr,"Save: Closing\n"); outfile.close(); //fprintf(stderr,"Save: Done\n"); return true; } /// add a command to the history void add(const std::string& command) { // if current command = last in history -> do not add. Always add if history is empty. if(!history.empty() && history.front() == command) return; history.push_front(command); if(history.size() > capacity) history.pop_back(); } /// clear the command history void clear() { history.clear(); } /// get current history size std::size_t size() { return history.size(); } /// get pointer to a particular history item std::string & operator[](std::size_t index) { assert(index < history.size()); return history[index]; } void remove( void ) { history.pop_front(); } private: std::size_t capacity; std::deque history; }; class Private; class DFHACK_EXPORT Console : public color_ostream { protected: virtual void begin_batch(); virtual void add_text(color_value color, const std::string &text); virtual void end_batch(); virtual void flush_proxy(); public: ///ctor, NOT thread-safe Console(); ///dtor, NOT thread-safe ~Console(); /// initialize the console. NOT thread-safe bool init( bool sharing ); /// shutdown the console. NOT thread-safe bool shutdown( void ); /// Clear the console, along with its scrollback void clear(); /// Position cursor at x,y. 1,1 = top left corner void gotoxy(int x, int y); /// Enable or disable the caret/cursor void cursor(bool enable = true); /// Waits given number of milliseconds before continuing. void msleep(unsigned int msec); /// get the current number of columns int get_columns(void); /// get the current number of rows int get_rows(void); /// beep. maybe? //void beep (void); /// A simple line edit (raw mode) int lineedit(const std::string& prompt, std::string& output, CommandHistory & history ); bool isInited (void) { return inited; }; bool is_console() { return true; } private: Private * d; tthread::recursive_mutex * wlock; bool inited; }; }