Changes in src/Actions/MapOfActions.hpp [7e6b00:0bb05a]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Actions/MapOfActions.hpp
r7e6b00 r0bb05a 9 9 #define MAPOFACTIONS_HPP_ 10 10 11 #include "Helpers/Assert.hpp"12 11 #include <boost/program_options.hpp> 12 #include <boost/lexical_cast.hpp> 13 13 14 #include <map> 14 15 #include <set> 16 #include <vector> 17 #include <typeinfo> 18 19 #include "Exceptions/IllegalTypeException.hpp" 20 #include "Exceptions/MissingValueException.hpp" 21 #include "Helpers/Assert.hpp" 22 #include "Patterns/Singleton.hpp" 15 23 16 24 class MapOfActionsTest; 17 25 18 #include "Patterns/Singleton.hpp" 26 class Box; 27 class atom; 28 class element; 29 class molecule; 30 class Vector; 19 31 20 32 namespace po = boost::program_options; 21 33 34 using boost::lexical_cast; 35 36 /** Central class for adding functionality to the code. 37 * 38 * In Molecuilder everything that can be done - such as adding atoms, 39 * translating molecules, saving bind information - is an Action. 40 * 41 * In order to reference Action's with what the user sees, this class is the 42 * mediator. 43 * 44 * An Action is described to the user by: 45 * -# a name (this is the most important information) 46 * -# a description 47 * -# a shortform (single letter for use on the command line) 48 * -# a text menu it resides in 49 * -# the type of its argument 50 * -# the command line category 51 * 52 * The Action::NAME is the most important information because every Action 53 * registers itself automatically with the ActionRegistry and can be retrieved 54 * therefrom and from this MapOfActions simply by knowing its name alone. 55 * 56 * In the constructor of MapOfActions all this is set. 57 * 58 * Note that Action will require input from the user. This is done via class 59 * Query. 60 * 61 * And note also that MapOfActions actually contains more than just all 62 * Actions: There are a number of names that actually are just arguments to 63 * actions (e.g. "output-file"). 64 * 65 * <h1> Howto add an Action</h1> 66 * 67 * Let us assume your new action (class) is called SuperDuperAction, consisting 68 * of two files SuperDuperAction.cpp and SuperDuperAction.hpp. 69 * 70 * Furthermore, let's say you Action needs two values: a double value as a 71 * upper threshold and a string which is the name of the output file. 72 * 73 * <h2> Command Line preliminaries </h2> 74 * 75 * You have to decide whether (for the command line) it makes sense to have an 76 * extra argument requesting the arguments, or one should be the argument of 77 * your action. I.e. your action name is "super-duper", then the use may 78 * call your action like this: 79 * 80 * ./molecuilder --super-duper 4 --output-file test.dat 81 * 82 * Here, we have picked the threshold as the value for your action and the 83 * name of the output file is given by an additional argument. Of course, 84 * it can be the other way round or by two arguments such as here: 85 * 86 * ./molecuilder --super-duper --threshold 4 --output-file test.dat 87 * 88 * It depends on what possible arguments are already there (don't make up 89 * new ones if present ones actually make sense for your action) and which 90 * argument is more natural or closer to what your action does. 91 * 92 * <h2> Menu preliminaries </h2> 93 * 94 * Whatever you decide, your action will need some Query dialogs to request 95 * the necessary information from the user, either via a command line 96 * argument (--output-file) via a text dialog (referenced by "output-file") 97 * or via a graphical dialog (same reference). And therein, the names 98 * of the arguments have to re-appear. 99 * 100 * Then, the following steps have to be done to incorporate your Action: 101 * -# create a unique name for your action (no capital letters) to reference 102 * it, this name has to appear in the file SuperDuperAction.cpp, e.g. 103 * "super-duper" 104 * -# pick names the other required arguments, best if they are already 105 * present in the MapOfActions. They have to appear in Query's in the 106 * code of your Action. 107 * -# With this name create entries in the following maps for the action 108 * name and for each names of a desired addtional argument if not present: 109 * -# DescriptionMap, a catchy description of what your action does 110 * -# TypeMap, see MapOfActions::OptionTypes for possible types of the single 111 * argument it takes. 112 * -# MenuContainsActionMap, in which menu should your action appear 113 * -# ShortFormMap (optional), single letter for command line call 114 * -# DefaultValueMap (optional), the default value (always a string) 115 * -# add to one of the command line sets by the following categories 116 * -# generic - generic options (i.e. not one of the others) 117 * -# config - action/argument only considers internal bevahior, user 118 * does not have to see it while still having full functionality 119 * -# hidden - this should be hidden from the user 120 * -# visible - this should be visible to the user 121 * -# inputfile - this should only be parsed from an input file, not 122 * from command line 123 * -# add to a menu, i.e. make an entry in MenuContainsActionMap. 124 * -# add header file SuperDuperAction.hpp to MapOfActions.cpp and instantiate 125 * your action in populateMenu() (mind the sorting: 1. menu, 126 * 2. alphabetical) 127 * 128 * And that's. 129 * 130 * Now, your action can be called from the command line, within the text 131 * menu and the graphical user interface. 132 * 133 */ 22 134 class MapOfActions : public Singleton<MapOfActions> { 23 135 friend class Singleton<MapOfActions>; 24 136 friend class MapOfActionsTest; 25 137 public: 26 enum OptionTypes { None, Boolean, Integer, ListOfInt s, Double, ListOfDoubles, String, Axis, Vector, Box, Molecule, ListOfMolecules, Atom, ListOfAtoms, Element, ListOfElements };138 enum OptionTypes { None, Boolean, Integer, ListOfIntegers, Double, ListOfDoubles, String, ListOfStrings, Vector, ListOfVectors, Box, Molecule, ListOfMolecules, Atom, ListOfAtoms, Element, ListOfElements }; 27 139 28 140 // getter for the action descriptions and short forms 29 std::string getDescription(st ring actionname);30 std::string getKeyAndShortForm(st ring actionname);31 std::string getShortForm(st ring actionname);32 map <std::string, std::string> getShortFormToActionMap();141 std::string getDescription(std::string actionname); 142 std::string getKeyAndShortForm(std::string actionname); 143 std::string getShortForm(std::string actionname); 144 std::map <std::string, std::string> getShortFormToActionMap(); 33 145 34 146 void AddOptionsToParser(); 35 147 36 148 // check presence and getter for action type 37 bool hasValue(string actionname); 38 bool isShortFormPresent(string shortform); 39 enum OptionTypes getValueType(string actionname); 40 41 set<string> generic; 42 set<string> config; 43 set<string> hidden; 44 set<string> visible; 45 set<string> inputfile; 149 bool hasValue(std::string actionname); 150 bool isShortFormPresent(std::string shortform); 151 std::string getValueType(std::string actionname); 152 153 std::set<std::string> generic; 154 std::set<std::string> config; 155 std::set<std::string> hidden; 156 std::set<std::string> visible; 157 std::set<std::string> inputfile; 158 159 std::multimap <std::string, std::string> MenuContainsActionMap; 160 std::map <std::string, std::pair<std::string,std::string> > MenuDescription; 161 162 // instantiates and puts all known actions into the ActionRegistry 163 void populateActions(); 164 165 void queryCurrentValue(const char * name, class atom * &_T); 166 void queryCurrentValue(const char * name, class element * &_T); 167 void queryCurrentValue(const char * name, class molecule * &_T); 168 void queryCurrentValue(const char * name, class Box &_T); 169 void queryCurrentValue(const char * name, class Vector &_T); 170 void queryCurrentValue(const char * name, std::vector<atom *>&_T); 171 void queryCurrentValue(const char * name, std::vector<element *>&_T); 172 void queryCurrentValue(const char * name, std::vector<molecule *>&_T); 173 template<typename T> void queryCurrentValue(const char * name, T &_T) 174 { 175 if (typeid( T ) == *TypeMap[name]) { // constructor of type_info is private, hence can only store by ref or ptr 176 if (CurrentValue.find(name) == CurrentValue.end()) 177 throw MissingValueException(__FILE__, __LINE__); 178 _T = lexical_cast<T>(CurrentValue[name].c_str()); 179 CurrentValue.erase(name); 180 } else 181 throw IllegalTypeException(__FILE__,__LINE__); 182 } 183 template<typename T> void queryCurrentValue(const char * name, std::vector<T> &_T) 184 { 185 T temp; 186 if (typeid( std::vector<T> ) == *TypeMap[name]) { // constructor of type_info is private, hence can only store by ref or ptr 187 if (CurrentValue.find(name) == CurrentValue.end()) 188 throw MissingValueException(__FILE__, __LINE__); 189 std::istringstream stream(CurrentValue[name]); 190 CurrentValue.erase(name); 191 while (!stream.fail()) { 192 stream >> temp >> std::ws; 193 _T.push_back(temp); 194 } 195 } else 196 throw IllegalTypeException(__FILE__,__LINE__); 197 } 198 199 void setCurrentValue(const char * name, class atom * &_T); 200 void setCurrentValue(const char * name, class element * &_T); 201 void setCurrentValue(const char * name, class molecule * &_T); 202 void setCurrentValue(const char * name, class Box &_T); 203 void setCurrentValue(const char * name, class Vector &_T); 204 void setCurrentValue(const char * name, std::vector<atom *>&_T); 205 void setCurrentValue(const char * name, std::vector<element *>&_T); 206 void setCurrentValue(const char * name, std::vector<molecule *>&_T); 207 template<class T> void setCurrentValue(const char * name, T &_T) 208 { 209 std::ostringstream stream; 210 if (typeid( T ) == *TypeMap[name]) { // constructor of type_info is private, hence can only store by ref or ptr 211 stream << _T; 212 CurrentValue[name] = stream.str(); 213 } else 214 throw IllegalTypeException(__FILE__,__LINE__); 215 } 216 template<class T> void setCurrentValue(const char * name, std::vector<T> &_T) 217 { 218 std::ostringstream stream; 219 if (typeid( std::vector<T> ) == *TypeMap[name]) { // constructor of type_info is private, hence can only store by ref or ptr 220 std::ostringstream stream; 221 for (typename std::vector<T>::iterator iter = _T.begin(); iter != _T.end(); ++iter) { 222 stream << (*iter) << " "; 223 } 224 CurrentValue[name] = stream.str(); 225 } else 226 throw IllegalTypeException(__FILE__,__LINE__); 227 } 228 46 229 47 230 private: … … 51 234 52 235 // lookup list from our configs to the ones of CommandLineParser 53 map<set<std::string> *, po::options_description *> CmdParserLookup;236 std::map< std::set<std::string> *, po::options_description *> CmdParserLookup; 54 237 55 238 // map of the action names and their description 56 map<std::string, std::string> DefaultValue; 57 map<std::string, std::string> DescriptionMap; 58 map<std::string, std::string> ShortFormMap; 59 map<std::string, enum OptionTypes > TypeMap; 239 std::map<std::string, std::string> CurrentValue; 240 std::map<std::string, std::string> DescriptionMap; 241 std::map<std::string, std::string> ShortFormMap; 242 std::map<std::string, const std::type_info * > TypeMap; 243 std::map<const std::type_info *, enum OptionTypes > TypeEnumMap; 60 244 }; 61 245
Note:
See TracChangeset
for help on using the changeset viewer.