/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010-2012 University of Bonn. All rights reserved. * Copyright (C) 2013 Frederik Heber. All rights reserved. * * * This file is part of MoleCuilder. * * MoleCuilder is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * MoleCuilder is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MoleCuilder. If not, see . */ /* * Registry.cpp * * Created on: Jan 7, 2010 * Author: crueger */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include "CodePatterns/Assert.hpp" #include "Actions/ActionRegistry.hpp" #include "Actions/OptionRegistry.hpp" #include "Actions/OptionTrait.hpp" #include "CodePatterns/Registry_impl.hpp" #include "GlobalListOfActions.hpp" #include "AllActionHeaders.hpp" #include #include #include using namespace MoleCuilder; // static entities bool ActionRegistry::completely_instatiated = false; /** Constructor for class ActionRegistry. */ ActionRegistry::ActionRegistry() { //std::cout << "ActionRegistry::ActionRegistry() called, instance is " << this << "." << std::endl; fillRegistry(); prepareAllMakroActions(); fillOptionRegistry(); completely_instatiated = true; } /** Destructor for class ActionRegistry. */ ActionRegistry::~ActionRegistry() { // first unregister all their options clearOptionRegistry(); // add all MakroActions: PLEASE adhere to the alphabetical ordering { MakroAction & presentAction = const_cast( dynamic_cast(getActionByName("molecular-dynamics"))); presentAction.unprepare(*this); } { MakroAction & presentAction = const_cast( dynamic_cast(getActionByName("optimize-structure"))); presentAction.unprepare(*this); } { MakroAction & presentAction = const_cast( dynamic_cast(getActionByName("subgraph-dissection"))); presentAction.unprepare(*this); } { MakroAction & presentAction = const_cast( dynamic_cast(getActionByName("translate-molecules"))); presentAction.unprepare(*this); } //std::cout << "ActionRegistry::~ActionRegistry() called, instance is " << this << "." << std::endl; cleanup(); } /** Instantiates each existing Action. * */ void ActionRegistry::fillRegistry() { #define instance_print(z,n,list) \ { \ Action * presentAction = new \ BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(n, list), Action) \ (); \ registerInstance(presentAction); \ } #define BOOST_PP_LOCAL_MACRO(n) instance_print(~, n, GLOBALLISTOFACTIONS) #define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(GLOBALLISTOFACTIONS))) #include BOOST_PP_LOCAL_ITERATE() #undef instance_print } void ActionRegistry::prepareAllMakroActions() { // now prepare each macro action that require presence of all primitive ones { MakroAction & presentAction = const_cast( dynamic_cast(getActionByName("subgraph-dissection"))); presentAction.prepare(*this); } { MakroAction & presentAction = const_cast( dynamic_cast(getActionByName("molecular-dynamics"))); presentAction.prepare(*this); } { MakroAction & presentAction = const_cast( dynamic_cast(getActionByName("optimize-structure"))); presentAction.prepare(*this); } { MakroAction & presentAction = const_cast( dynamic_cast(getActionByName("translate-molecules"))); presentAction.prepare(*this); } } /** Registers every existing Action's option with the OptionRegistry. * */ void ActionRegistry::fillOptionRegistry() const { for (const_iterator iter = getBeginIter(); iter != getEndIter(); ++iter) { // register with OptionRegistry Action ¤Action = *(iter->second); for (ActionTrait::options_const_iterator optioniter = currenAction.Traits.getBeginIter(); optioniter != currenAction.Traits.getEndIter(); ++optioniter) { // options may have been re-used by other Actions, so check beforehand whether adding is needed if (!OptionRegistry::getInstance().isOptionPresentByName((optioniter->first))) { OptionRegistry::getInstance().registerInstance(optioniter->second); } else { // if present, ASSERT that types coincide #ifndef NDEBUG OptionTrait const * const PresentOption = OptionRegistry::getInstance().getOptionByName(optioniter->first); #endif ASSERT(PresentOption->getType() == optioniter->second->getType(), ("Action::Action() - option to add "+ std::string(optioniter->first)+ " of Action "+ std::string(currenAction.getName())+ " is already present with different type: " +toString(PresentOption->getType())+" != "+toString(optioniter->second->getType()) ) ); ASSERT(PresentOption->getDefaultValue() == optioniter->second->getDefaultValue(), ("Action::Action() - option to add "+ std::string(optioniter->first)+ " of Action "+ std::string(currenAction.getName())+ " is already present with different default value: " +PresentOption->getDefaultValue()+" != "+optioniter->second->getDefaultValue() ) ); ASSERT(PresentOption->getShortForm() == optioniter->second->getShortForm(), ("Action::Action() - option to add "+ std::string(optioniter->first)+ " of Action "+ std::string(currenAction.getName())+ " is already present with different short form: " +PresentOption->getShortForm()+" != "+optioniter->second->getShortForm() ) ); } } } } /** Unregisters every existing Action's option from OptionRegistry. * */ void ActionRegistry::clearOptionRegistry() const { for (const_iterator iter = getBeginIter(); iter != getEndIter(); ++iter) { Action ¤Action = *(iter->second); for (ActionTrait::options_const_iterator optioniter = currenAction.Traits.getBeginIter(); optioniter != currenAction.Traits.getEndIter(); ++optioniter) { // unregister option if still registered if(OptionRegistry::getInstance().isOptionPresentByName((optioniter->first))) if (OptionRegistry::getInstance().getOptionByName((optioniter->first)) == optioniter->second) { OptionRegistry::getInstance().unregisterInstance(optioniter->second); } } } } /** Just passes on call to Registry::getByName(). * \param name name of Action * \return const ref to Action */ const Action& ActionRegistry::getActionByName(const std::string &name) { Action * const action = getByName(name); ASSERT( action != NULL, "ActionRegistry::getActionByName() - action "+name+" not present!"); return *action; } /** Just passes on call to Registry::isPresentByName(). * \param name name of Action * \return true - Action instance present, false - not */ bool ActionRegistry::isActionPresentByName(const std::string &name) const { return isPresentByName(name); } CONSTRUCT_REGISTRY(Action)