f8e471e541
[SVN r36255]
183 lines
5.7 KiB
C++
183 lines
5.7 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
// Copyright 2002-2006 Andreas Huber Doenni
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompany-
|
|
// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// The following example program demonstrates the use of orthogonal states and
|
|
// state_downcast to query the state of orthogonal regions.
|
|
// Moreover, the use of the state type information interface is also shown.
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// #define BOOST_STATECHART_USE_NATIVE_RTTI
|
|
|
|
|
|
#include <boost/statechart/event.hpp>
|
|
#include <boost/statechart/state_machine.hpp>
|
|
#include <boost/statechart/simple_state.hpp>
|
|
#include <boost/statechart/transition.hpp>
|
|
#include <boost/statechart/custom_reaction.hpp>
|
|
|
|
#include <boost/mpl/list.hpp>
|
|
#include <boost/config.hpp>
|
|
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
|
|
#ifdef BOOST_INTEL
|
|
# pragma warning( disable: 304 ) // access control not specified
|
|
# pragma warning( disable: 981 ) // operands are evaluated in unspecified order
|
|
#endif
|
|
|
|
|
|
|
|
namespace sc = boost::statechart;
|
|
namespace mpl = boost::mpl;
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
struct EvNumLockPressed : sc::event< EvNumLockPressed > {};
|
|
struct EvCapsLockPressed : sc::event< EvCapsLockPressed > {};
|
|
struct EvScrollLockPressed : sc::event< EvScrollLockPressed > {};
|
|
struct EvRequestShutdown : sc::event< EvRequestShutdown > {};
|
|
|
|
struct Active;
|
|
struct Keyboard : sc::state_machine< Keyboard, Active > {};
|
|
|
|
struct NumLockOff;
|
|
struct CapsLockOff;
|
|
struct ScrollLockOff;
|
|
struct Active: sc::simple_state<
|
|
Active, Keyboard, mpl::list< NumLockOff, CapsLockOff, ScrollLockOff > >
|
|
{
|
|
typedef sc::custom_reaction< EvRequestShutdown > reactions;
|
|
|
|
sc::result react( const EvRequestShutdown & );
|
|
};
|
|
|
|
struct NumLockOn : sc::simple_state< NumLockOn, Active::orthogonal< 0 > >
|
|
{
|
|
typedef sc::transition< EvNumLockPressed, NumLockOff > reactions;
|
|
};
|
|
|
|
struct NumLockOff : sc::simple_state< NumLockOff, Active::orthogonal< 0 > >
|
|
{
|
|
typedef sc::transition< EvNumLockPressed, NumLockOn > reactions;
|
|
};
|
|
|
|
struct CapsLockOn : sc::simple_state< CapsLockOn, Active::orthogonal< 1 > >
|
|
{
|
|
typedef sc::transition< EvCapsLockPressed, CapsLockOff > reactions;
|
|
};
|
|
|
|
struct CapsLockOff : sc::simple_state< CapsLockOff, Active::orthogonal< 1 > >
|
|
{
|
|
typedef sc::transition< EvCapsLockPressed, CapsLockOn > reactions;
|
|
};
|
|
|
|
struct ScrollLockOn : sc::simple_state< ScrollLockOn, Active::orthogonal< 2 > >
|
|
{
|
|
typedef sc::transition< EvScrollLockPressed, ScrollLockOff > reactions;
|
|
};
|
|
|
|
struct ScrollLockOff : sc::simple_state< ScrollLockOff, Active::orthogonal< 2 > >
|
|
{
|
|
typedef sc::transition< EvScrollLockPressed, ScrollLockOn > reactions;
|
|
};
|
|
|
|
sc::result Active::react( const EvRequestShutdown & )
|
|
{
|
|
if ( ( state_downcast< const NumLockOff * >() != 0 ) &&
|
|
( state_downcast< const CapsLockOff * >() != 0 ) &&
|
|
( state_downcast< const ScrollLockOff * >() != 0 ) )
|
|
{
|
|
std::cout << "Shutdown request accepted\n";
|
|
return terminate();
|
|
}
|
|
else
|
|
{
|
|
std::cout << "Ignoring shutdown request\n\n";
|
|
return discard_event();
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
void DisplayStateConfiguration( const Keyboard & keyboard )
|
|
{
|
|
char orthogonalRegion = 'a';
|
|
|
|
for ( Keyboard::state_iterator pLeafState = keyboard.state_begin();
|
|
pLeafState != keyboard.state_end(); ++pLeafState )
|
|
{
|
|
std::cout << "Orthogonal region " << orthogonalRegion << ": ";
|
|
|
|
const Keyboard::state_base_type * pState = &*pLeafState;
|
|
|
|
while ( pState != 0 )
|
|
{
|
|
if ( pState != &*pLeafState )
|
|
{
|
|
std::cout << " -> ";
|
|
}
|
|
|
|
#ifdef BOOST_STATECHART_USE_NATIVE_RTTI
|
|
std::cout << std::setw( 15 ) << typeid( *pState ).name();
|
|
#else
|
|
std::cout << std::setw( 15 ) <<
|
|
pState->custom_dynamic_type_ptr< char >();
|
|
#endif
|
|
pState = pState->outer_state_ptr();
|
|
}
|
|
|
|
std::cout << "\n";
|
|
++orthogonalRegion;
|
|
}
|
|
|
|
std::cout << "\n";
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
int main()
|
|
{
|
|
#ifndef BOOST_STATECHART_USE_NATIVE_RTTI
|
|
Active::custom_static_type_ptr( "Active" );
|
|
NumLockOn::custom_static_type_ptr( "NumLockOn" );
|
|
NumLockOff::custom_static_type_ptr( "NumLockOff" );
|
|
CapsLockOn::custom_static_type_ptr( "CapsLockOn" );
|
|
CapsLockOff::custom_static_type_ptr( "CapsLockOff" );
|
|
ScrollLockOn::custom_static_type_ptr( "ScrollLockOn" );
|
|
ScrollLockOff::custom_static_type_ptr( "ScrollLockOff" );
|
|
#endif
|
|
|
|
std::cout << "Boost.Statechart Keyboard example\n\n";
|
|
Keyboard keyboard;
|
|
keyboard.initiate();
|
|
DisplayStateConfiguration( keyboard );
|
|
keyboard.process_event( EvNumLockPressed() );
|
|
DisplayStateConfiguration( keyboard );
|
|
keyboard.process_event( EvRequestShutdown() );
|
|
keyboard.process_event( EvCapsLockPressed() );
|
|
DisplayStateConfiguration( keyboard );
|
|
keyboard.process_event( EvRequestShutdown() );
|
|
keyboard.process_event( EvScrollLockPressed() );
|
|
DisplayStateConfiguration( keyboard );
|
|
keyboard.process_event( EvRequestShutdown() );
|
|
|
|
keyboard.process_event( EvNumLockPressed() );
|
|
DisplayStateConfiguration( keyboard );
|
|
keyboard.process_event( EvRequestShutdown() );
|
|
keyboard.process_event( EvCapsLockPressed() );
|
|
DisplayStateConfiguration( keyboard );
|
|
keyboard.process_event( EvRequestShutdown() );
|
|
keyboard.process_event( EvScrollLockPressed() );
|
|
DisplayStateConfiguration( keyboard );
|
|
keyboard.process_event( EvRequestShutdown() );
|
|
|
|
return 0;
|
|
}
|