Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

fsm.cpp

00001 /*****************************************************************************
00002  * fsm.cpp
00003  *****************************************************************************
00004  * Copyright (C) 2003 the VideoLAN team
00005  * $Id: fsm.cpp 12053 2005-08-06 23:38:31Z asmax $
00006  *
00007  * Authors: Cyril Deguet     <[email protected]>
00008  *          Olivier Teulière <[email protected]>
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00023  *****************************************************************************/
00024 
00025 #include "fsm.hpp"
00026 #include "../commands/cmd_generic.hpp"
00027 
00028 
00029 void FSM::addState( const string &state )
00030 {
00031     m_states.insert( state );
00032 }
00033 
00034 
00035 void FSM::addTransition( const string &state1, const string &event,
00036                          const string &state2, CmdGeneric *pCmd )
00037 {
00038     // Check that we already know the states
00039     if( m_states.find( state1 ) == m_states.end() ||
00040         m_states.find( state2 ) == m_states.end() )
00041     {
00042         msg_Warn( getIntf(),
00043                   "FSM: ignoring transition between invalid states" );
00044         return;
00045     }
00046 
00047     Key_t key( state1, event );
00048     Data_t data( state2, pCmd );
00049 
00050     // Check that the transition doesn't already exist
00051     if( m_transitions.find( key ) != m_transitions.end() )
00052     {
00053         msg_Warn( getIntf(), "FSM: transition already exists" );
00054         return;
00055     }
00056 
00057     m_transitions[key] = data;
00058 }
00059 
00060 
00061 void FSM::setState( const string &state )
00062 {
00063     if( m_states.find( state ) == m_states.end() )
00064     {
00065         msg_Warn( getIntf(), "FSM: trying to set an invalid state" );
00066         return;
00067     }
00068     m_currentState = state;
00069 }
00070 
00071 
00072 void FSM::handleTransition( const string &event )
00073 {
00074     string tmpEvent = event;
00075     Key_t key( m_currentState, event );
00076     map<Key_t, Data_t>::const_iterator it;
00077 
00078     // Find a transition
00079     it = m_transitions.find( key );
00080 
00081     // While the matching fails, try to match a more generic transition
00082     // For example, if "key:up:F" isn't a transition, "key:up" or "key" may be
00083     while( it == m_transitions.end() &&
00084            tmpEvent.rfind( ":", tmpEvent.size() ) != string::npos )
00085     {
00086         // Cut the last part
00087         tmpEvent = tmpEvent.substr( 0, tmpEvent.rfind( ":", tmpEvent.size() ) );
00088 
00089         key.second = tmpEvent;
00090         it = m_transitions.find( key );
00091     }
00092 
00093     // No transition was found
00094     if( it == m_transitions.end() )
00095     {
00096         return;
00097     }
00098 
00099     // Change state
00100     m_currentState = (*it).second.first;
00101 
00102     // Call the callback, if any
00103     CmdGeneric *pCmd = (*it).second.second;
00104     if( pCmd != NULL )
00105     {
00106         pCmd->execute();
00107     }
00108 }

Generated on Tue Dec 20 10:14:43 2005 for vlc-0.8.4a by  doxygen 1.4.2