/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * builder_init.cpp * * Created on: Dec 15, 2010 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include #include "Graph/BondGraph.hpp" #include "config.hpp" #include "CodePatterns/Log.hpp" #include "molecule.hpp" #include "Element/periodentafel.hpp" #include "Tesselation/tesselationhelpers.hpp" #include "UIElements/UIFactory.hpp" #include "UIElements/Menu/MenuDescription.hpp" #include "UIElements/TextUI/TextUIFactory.hpp" #include "UIElements/CommandLineUI/CommandLineUIFactory.hpp" #include "UIElements/CommandLineUI/CommandLineParser.hpp" #ifdef USE_GUI_QT #include "UIElements/Qt4/QtUIFactory.hpp" #endif #include "UIElements/MainWindow.hpp" #include "UIElements/Dialog.hpp" //#include "Menu/ActionMenuItem.hpp" #include "CodePatterns/Verbose.hpp" #include "World.hpp" #include "Actions/ActionExceptions.hpp" #include "Actions/ActionHistory.hpp" #include "Actions/ActionRegistry.hpp" #include "RandomNumbers/RandomNumberDistributionFactory.hpp" #include "RandomNumbers/RandomNumberEngineFactory.hpp" #include "RandomNumbers/RandomNumberGeneratorFactory.hpp" #include "Parser/ChangeTracker.hpp" #include "Parser/FormatParserStorage.hpp" #include "UIElements/UIFactory.hpp" #include "UIElements/TextUI/TextUIFactory.hpp" #include "UIElements/CommandLineUI/CommandLineUIFactory.hpp" #include "UIElements/MainWindow.hpp" #include "UIElements/Dialog.hpp" #include "version.h" #include "builder_init.hpp" /** Print some initial information output the program. * */ void ProgramHeader() { // print version check and copyright notice cout << MOLECUILDERVERSION << endl; cout << "MoleCuilder comes with ABSOLUTELY NO WARRANTY; for details type" << endl; cout << "`molecuilder --warranty'." << endl; cout << "`MoleCuilder - to create and alter molecular systems." << endl; cout << "Copyright (C) 2010 University Bonn. All rights reserved." << endl; cout << endl; } /** General stuff to intialize before UI. * */ void initGeneral() { // while we are non interactive, we want to abort from asserts ASSERT_DO(Assert::Abort); ASSERT_HOOK(dumpMemory); ProgramHeader(); setVerbosity(1); // need to init the history before any action is created MoleCuilder::ActionHistory::init(); // from this moment on, we need to be sure to deeinitialize in the correct order // this is handled by the cleanup function atexit(cleanUp); } /** Initialize specific UIFactory. * * @param argc argument count * @param argv argument array */ void initUI(int argc, char **argv) { std::string BondGraphFileName("\n"); // Parse command line options and if present create respective UI // construct bond graph if (boost::filesystem::exists(BondGraphFileName)) { std::ifstream input(BondGraphFileName.c_str()); if ((input.good()) && (World::getInstance().getBondGraph()->LoadBondLengthTable(input))) { DoLog(0) && (Log() << Verbose(0) << "Bond length table loaded successfully." << endl); } else { DoeLog(1) && (eLog()<< Verbose(1) << "Bond length table loading failed." << endl); } input.close(); } // handle remaining arguments by CommandLineParser if (argc>1) { DoLog(0) && (Log() << Verbose(0) << "Setting UI to CommandLine." << endl); CommandLineParser::getInstance().InitializeCommandArguments(); CommandLineParser::getInstance().Run(argc,argv); UIFactory::registerFactory(new CommandLineUIFactory::description()); UIFactory::makeUserInterface("CommandLine"); } else { // In the interactive mode, we can leave the user the choice in case of error ASSERT_DO(Assert::Ask); #ifdef USE_GUI_QT DoLog(0) && (Log() << Verbose(0) << "Setting UI to Qt4." << endl); UIFactory::registerFactory(new QtUIFactory::description()); UIFactory::makeUserInterface("Qt4"); #else DoLog(0) && (Log() << Verbose(0) << "Setting UI to Text." << endl); cout << MOLECUILDERVERSION << endl; UIFactory::registerFactory(new TextUIFactory::description()); UIFactory::makeUserInterface("Text"); #endif } } /** Create MainWindow and displays. * I.e. here all the Actions are parsed and done. */ void doUI() { MainWindow *mainWindow = UIFactory::getInstance().makeMainWindow(); try { mainWindow->display(); } catch(ActionFailureException &e) { std::cerr << "Action " << *boost::get_error_info(e) << " has failed." << std::endl; World::getInstance().setExitFlag(5); } delete mainWindow; } /** In this function all dynamicly allocated member variables to static/global * variables are added to the ignore list of Memory/MemDebug. * * Use this to prevent their listing in the Memory::getState() at the end of the * program. Check with valgrind that truely no memory leak occurs! */ void AddStaticEntitiestoIgnoreList() { // zeroVec and unitVec are global variables (on the stack) but vectorContent // within is situated on the heap and has to be ignored Memory::ignore(zeroVec.get()); Memory::ignore(unitVec[0].get()); Memory::ignore(unitVec[1].get()); Memory::ignore(unitVec[2].get()); } /** Cleans all singleton instances in an orderly fashion. * C++ does not guarantee any specific sequence of removal of single instances * which have static/global variables. Some singletons depend on others hence we * acertain a specific ordering here, which is is used via the atexit() hook. */ void cleanUp() { RandomNumberDistributionFactory::purgeInstance(); RandomNumberEngineFactory::purgeInstance(); RandomNumberGeneratorFactory::purgeInstance(); FormatParserStorage::purgeInstance(); ChangeTracker::purgeInstance(); World::purgeInstance(); MenuDescription::purgeInstance(); UIFactory::purgeInstance(); ValueStorage::purgeInstance(); CommandLineParser::purgeInstance(); MoleCuilder::ActionRegistry::purgeInstance(); MoleCuilder::OptionRegistry::purgeInstance(); MoleCuilder::ActionHistory::purgeInstance(); // we have to remove these two static as otherwise their boost::shared_ptrs are still present MoleCuilder::Action::removeStaticStateEntities(); // put some static variables' dynamic contents on the Memory::ignore map to avoid their // admonishing lateron AddStaticEntitiestoIgnoreList(); logger::purgeInstance(); errorLogger::purgeInstance(); #ifdef LOG_OBSERVER cout << observerLog().getLog(); #endif Memory::getState(); } /** Dump current memory chunks. * */ void dumpMemory() { ofstream ost("molecuilder.memdump"); Memory::dumpMemory(ost); } /** Save the current World to output files and exit. * * @return retrieved from World::getExitFlag() */ int saveAll() { FormatParserStorage::getInstance().SaveAll(); ChangeTracker::getInstance().saveStatus(); int ExitFlag = World::getInstance().getExitFlag(); return (ExitFlag == 1 ? 0 : ExitFlag); }