/* * Reaction_impl.hpp * * Created on: Oct 13, 2011 * Author: heber */ /** These macros define the following functions, necessary but repetitive for * every Action: * -# Dialog* fillDialog() * -# action command (e.g. AnalysisMolecularVolume() ) * -# void getParametersfromValuStorage() * -# struct Action...Parameters * * For this, the user has the define the following values, each with * parenthesis, for the values/parameters the action needs * -# paramtypes, e.g. (int)(double) * -# paramtokens, e.g. ("Z")("length") * -# paramreferences, e.g. (Z)(length) * and for additional values/parameters to save in the state * -# statetypes, e.g. (int)(double) * -# statereferences, e.g. (Z)(length) * and the name and category of the action * -# CATEGORY, e.g. Analysis * -# ACTIONNAME, e.g. MolecularVolume */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include // some derived names: if CATEGORY is not given, we don't prefix with it #ifdef CATEGORY #define REACTION BOOST_PP_CAT(CATEGORY, BOOST_PP_CAT(ACTIONNAME, Action)) #define COMMAND BOOST_PP_CAT(CATEGORY, ACTIONNAME) #define STATE BOOST_PP_CAT(CATEGORY, BOOST_PP_CAT(ACTIONNAME, State)) #define PARAMS BOOST_PP_CAT(CATEGORY, BOOST_PP_CAT(ACTIONNAME, Parameters)) #else #define REACTION BOOST_PP_CAT(ACTIONNAME, Action) #define COMMAND ACTIONNAME #define STATE BOOST_PP_CAT(ACTIONNAME, State) #define PARAMS BOOST_PP_CAT(ACTIONNAME, Parameters) #endif // check if no lists given #ifndef paramtypes #define MAXPARAMTYPES 0 #else #define MAXPARAMTYPES BOOST_PP_SEQ_SIZE(paramtypes) #endif #ifndef statetypes #define MAXSTATETYPES 0 #else #define MAXSTATETYPES BOOST_PP_SEQ_SIZE(statetypes) #endif // check user has given name and category #ifndef ACTIONNAME ERROR: No "ACTIONNAME" defined in: __FILE__ #endif // calculate numbers and check whether all have same size #ifdef paramtokens BOOST_PP_ASSERT_MSG(BOOST_PP_EQUAL(MAXPARAMTYPES, BOOST_PP_SEQ_SIZE(paramtokens)),\ ERROR: There are not the same number of "paramtokens" and "paramtypes" in: __FILE__ \ ) #endif #ifdef paramreferences BOOST_PP_ASSERT_MSG(BOOST_PP_EQUAL(MAXPARAMTYPES, BOOST_PP_SEQ_SIZE(paramreferences)),\ ERROR: There are not the same number of "paramtokens" and "paramreferences" in: __FILE__ \ ) #endif #ifdef statetypes BOOST_PP_ASSERT_MSG(BOOST_PP_EQUAL(MAXSTATETYPES, BOOST_PP_SEQ_SIZE(statereferences)),\ ERROR: There are not the same number of "statetypes" and "statereferences" in: __FILE__ \ ) #endif // set the return type #ifndef returntype BOOST_PP_ASSERT_MSG(0,\ ERROR: No returntype is defined in __FILE__ \ ) #endif #define RETURNTYPE returntype // print a list of type ref followed by a separator, i.e. "int i;" #define initialiser_print(z,n,initialiserlist) \ BOOST_PP_SEQ_ELEM(n, initialiserlist) \ (BOOST_PP_CAT(_, BOOST_PP_SEQ_ELEM(n, initialiserlist))), // print a list of ref(_ref) followed by a separator, i.e. "id(_id)," #define type_print(z,n,TYPELIST, VARLIST, separator) \ BOOST_PP_SEQ_ELEM(n, TYPELIST) \ BOOST_PP_SEQ_ELEM(n, VARLIST)\ separator // print a list of type ref followed, i.e. "int i, double position" #define type_list(z,n,TYPELIST,VARLIST) \ BOOST_PP_COMMA_IF(n)\ BOOST_PP_SEQ_ELEM(n, TYPELIST) \ BOOST_PP_SEQ_ELEM(n, VARLIST) // prints dialog->query calls for paramtypes with tokens #define dialog_print(z,n,unused) \ dialog->query<\ BOOST_PP_SEQ_ELEM(n, paramtypes)\ >(\ BOOST_PP_SEQ_ELEM(n, paramtokens)\ , Traits.getDescription()\ ); // prints set/queryCurrentValue (command) for paramreferences and paramtokens #define value_print(z,n,command, prefix) \ ValueStorage::getInstance(). command (\ BOOST_PP_SEQ_ELEM(n, paramtokens)\ , \ prefix\ BOOST_PP_SEQ_ELEM(n, paramreferences)\ ); // prints set/queryCurrentValue (command) for paramreferences and paramtokens #define valuetype_print(z,n,command, prefix) \ ValueStorage::getInstance(). command< \ BOOST_PP_SEQ_ELEM(n, paramtypes) \ > (\ BOOST_PP_SEQ_ELEM(n, paramtokens)\ , \ prefix\ BOOST_PP_SEQ_ELEM(n, paramreferences)\ ); #define stringtype std::string #define type2string(s, data, elem) \ stringtype #include "Actions/ActionRegistry.hpp" //#include "Actions/ActionTraits.hpp" #include "UIElements/Dialog.hpp" #ifdef paramtokens #define statenecessary 1 #endif #ifndef statetokens #define statenecessary 1 #endif namespace MoleCuilder { // =========== constructor =========== REACTION::REACTION () : Reaction< RETURNTYPE >(ActionTraits< REACTION >(), false) {} // =========== destructor =========== REACTION::~REACTION () { //std::cout << "Action REACTION is being destroyed." << std::endl; } // =========== fill a dialog =========== Dialog* REACTION::fillDialog(Dialog *dialog) { ASSERT(dialog,"No Dialog given when filling actionname's dialog"); #if BOOST_PP_EQUAL(MAXPARAMTYPES,0) dialog->queryEmpty(TOKEN, Traits.getDescription()); #else #define BOOST_PP_LOCAL_MACRO(n) dialog_print(~, n, ~) #define BOOST_PP_LOCAL_LIMITS (0, MAXPARAMTYPES-1) #include BOOST_PP_LOCAL_ITERATE() #endif return dialog; }; // =========== command for calling action directly =========== RETURNTYPE COMMAND( #if defined paramtypes && defined paramreferences #define BOOST_PP_LOCAL_MACRO(n) type_list(~, n, paramtypes, paramreferences) #define BOOST_PP_LOCAL_LIMITS (0, MAXPARAMTYPES-1) #include BOOST_PP_LOCAL_ITERATE() #endif ) { Action *ToCall = ActionRegistry::getInstance().getActionByName( TOKEN ); //->clone(params); //REACTION::PARAMS params; #if BOOST_PP_NOT_EQUAL(MAXPARAMTYPES,0) #define BOOST_PP_LOCAL_MACRO(n) value_print(~, n, setCurrentValue, ) #define BOOST_PP_LOCAL_LIMITS (0, MAXPARAMTYPES-1) #include BOOST_PP_LOCAL_ITERATE() #endif ToCall->call(Action::NonInteractive); return static_cast *>(ToCall)->getResult(); }; RETURNTYPE BOOST_PP_CAT( COMMAND, _stringargs)( #if defined paramtypes && defined paramreferences #define BOOST_PP_LOCAL_MACRO(n) type_list(~, n, BOOST_PP_SEQ_TRANSFORM( type2string, , paramtypes), paramreferences) #define BOOST_PP_LOCAL_LIMITS (0, MAXPARAMTYPES-1) #include BOOST_PP_LOCAL_ITERATE() #endif ) { Action *ToCall = ActionRegistry::getInstance().getActionByName( TOKEN ); //->clone(params); //REACTION::PARAMS params; #if BOOST_PP_NOT_EQUAL(MAXPARAMTYPES,0) #define BOOST_PP_LOCAL_MACRO(n) valuetype_print(~, n, setCurrentValueByString, ) #define BOOST_PP_LOCAL_LIMITS (0, MAXPARAMTYPES-1) #include BOOST_PP_LOCAL_ITERATE() #endif ToCall->call(MoleCuilder::Action::NonInteractive); return static_cast *>(ToCall)->getResult(); }; // =========== obtain parameters from Storage, used by performCall() =========== void REACTION::getParametersfromValueStorage() { #if BOOST_PP_NOT_EQUAL(MAXPARAMTYPES,0) #define BOOST_PP_LOCAL_MACRO(n) value_print(~, n, queryCurrentValue, params.) #define BOOST_PP_LOCAL_LIMITS (0, MAXPARAMTYPES-1) #include BOOST_PP_LOCAL_ITERATE() #endif }; } // free up defines #undef paramtypes #undef paramtokens #undef paramreferences #undef MAXPARAMTYPES #undef returntype #undef RETURNTYPE #undef type2string #undef stringtype #undef initialiser_print #undef type_print #undef type_list #undef dialog_print #undef value_print #undef valuetype_print #undef REACTION #undef COMMAND #undef PARAMS #undef STATE #undef ACTIONNAME #undef CATEGORY #undef TOKEN