]> git.sesse.net Git - vlc/blob - modules/gui/skins2/utils/fsm.cpp
Remove bogus executable permissions
[vlc] / modules / gui / skins2 / utils / fsm.cpp
1 /*****************************************************************************
2  * fsm.cpp
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id$
6  *
7  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
8  *          Olivier Teulière <ipkiss@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 #include "fsm.hpp"
26 #include "../commands/cmd_generic.hpp"
27
28
29 void FSM::addState( const string &state )
30 {
31     m_states.insert( state );
32 }
33
34
35 void FSM::addTransition( const string &state1, const string &event,
36                          const string &state2, Callback *pCmd )
37 {
38     // Check that we already know the states
39     if( m_states.find( state1 ) == m_states.end() ||
40         m_states.find( state2 ) == m_states.end() )
41     {
42         msg_Warn( getIntf(),
43                   "FSM: ignoring transition between invalid states" );
44         return;
45     }
46
47     Key_t key( state1, event );
48     Data_t data( state2, pCmd );
49
50     // Check that the transition doesn't already exist
51     if( m_transitions.find( key ) != m_transitions.end() )
52     {
53         msg_Warn( getIntf(), "FSM: transition already exists" );
54         return;
55     }
56
57     m_transitions[key] = data;
58 }
59
60
61 void FSM::setState( const string &state )
62 {
63     if( m_states.find( state ) == m_states.end() )
64     {
65         msg_Warn( getIntf(), "FSM: trying to set an invalid state" );
66         return;
67     }
68     m_currentState = state;
69 }
70
71
72 void FSM::handleTransition( const string &event )
73 {
74     string tmpEvent = event;
75     Key_t key( m_currentState, event );
76     map<Key_t, Data_t>::const_iterator it;
77
78     // Find a transition
79     it = m_transitions.find( key );
80
81     // While the matching fails, try to match a more generic transition
82     // For example, if "key:up:F" isn't a transition, "key:up" or "key" may be
83     while( it == m_transitions.end() &&
84            tmpEvent.rfind( ":", tmpEvent.size() ) != string::npos )
85     {
86         // Cut the last part
87         tmpEvent = tmpEvent.substr( 0, tmpEvent.rfind( ":", tmpEvent.size() ) );
88
89         key.second = tmpEvent;
90         it = m_transitions.find( key );
91     }
92
93     // No transition was found
94     if( it == m_transitions.end() )
95     {
96         return;
97     }
98
99     // Change state
100     m_currentState = (*it).second.first;
101
102     // Call the callback, if any
103     Callback *pCmd = (*it).second.second;
104     if( pCmd != NULL )
105     {
106         (*(pCmd->getFunc()))( pCmd->getObj() );
107     }
108 }