Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members  

action_handler.hh

00001 /*
00002 *  Name:      action_handler.hh
00003 *  Authors:   Francisco Rodrigo Escobedo Robles
00004 *             Rafael Jesus Alcantara Perez
00005 *  Summary:   Base Action Handler definitions
00006 *  Date:      $Date: 2003/10/06 12:45:11 $
00007 *  Revision:  $Revision: 1.1 $
00008 *
00009 *  Copyright (C) 1999       Francisco Rodrigo Escobedo Robles <frer@dedalo-ing.com>
00010 *  Copyright (C) 2001-2002  Rafael Jesus Alcantara Perez <rafa@dedalo-ing.com>
00011 *
00012 *  This program is free software; you can redistribute it and/or modify
00013 *  it under the terms of the GNU General Public License as published by
00014 *  the Free Software Foundation; either version 2 of the License, or
00015 *  (at your option) any later version.
00016 *
00017 *  This program is distributed in the hope that it will be useful,
00018 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 *  GNU General Public License for more details.
00021 *
00022 *  You should have received a copy of the GNU General Public License
00023 *  along with this program; if not, write to the Free Software
00024 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00025 *  MA 02111-1307, USA.
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         //  C O N S T R U C T O R S
00103         //
00104 
00110         int executeActions (const TActionList& rktACTION_LIST);
00111 
00112 
00113       public:
00114 
00115         //
00116         //  C O N S T R U C T O R S
00117         //
00118 
00124         TActionHandler (const unsigned int kuiRETRIES = 1)
00125           throw (TIntegrityException)        :
00126           kuiRetries            (kuiRETRIES) ,
00127           tActionList           ()           ,
00128           tStateToActionListMap ()
00129         {
00130           //
00131           //  Bad call to constructor.
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         //  S E L E C T O R S
00177         //
00178 
00183         TActionNamesList getActions (const TState& rktSOURCE_STATE) const;
00184 
00185     };  // class TActionHandler
00186 
00187   }  // namespace automaton
00188 
00189 }  // namespace mpcl
00190 
00191 
00192 //
00193 //  C O N S T R U C T O R S
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     //  Executes the action and checks for the reaction.
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           //  Reaction has ran correctly.
00218           //
00219           break;
00220         }
00221       }
00222     }
00223   }
00224   return iExitCode;
00225 
00226 }  // executeActions()
00227 
00228 
00229 //
00230 //  S E L E C T O R S
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     //  Translates action to action names.
00252     //
00253     for (; ( J != I->second.end() ) ;++J)
00254     {
00255       tActionNamesList.push_back ((*J)->getName());
00256     }
00257   }
00258   return tActionNamesList;
00259 
00260 }  // getActions()
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   //  State already exists.
00275   //
00276 
00277   if ( tStateToActionListMap.find (rktSOURCE_STATE) != tStateToActionListMap.end() )
00278   {
00279     throw TIntegrityException ("attempt to redefine a state", __FILE__, __LINE__);
00280   }
00281   //FIXME: dynamic dependence
00282 
00283   //
00284   //  Translates action names to action objects.
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 }  // setActions()
00304 
00305 
00306 #endif  // not _MPCL_AUTOMATON_ACTION_HANDLER__

Generated on Mon Oct 13 02:35:22 2003 for MPCL by doxygen1.2.18