From 49d9b24c7188bd1264e187a1511ecca07ff47a06 Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Sat, 1 Sep 2012 20:20:14 +0200 Subject: [PATCH] Add keyboard example to test orthogonal states The generated graph is not complete and no warnings are issued. --- examples/Keyboard.cpp | 182 ++++++++++++++++++++++++++++++++++++++++++ examples/Makefile | 2 +- 2 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 examples/Keyboard.cpp diff --git a/examples/Keyboard.cpp b/examples/Keyboard.cpp new file mode 100644 index 0000000..e9f0867 --- /dev/null +++ b/examples/Keyboard.cpp @@ -0,0 +1,182 @@ +////////////////////////////////////////////////////////////////////////////// +// 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 +#include +#include +#include +#include + +#include +#include + +#include +#include + +#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; +} diff --git a/examples/Makefile b/examples/Makefile index f1bf4c6..d71a9ac 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,7 +1,7 @@ -include ../Makefile.config .PHONY: all -all: test.pdf StopWatch.pdf main.pdf Camera/Main.pdf +all: test.pdf StopWatch.pdf main.pdf Camera/Main.pdf Keyboard.pdf CLANG++ ?= $(shell $(LLVM_CONFIG) --bindir)/clang++ ifeq ($(wildcard $(CLANG++)),) -- 2.39.2