00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _MPCL_AUTOMATON_ACTION_HANDLER__
00029 #define _MPCL_AUTOMATON_ACTION_HANDLER__
00030
00031 #include <algorithm>
00032 #include <list>
00033 #include "../event/action.hh"
00034 #include "../util/collection/map.hh"
00035 #include "../util/general-functions.hh"
00036 #include "exceptions.hh"
00037
00038
00040 namespace mpcl
00041 {
00042
00044 namespace automaton
00045 {
00046
00047 using event::IAction;
00048 using text::TString;
00049 using util::collection::TMap;
00050
00061 template <typename TState>
00062 class TActionHandler
00063 {
00064
00065 private:
00066
00068 typedef TMap<TString, IAction> TNameToActionMap;
00069
00071 const unsigned int kuiRetries;
00072
00073
00074 protected:
00075
00077 typedef std::list<IAction*> TActionList;
00078
00080 typedef TMap<TState, TActionList> TStateToActionListMap;
00081
00087 TActionList tActionList;
00088
00090 TStateToActionListMap tStateToActionListMap;
00091
00092
00093 public:
00094
00096 typedef std::list<TString> TActionNamesList;
00097
00098
00099 private:
00100
00101
00102
00103
00104
00110 int executeActions (const TActionList& rktACTION_LIST);
00111
00112
00113 public:
00114
00115
00116
00117
00118
00124 TActionHandler (const unsigned int kuiRETRIES = 1)
00125 throw (TIntegrityException) :
00126 kuiRetries (kuiRETRIES) ,
00127 tActionList () ,
00128 tStateToActionListMap ()
00129 {
00130
00131
00132
00133 if ( kuiRETRIES < 1 )
00134 {
00135 throw TIntegrityException ("retries set to less than 1", __FILE__, __LINE__);
00136 }
00137 }
00138
00140 virtual ~TActionHandler (void)
00141 {
00142 using std::for_each;
00143 using util::MDelete;
00144
00145 for_each (tActionList.begin(), tActionList.end(), MDelete<IAction*>());
00146 }
00147
00152 int execute (const TState& rktSTATE)
00153 {
00154 typename TStateToActionListMap::const_iterator I;
00155
00156 I = tStateToActionListMap.find (rktSTATE);
00157 if ( I == tStateToActionListMap.end() )
00158 {
00159 throw TNotFoundException ("state not found", __FILE__, __LINE__);
00160 }
00161 return executeActions (I->second);
00162 }
00163
00169 void setActions ( const TState& rktSOURCE_STATE ,
00170 const TActionNamesList& rktSOURCE_ACTION_NAMES_LIST );
00171
00172
00173 public:
00174
00175
00176
00177
00178
00183 TActionNamesList getActions (const TState& rktSOURCE_STATE) const;
00184
00185 };
00186
00187 }
00188
00189 }
00190
00191
00192
00193
00194
00195
00196 template <typename TState>
00197 int mpcl::automaton::TActionHandler<TState>::
00198 executeActions (const TActionList& rktACTION_LIST)
00199 {
00200
00201 register int iExitCode = 0;
00202 typename TActionList::const_iterator ktActionIter = rktACTION_LIST.begin();
00203
00204 for (; ( ktActionIter != rktACTION_LIST.end() ) ;++ktActionIter)
00205 {
00206
00207
00208
00209 if ( !(**ktActionIter)() )
00210 {
00211 for (unsigned int I = 0; ( I < kuiRetries ) ;++I)
00212 {
00213 iExitCode = (*ktActionIter)->react();
00214 if ( !iExitCode )
00215 {
00216
00217
00218
00219 break;
00220 }
00221 }
00222 }
00223 }
00224 return iExitCode;
00225
00226 }
00227
00228
00229
00230
00231
00232
00233 template <typename TState>
00234 typename mpcl::automaton::TActionHandler<TState>::TActionNamesList mpcl::automaton::TActionHandler<TState>::
00235 getActions (const TState& rktSOURCE_STATE) const
00236 {
00237
00238 typename TStateToActionListMap::const_iterator I;
00239 TActionNamesList tActionNamesList;
00240
00241 I = tStateToActionListMap.find (rktSOURCE_STATE);
00242 if ( I == tStateToActionListMap.end() )
00243 {
00244 throw TNotFoundException ("state not found", __FILE__, __LINE__);
00245 }
00246 else
00247 {
00248 typename TActionList::const_iterator J = I->second.begin();
00249
00250
00251
00252
00253 for (; ( J != I->second.end() ) ;++J)
00254 {
00255 tActionNamesList.push_back ((*J)->getName());
00256 }
00257 }
00258 return tActionNamesList;
00259
00260 }
00261
00262
00263 template <typename TState>
00264 void mpcl::automaton::TActionHandler<TState>::
00265 setActions ( const TState& rktSOURCE_STATE ,
00266 const TActionNamesList& rktSOURCE_ACTION_NAMES_LIST )
00267 {
00268
00269 typename TActionList::const_iterator J;
00270 TActionList tAuxActionList;
00271 typename TActionNamesList::const_iterator I = rktSOURCE_ACTION_NAMES_LIST.begin();
00272
00273
00274
00275
00276
00277 if ( tStateToActionListMap.find (rktSOURCE_STATE) != tStateToActionListMap.end() )
00278 {
00279 throw TIntegrityException ("attempt to redefine a state", __FILE__, __LINE__);
00280 }
00281
00282
00283
00284
00285
00286 for (; ( I != rktSOURCE_ACTION_NAMES_LIST.end() ) ;++I)
00287 {
00288 for (J = tActionList.begin(); ( J != tActionList.end() ) ;++J)
00289 {
00290 if ( (*J)->getName() == *I )
00291 {
00292 break;
00293 }
00294 }
00295 if ( J == tActionList.end() )
00296 {
00297 throw TNotFoundException ("action name not found", __FILE__, __LINE__);
00298 }
00299 tAuxActionList.push_back (*J);
00300 }
00301 tStateToActionListMap.bind (rktSOURCE_STATE, tAuxActionList);
00302
00303 }
00304
00305
00306 #endif // not _MPCL_AUTOMATON_ACTION_HANDLER__