diff --git a/library/Console-linux.cpp b/library/Console-linux.cpp index 125b6cc4b..b47e1274c 100644 --- a/library/Console-linux.cpp +++ b/library/Console-linux.cpp @@ -76,6 +76,7 @@ const char * ANSI_LIGHTBLUE = "\033[01;34m"; const char * ANSI_LIGHTMAGENTA = "\033[01;35m"; const char * ANSI_LIGHTCYAN = "\033[01;36m"; const char * ANSI_WHITE = "\033[01;37m"; +const char * RESETCOLOR = "\033[0m"; const char * getANSIColor(const int c) { @@ -106,6 +107,12 @@ void Console::color(int index) dfout << getANSIColor(index); } +void Console::reset_color( void ) +{ + dfout << RESETCOLOR; +} + + void Console::cursor(bool enable) { if(enable) diff --git a/library/Console-windows.cpp b/library/Console-windows.cpp index 63035c6df..3655b66da 100644 --- a/library/Console-windows.cpp +++ b/library/Console-windows.cpp @@ -50,6 +50,7 @@ duthomhas::stdiobuf * stream_o = 0; HANDLE g_hConsoleOut; // Handle to debug console HWND ConsoleWindow; +WORD default_attributes; // FIXME: prime candidate for being a singleton... indeed. Console::Console() @@ -68,6 +69,7 @@ Console::Console() // set the screen buffer to be big enough to let us scroll text GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo); + default_attributes = coninfo.wAttributes; coninfo.dwSize.Y = MAX_CONSOLE_LINES; // How many lines do you want to have in the console buffer SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize); @@ -119,6 +121,13 @@ void Console::color(int index) SetConsoleTextAttribute(hConsole, index); } +void Console::reset_color( void ) +{ + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(hConsole, default_attributes); +} + + void Console::cursor(bool enable) { if(enable) diff --git a/library/Core.cpp b/library/Core.cpp index 0ae8b5edc..59d84182c 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -66,6 +66,11 @@ int fIOthread(void * iodata) { Core * core = ((IODATA*) iodata)->core; PluginManager * plug_mgr = ((IODATA*) iodata)->plug_mgr; + if(plug_mgr == 0) + { + dfout << "Something horrible happened to the plugin manager in Core's constructor..." << std::endl; + return 0; + } fprintf(dfout_C,"DFHack is ready. Have a nice day! Type in '?' or 'help' for help.\n"); //dfterm << << endl; int clueless_counter = 0; @@ -156,10 +161,11 @@ Core::Core() plug_mgr = new PluginManager(this); // look for all plugins, // create IO thread - IODATA temp; - temp.core = this; - temp.plug_mgr = plug_mgr; - DFThread * IO = SDL_CreateThread(fIOthread, (void *) &temp); + IODATA *temp = new IODATA; + temp->core = this; + temp->plug_mgr = plug_mgr; + DFThread * IO = SDL_CreateThread(fIOthread, (void *) temp); + delete temp; // and let DF do its thing. }; diff --git a/library/PluginManager.cpp b/library/PluginManager.cpp index bfee5423d..072c6bae3 100644 --- a/library/PluginManager.cpp +++ b/library/PluginManager.cpp @@ -119,7 +119,10 @@ Plugin::Plugin(Core * core, const std::string & file) Plugin::~Plugin() { if(loaded) + { + plugin_shutdown(&Core::getInstance()); ClosePlugin(plugin_lib); + } } bool Plugin::isLoaded() @@ -143,9 +146,10 @@ PluginManager::PluginManager(Core * core) if(hasEnding(filez[i],searchstr)) { Plugin * p = new Plugin(core, path + filez[i]); - for(int j = 0; j < p->commands.size();j++) + Plugin & pr = *p; + for(int j = 0; j < pr.size();j++) { - commands[p->commands[j].name] = &p->commands[j]; + commands[p->commands[j].name] = &pr[j]; } all_plugins.push_back(p); } @@ -154,28 +158,32 @@ PluginManager::PluginManager(Core * core) PluginManager::~PluginManager() { - + commands.clear(); + for(int i = 0; i < all_plugins.size();i++) + { + delete all_plugins[i]; + } + all_plugins.clear(); } + Plugin *PluginManager::getPluginByName (const std::string & name) { - + for(int i = 0; i < all_plugins.size(); i++) + { + if(name == all_plugins[i]->name) + return all_plugins[i]; + } + return 0; } + +// FIXME: handle name collisions... command_result PluginManager::InvokeCommand( std::string & command, std::vector & parameters) { Core * c = &Core::getInstance(); - map ::iterator iter = commands.find(command); + map ::iterator iter = commands.find(command); if(iter != commands.end()) { return iter->second->function(c,parameters); } return CR_NOT_IMPLEMENTED; } -/* -for (map ::iterator iter = plugins.begin(); iter != plugins.end(); iter++) -{ - dfout << iter->first << endl; -} -*/ -/* - -*/ \ No newline at end of file diff --git a/library/include/dfhack/Console.h b/library/include/dfhack/Console.h index 4213cb2ac..faa29c866 100644 --- a/library/include/dfhack/Console.h +++ b/library/include/dfhack/Console.h @@ -44,6 +44,8 @@ namespace DFHack void gotoxy(int x, int y); /// Set color (ANSI color number) void color(int index); + /// Reset color to default + void reset_color(void); /// Enable or disable the caret/cursor void cursor(bool enable = true); /// Waits given number of milliseconds before continuing. diff --git a/library/include/dfhack/PluginManager.h b/library/include/dfhack/PluginManager.h index 76059a361..8838d399e 100644 --- a/library/include/dfhack/PluginManager.h +++ b/library/include/dfhack/PluginManager.h @@ -67,11 +67,14 @@ namespace DFHack Plugin(DFHack::Core* core, const std::string& file); ~Plugin(); bool isLoaded (); - /* - bool Load (); - bool Unload (); - std::string Status (); - */ + const PluginCommand& operator[] (std::size_t index) + { + return commands[index]; + }; + std::size_t size() + { + return commands.size(); + } private: std::vector commands; std::string filename; @@ -89,8 +92,19 @@ namespace DFHack ~PluginManager(); Plugin *getPluginByName (const std::string & name); command_result InvokeCommand( std::string & command, std::vector & parameters); + //FIXME: how do we deal with errors inside DF? Unhandled exceptions are deadly. + const Plugin* operator[] (std::size_t index) + { + if(index >= all_plugins.size()) + return 0; + return all_plugins[index]; + }; + std::size_t size() + { + return all_plugins.size(); + } private: - std::map commands; + std::map commands; std::vector all_plugins; std::string plugin_path; }; diff --git a/plugins/kittens.cpp b/plugins/kittens.cpp index 0261bc73a..8e9da7d09 100644 --- a/plugins/kittens.cpp +++ b/plugins/kittens.cpp @@ -61,6 +61,8 @@ DFhackCExport command_result kittens (Core * c, vector & parameters) if(shutdown_flag) { final_flag = true; + c->con->reset_color(); + dfout << std::endl << "MEOW!" << std::endl << std::flush; return CR_OK; } con->color(color); diff --git a/plugins/reveal.cpp b/plugins/reveal.cpp index cd5ddd5c2..e6ff7064f 100644 --- a/plugins/reveal.cpp +++ b/plugins/reveal.cpp @@ -27,7 +27,6 @@ bool revealed = false; DFhackCExport command_result reveal(DFHack::Core * c, std::vector & params); DFhackCExport command_result unreveal(DFHack::Core * c, std::vector & params); DFhackCExport command_result revealtoggle(DFHack::Core * c, std::vector & params); -//DFhackCExport command_result revealclear(DFHack::Core * c, std::vector & params); DFhackCExport const char * plugin_name ( void ) { @@ -40,7 +39,6 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector commands.push_back(PluginCommand("reveal","Reveal the map.",reveal)); commands.push_back(PluginCommand("unreveal","Revert the map to its previous state.",unreveal)); commands.push_back(PluginCommand("revealtoggle","Reveal/unreveal depending on state.",revealtoggle)); - //commands.push_back(PluginCommand("revealclear","Reset the reveal tool.",revealclear)); return CR_OK; } @@ -68,7 +66,6 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector & return CR_FAILURE; } - dfout << "Revealing, please wait..." << std::endl; Maps->getSize(x_max,y_max,z_max); hidesaved.reserve(x_max * y_max * z_max); for(uint32_t x = 0; x< x_max;x++) @@ -103,8 +100,7 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector & c->Resume(); dfout << "Map revealed. The game has been paused for you." << std::endl; dfout << "Unpausing can unleash the forces of hell!" << std::endl; - dfout << "Saving will make this state permanent. Don't do it." << std::endl << std::endl; - dfout << "Run 'reveal' again to revert to previous state." << std::endl; + dfout << "Run 'unreveal' to revert to previous state." << std::endl; return CR_OK; } @@ -139,7 +135,6 @@ DFhackCExport command_result unreveal(DFHack::Core * c, std::vector // FIXME: add more sanity checks / MAP ID - dfout << "Unrevealing... please wait." << std::endl; for(size_t i = 0; i < hidesaved.size();i++) { hideblock & hb = hidesaved[i]; @@ -153,6 +148,7 @@ DFhackCExport command_result unreveal(DFHack::Core * c, std::vector // give back memory. hidesaved.clear(); revealed = false; + dfout << "Map hidden!" << std::endl; c->Resume(); return CR_OK; }