/* * Action_impl_header.hpp * * Created on: Aug 25, 2010 * Author: heber */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Actions/ActionTraits.hpp" #include "Actions/OptionTrait.hpp" #include "Actions/ValueStorage.hpp" // some derived names: if CATEGORY is not given, we don't prefix with it #ifdef CATEGORY #define ACTION BOOST_PP_CAT(CATEGORY, BOOST_PP_CAT(ACTIONNAME, Action)) #define COMMAND BOOST_PP_CAT(CATEGORY, ACTIONNAME) #define PARAMS BOOST_PP_CAT(CATEGORY, BOOST_PP_CAT(ACTIONNAME, Parameters)) #else #define ACTION BOOST_PP_CAT(ACTIONNAME, Action) #define COMMAND ACTIONNAME #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 // 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 paramdescriptions BOOST_PP_ASSERT_MSG(BOOST_PP_EQUAL(MAXPARAMTYPES, BOOST_PP_SEQ_SIZE(paramdescriptions)),\ ERROR: There are not the same number of "paramtokens" and "paramdescriptions" in: __FILE__ \ ) #endif // check for mandatory defines #ifndef DESCRIPTION BOOST_PP_ASSERT_MSG(0, \ "ERROR: Description is mandatory for Actions, here for ACTION " \ ) #endif // check if paramdefaults is given, otherwise fill list with NODEFAULT // this does not work: paramdefaults has to be completely defined before // being used within option_print (used as an array there and not as // some function call still to be expanded) //#define paramdefaults (NODEFAULT) //#define tempvalue(z,n,value) // BOOST_PP_CAT(value,(NODEFAULT)) //BOOST_PP_REPEAT(tempvalue, MAXPARAMTYPES, paramdefaults) //#undef tempvalue //#else // if present, check if correct number of arguments #ifdef paramdefaults BOOST_PP_ASSERT_MSG(BOOST_PP_EQUAL(MAXPARAMTYPES, BOOST_PP_SEQ_SIZE(paramdefaults)),\ ERROR: There are not the same number of "paramtokens" and "paramdefaults" in: __FILE__ \ ) #endif // print a list of type ref followed by a separator, i.e. "int i;" #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 Options.insert #ifdef paramdefaults #define option_print(z,n,unused, unused2) \ tester = Options. insert (\ std::pair< std::string, OptionTrait *> ( \ BOOST_PP_SEQ_ELEM(n, paramtokens), \ new OptionTrait(\ BOOST_PP_SEQ_ELEM(n, paramtokens), \ &typeid( BOOST_PP_SEQ_ELEM(n, paramtypes) ), \ BOOST_PP_SEQ_ELEM(n, paramdescriptions), \ BOOST_PP_SEQ_ELEM(n, paramdefaults) )\ )\ ); \ ASSERT(tester.second, "ActionTrait::ActionTrait() option token present twice!"); #else #define option_print(z,n,unused, unused2) \ tester = Options. insert (\ std::pair< std::string, OptionTrait *> ( \ BOOST_PP_SEQ_ELEM(n, paramtokens), \ new OptionTrait(\ BOOST_PP_SEQ_ELEM(n, paramtokens), \ &typeid( BOOST_PP_SEQ_ELEM(n, paramtypes) ), \ BOOST_PP_SEQ_ELEM(n, paramdescriptions), \ NODEFAULT )\ )\ ); \ ASSERT(tester.second, "ActionTrait::ActionTrait() option token present twice!"); #endif #if defined paramtypes && defined paramreferences void COMMAND( #define BOOST_PP_LOCAL_MACRO(n) type_list(~, n, paramtypes, paramreferences) #define BOOST_PP_LOCAL_LIMITS (0, MAXPARAMTYPES-1) #include BOOST_PP_LOCAL_ITERATE() ); # else void COMMAND(); #endif class ACTION; template <> class ActionTrait : public ActionTraits { public: ActionTrait() : #ifndef SHORTFORM ActionTraits(OptionTrait(TOKEN, &typeid(void), DESCRIPTION, std::string())) #else ActionTraits(OptionTrait(TOKEN, &typeid(void), DESCRIPTION, std::string(), SHORTFORM)) #endif /* SHORTFORM */ { // initialize remainder of action info #ifdef MENUNAME MenuTitle = MENUNAME; #endif #ifdef MENUPOSITION MenuPosition = MENUPOSITION; #endif // initialize action's options std::pair< ActionTraits::options_iterator, bool > tester; #ifdef paramtokens #define BOOST_PP_LOCAL_MACRO(n) option_print(~, n, ~, ) #define BOOST_PP_LOCAL_LIMITS (0, MAXPARAMTYPES-1) #include BOOST_PP_LOCAL_ITERATE() #endif // associate action's short form also with option #ifdef SHORTFORM if (Options.find(TOKEN) != Options.end()) Options[TOKEN]->setShortForm(std::string(SHORTFORM)); #endif /* SHORTFORM */ //std::cout << "ActionTrait::ActionTrait() with " << getName() << ", type " << getTypeName() << " and description " << getDescription() << std::endl; } ~ActionTrait() {} }; class ACTION : public Action { #if defined paramtypes && defined paramreferences friend void COMMAND( #define BOOST_PP_LOCAL_MACRO(n) type_list(~, n, paramtypes, paramreferences) #define BOOST_PP_LOCAL_LIMITS (0, MAXPARAMTYPES-1) #include BOOST_PP_LOCAL_ITERATE() ); # else void COMMAND(); #endif public: ACTION(); virtual ~ACTION(); bool canUndo(); bool shouldUndo(); struct PARAMS : ActionParameters { #if defined paramtypes && defined paramreferences #define BOOST_PP_LOCAL_MACRO(n) type_print(~, n, paramtypes, paramreferences, ;) #define BOOST_PP_LOCAL_LIMITS (0, MAXPARAMTYPES-1) #include BOOST_PP_LOCAL_ITERATE() #endif } params; protected: virtual Dialog * fillDialog(Dialog*); private: virtual void getParametersfromValueStorage(); virtual Action::state_ptr performCall(); virtual Action::state_ptr performUndo(Action::state_ptr); virtual Action::state_ptr performRedo(Action::state_ptr); }; #undef paramtypes #undef paramtokens #undef paramreferences #undef paramdescriptions #undef paramdefaults #undef MAXPARAMTYPES #undef statetypes #undef statereferences #undef MAXSTATETYPES #undef ACTION #undef COMMAND #undef COMMANDFULL #undef PARAMS #undef ACTIONNAME #undef CATEGORY #undef MENUNAME #undef MENUPOSITION #undef TOKEN #undef DESCRIPTION #undef SHORTFORM