diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/statechart/example | |
parent | Initial commit. (diff) | |
download | ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.tar.xz ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/statechart/example')
30 files changed, 4646 insertions, 0 deletions
diff --git a/src/boost/libs/statechart/example/BitMachine/BitMachine.cpp b/src/boost/libs/statechart/example/BitMachine/BitMachine.cpp new file mode 100644 index 000000000..89478a5a4 --- /dev/null +++ b/src/boost/libs/statechart/example/BitMachine/BitMachine.cpp @@ -0,0 +1,264 @@ +////////////////////////////////////////////////////////////////////////////// +// 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) +////////////////////////////////////////////////////////////////////////////// + + + +////////////////////////////////////////////////////////////////////////////// +#define NO_OF_BITS 3 +////////////////////////////////////////////////////////////////////////////// +// This program demonstrates the fact that measures must be taken to hide some +// of the complexity (e.g. in separate .cpp file) of a Boost.Statechart state +// machine once a certain size is reached. +// For this purpose, a state machine with exactly 2^NO_OF_BITS states (i.e. +// BitState< 0 > .. BitState< 2^NO_OF_BITS - 1 >) is generated. For the events +// EvFlipBit< 0 > .. EvFlipBit< NO_OF_BITS - 1 > there is a transition from +// each state to the state with the corresponding bit toggled. That is, there +// is a total of 2^NO_OF_BITS * NO_OF_BITS transitions. +// E.g. if the state machine is currently in state BitState< 5 > and receives +// EvFlipBit< 2 >, it transitions to state BitState< 1 >. If it is in +// BitState< 15 > and receives EvFlipBit< 4 > it transitions to BitState< 31 > +// etc. +// The maximum size of such a state machine depends on your compiler. The +// following table gives upper limits for NO_OF_BITS. From this, rough +// estimates for the maximum size of any "naively" implemented Boost.Statechart +// machine (i.e. no attempt is made to hide inner state implementation in a +// .cpp file) can be deduced. +// +// NOTE: Due to the fact that the amount of generated code more than +// *doubles* each time NO_OF_BITS is *incremented*, build times on most +// compilers soar when NO_OF_BITS > 6. +// +// Compiler | max. NO_OF_BITS b | max. states s | +// --------------|-------------------|----------------| +// MSVC 7.1 | b < 6 | 32 < s < 64 | +// GCC 3.4.2 (1) | b < 8 | 128 < s < 256 | +// +// (1) This is a practical rather than a hard limit, caused by a compiler +// memory footprint that was significantly larger than the 1GB physical +// memory installed in the test machine. The resulting frequent swapping +// led to compilation times of hours rather than minutes. +////////////////////////////////////////////////////////////////////////////// + + + +#include "UniqueObject.hpp" + +#include <boost/statechart/event.hpp> +#include <boost/statechart/simple_state.hpp> +#include <boost/statechart/state_machine.hpp> +#include <boost/statechart/transition.hpp> + +#include <boost/mpl/list.hpp> +#include <boost/mpl/front_inserter.hpp> +#include <boost/mpl/transform_view.hpp> +#include <boost/mpl/copy.hpp> +#include <boost/mpl/range_c.hpp> +#include <boost/mpl/integral_c.hpp> +#include <boost/mpl/shift_left.hpp> +#include <boost/mpl/bitxor.hpp> +#include <boost/mpl/for_each.hpp> +#include <boost/mpl/placeholders.hpp> +#include <boost/mpl/aux_/lambda_support.hpp> + +#include <boost/config.hpp> +#include <boost/intrusive_ptr.hpp> + +#include <iostream> +#include <iomanip> +#include <cstddef> // size_t + +#ifdef BOOST_INTEL +# pragma warning( disable: 304 ) // access control not specified +# pragma warning( disable: 444 ) // destructor for base is not virtual +# pragma warning( disable: 981 ) // operands are evaluated in unspecified order +#endif + + + +namespace sc = boost::statechart; +namespace mpl = boost::mpl; + + + +////////////////////////////////////////////////////////////////////////////// +struct IDisplay +{ + virtual void Display() const = 0; +}; + +////////////////////////////////////////////////////////////////////////////// +template< class BitNo > +struct EvFlipBit : sc::event< EvFlipBit< BitNo > > {}; + +template< class StateNo > +struct BitState; + +struct BitMachine : sc::state_machine< + BitMachine, BitState< mpl::integral_c< unsigned int, 0 > > > {}; + +template< class BitNo, class StateNo > +struct FlipTransition +{ + private: + typedef typename mpl::bitxor_< + StateNo, + mpl::shift_left< mpl::integral_c< unsigned int, 1 >, BitNo > + >::type NextStateNo; + + public: + typedef typename sc::transition< + EvFlipBit< BitNo >, BitState< NextStateNo > > type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT( 2, FlipTransition, (BitNo, StateNo) ); +}; + +////////////////////////////////////////////////////////////////////////////// +void DisplayBits( unsigned int number ) +{ + char buffer[ NO_OF_BITS + 1 ]; + buffer[ NO_OF_BITS ] = 0; + + for ( unsigned int bit = 0; bit < NO_OF_BITS; ++bit ) + { + buffer[ bit ] = number & ( 1 << ( NO_OF_BITS - bit - 1 ) ) ? '1' : '0'; + } + + std::cout << "Current state: " << std::setw( 4 ) << + number << " (" << buffer << ")" << std::endl; +} + +template< class StateNo > +struct BitState : sc::simple_state< BitState< StateNo >, BitMachine >, + UniqueObject< BitState< StateNo > >, IDisplay +{ + void * operator new( std::size_t size ) + { + return UniqueObject< BitState< StateNo > >::operator new( size ); + } + + void operator delete( void * p, std::size_t size ) + { + UniqueObject< BitState< StateNo > >::operator delete( p, size ); + } + + typedef typename mpl::copy< + typename mpl::transform_view< + mpl::range_c< unsigned int, 0, NO_OF_BITS >, + FlipTransition< mpl::placeholders::_, StateNo > >::type, + mpl::front_inserter< mpl::list<> > + >::type reactions; + + virtual void Display() const + { + DisplayBits( StateNo::value ); + } +}; + + +void DisplayMachineState( const BitMachine & bitMachine ) +{ + bitMachine.state_cast< const IDisplay & >().Display(); +} + +////////////////////////////////////////////////////////////////////////////// +boost::intrusive_ptr< const sc::event_base > pFlipBitEvents[ NO_OF_BITS ]; + +struct EventInserter +{ + template< class BitNo > + void operator()( const BitNo & ) + { + pFlipBitEvents[ BitNo::value ] = new EvFlipBit< BitNo >(); + } +}; + +void FillEventArray() +{ + mpl::for_each< mpl::range_c< unsigned int, 0, NO_OF_BITS > >( + EventInserter() ); +} + +////////////////////////////////////////////////////////////////////////////// +void VisitAllStates( BitMachine & bitMachine, unsigned int msb ) +{ + if ( msb > 0 ) + { + VisitAllStates( bitMachine, msb - 1 ); + } + + bitMachine.process_event( *pFlipBitEvents[ msb ] ); + DisplayMachineState( bitMachine ); + + if ( msb > 0 ) + { + VisitAllStates( bitMachine, msb - 1 ); + } +} + +////////////////////////////////////////////////////////////////////////////// +char GetKey() +{ + char key; + std::cin >> key; + return key; +} + + +////////////////////////////////////////////////////////////////////////////// +int main() +{ + FillEventArray(); + + const unsigned int noOfStates = 1 << NO_OF_BITS; + std::cout << "Boost.Statechart BitMachine example\n"; + std::cout << "Machine configuration: " << noOfStates << + " states interconnected with " << noOfStates * NO_OF_BITS << + " transitions.\n\n"; + + for ( unsigned int bit = 0; bit < NO_OF_BITS; ++bit ) + { + std::cout << bit - 0 << "<CR>: Flips bit " << bit - 0 << "\n"; + } + + std::cout << "a<CR>: Goes through all states automatically\n"; + std::cout << "e<CR>: Exits the program\n\n"; + std::cout << "You may chain commands, e.g. 31<CR> flips bits 3 and 1\n\n"; + + + BitMachine bitMachine; + bitMachine.initiate(); + + char key = GetKey(); + + while ( key != 'e' ) + { + if ( ( key >= '0' ) && ( key < static_cast< char >( '0' + NO_OF_BITS ) ) ) + { + bitMachine.process_event( *pFlipBitEvents[ key - '0' ] ); + DisplayMachineState( bitMachine ); + } + else + { + switch( key ) + { + case 'a': + { + VisitAllStates( bitMachine, NO_OF_BITS - 1 ); + } + break; + + default: + { + std::cout << "Invalid key!\n"; + } + } + } + + key = GetKey(); + } + + return 0; +} diff --git a/src/boost/libs/statechart/example/BitMachine/BitMachine.vcproj b/src/boost/libs/statechart/example/BitMachine/BitMachine.vcproj new file mode 100644 index 000000000..af02845a9 --- /dev/null +++ b/src/boost/libs/statechart/example/BitMachine/BitMachine.vcproj @@ -0,0 +1,301 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="BitMachine" + ProjectGUID="{CF66596F-7DEA-4BB6-A728-F7FEF2889855}" + RootNamespace="BitMachine" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300 /bigobj" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + ForceConformanceInForLoopScope="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + EnablePREfast="false" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/BitMachine.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/BitMachine.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + EmbedManifest="true" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300 /bigobj" + Optimization="3" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="..\..\..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + StringPooling="true" + ExceptionHandling="1" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + ForceConformanceInForLoopScope="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="0" + EnablePREfast="false" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/BitMachine.exe" + LinkIncremental="1" + GenerateDebugInformation="false" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + EmbedManifest="true" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath="BitMachine.cpp" + > + </File> + </Filter> + <Filter + Name="Statechart Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + <File + RelativePath="..\..\..\..\boost\statechart\asynchronous_state_machine.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\custom_reaction.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\deep_history.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\deferral.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event_base.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event_processor.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\exception_translator.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\fifo_scheduler.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\in_state_reaction.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\null_exception_translator.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\result.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\shallow_history.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\simple_state.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\state.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\state_machine.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\termination.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\transition.hpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + > + <File + RelativePath=".\UniqueObject.hpp" + > + </File> + <File + RelativePath=".\UniqueObjectAllocator.hpp" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/boost/libs/statechart/example/BitMachine/UniqueObject.hpp b/src/boost/libs/statechart/example/BitMachine/UniqueObject.hpp new file mode 100644 index 000000000..d4e0cb288 --- /dev/null +++ b/src/boost/libs/statechart/example/BitMachine/UniqueObject.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_STATECHART_EXAMPLE_UNIQUE_OBJECT_HPP_INCLUDED +#define BOOST_STATECHART_EXAMPLE_UNIQUE_OBJECT_HPP_INCLUDED +////////////////////////////////////////////////////////////////////////////// +// 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) +////////////////////////////////////////////////////////////////////////////// + + + +#include "UniqueObjectAllocator.hpp" + +#include <cstddef> // size_t + + + +////////////////////////////////////////////////////////////////////////////// +template< class Derived > +class UniqueObject +{ + public: + ////////////////////////////////////////////////////////////////////////// + void * operator new( std::size_t size ) + { + return UniqueObjectAllocator< Derived >::allocate( size ); + } + + void operator delete( void * p, std::size_t size ) + { + UniqueObjectAllocator< Derived >::deallocate( p, size ); + } + + protected: + ////////////////////////////////////////////////////////////////////////// + UniqueObject() {} + ~UniqueObject() {} +}; + + + +#endif diff --git a/src/boost/libs/statechart/example/BitMachine/UniqueObjectAllocator.hpp b/src/boost/libs/statechart/example/BitMachine/UniqueObjectAllocator.hpp new file mode 100644 index 000000000..09c8836f3 --- /dev/null +++ b/src/boost/libs/statechart/example/BitMachine/UniqueObjectAllocator.hpp @@ -0,0 +1,78 @@ +#ifndef BOOST_STATECHART_EXAMPLE_UNIQUE_OBJECT_ALLOCATOR_HPP_INCLUDED +#define BOOST_STATECHART_EXAMPLE_UNIQUE_OBJECT_ALLOCATOR_HPP_INCLUDED +////////////////////////////////////////////////////////////////////////////// +// 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) +////////////////////////////////////////////////////////////////////////////// + + + +#include <boost/statechart/detail/avoid_unused_warning.hpp> + +#include <boost/config.hpp> + +#ifdef BOOST_MSVC +# pragma warning( push ) +# pragma warning( disable: 4511 ) // copy constructor could not be generated +# pragma warning( disable: 4512 ) // assignment operator could not be generated +#endif + +#include <boost/type_traits/alignment_of.hpp> + +#ifdef BOOST_MSVC +# pragma warning( pop ) +#endif + +#include <boost/type_traits/type_with_alignment.hpp> +#include <boost/assert.hpp> + +#include <cstddef> // size_t + + + +////////////////////////////////////////////////////////////////////////////// +template< class T > +class UniqueObjectAllocator +{ + public: + ////////////////////////////////////////////////////////////////////////// + static void * allocate( std::size_t size ) + { + boost::statechart::detail::avoid_unused_warning( size ); + BOOST_ASSERT( !constructed_ && ( size == sizeof( T ) ) ); + constructed_ = true; + return &storage_.data_[ 0 ]; + } + + static void deallocate( void * p, std::size_t size ) + { + boost::statechart::detail::avoid_unused_warning( p ); + boost::statechart::detail::avoid_unused_warning( size ); + BOOST_ASSERT( constructed_ && + ( p == &storage_.data_[ 0 ] ) && ( size == sizeof( T ) ) ); + constructed_ = false; + } + + private: + ////////////////////////////////////////////////////////////////////////// + union storage + { + char data_[ sizeof( T ) ]; + typename boost::type_with_alignment< + boost::alignment_of< T >::value >::type aligner_; + }; + + static bool constructed_; + static storage storage_; +}; + +template< class T > +bool UniqueObjectAllocator< T >::constructed_ = false; +template< class T > +typename UniqueObjectAllocator< T >::storage + UniqueObjectAllocator< T >::storage_; + + + +#endif diff --git a/src/boost/libs/statechart/example/Camera/Camera.cpp b/src/boost/libs/statechart/example/Camera/Camera.cpp new file mode 100644 index 000000000..8e4a984c4 --- /dev/null +++ b/src/boost/libs/statechart/example/Camera/Camera.cpp @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////////// +// 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) +////////////////////////////////////////////////////////////////////////////// + + + +#include "Precompiled.hpp" +#include "Camera.hpp" +#include "Configuring.hpp" +#include "Shooting.hpp" + + + +////////////////////////////////////////////////////////////////////////////// +NotShooting::NotShooting() +{ + std::cout << "Entering NotShooting\n"; +} + +NotShooting::~NotShooting() +{ + std::cout << "Exiting NotShooting\n"; +} + +sc::result NotShooting::react( const EvShutterHalf & ) +{ + if ( context< Camera >().IsBatteryLow() ) + { + return forward_event(); + } + else + { + return transit< Shooting >(); + } +} + +////////////////////////////////////////////////////////////////////////////// +Idle::Idle() +{ + std::cout << "Entering Idle\n"; +} + +Idle::~Idle() +{ + std::cout << "Exiting Idle\n"; +} + +sc::result Idle::react( const EvConfig & ) +{ + return transit< Configuring >(); +} diff --git a/src/boost/libs/statechart/example/Camera/Camera.hpp b/src/boost/libs/statechart/example/Camera/Camera.hpp new file mode 100644 index 000000000..11bdf639f --- /dev/null +++ b/src/boost/libs/statechart/example/Camera/Camera.hpp @@ -0,0 +1,64 @@ +#ifndef BOOST_STATECHART_EXAMPLE_CAMERA_HPP_INCLUDED +#define BOOST_STATECHART_EXAMPLE_CAMERA_HPP_INCLUDED +////////////////////////////////////////////////////////////////////////////// +// 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) +////////////////////////////////////////////////////////////////////////////// + + + +#include <boost/statechart/event.hpp> +#include <boost/statechart/state_machine.hpp> +#include <boost/statechart/simple_state.hpp> +#include <boost/statechart/custom_reaction.hpp> + +#include <boost/config.hpp> + +#ifdef BOOST_INTEL +# pragma warning( disable: 304 ) // access control not specified +#endif + + + +namespace sc = boost::statechart; + + + +////////////////////////////////////////////////////////////////////////////// +struct EvShutterHalf : sc::event< EvShutterHalf > {}; +struct EvShutterFull : sc::event< EvShutterFull > {}; +struct EvShutterRelease : sc::event< EvShutterRelease > {}; +struct EvConfig : sc::event< EvConfig > {}; + +struct NotShooting; +struct Camera : sc::state_machine< Camera, NotShooting > +{ + bool IsMemoryAvailable() const { return true; } + bool IsBatteryLow() const { return false; } +}; + +struct Idle; +struct NotShooting : sc::simple_state< NotShooting, Camera, Idle > +{ + typedef sc::custom_reaction< EvShutterHalf > reactions; + + NotShooting(); + ~NotShooting(); + + sc::result react( const EvShutterHalf & ); +}; + + struct Idle : sc::simple_state< Idle, NotShooting > + { + typedef sc::custom_reaction< EvConfig > reactions; + + Idle(); + ~Idle(); + + sc::result react( const EvConfig & ); + }; + + + +#endif diff --git a/src/boost/libs/statechart/example/Camera/Camera.vcproj b/src/boost/libs/statechart/example/Camera/Camera.vcproj new file mode 100644 index 000000000..b6e4edcb8 --- /dev/null +++ b/src/boost/libs/statechart/example/Camera/Camera.vcproj @@ -0,0 +1,335 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="Camera" + ProjectGUID="{7FD5B025-1675-4D68-BA85-588AFC99C5B8}" + RootNamespace="Camera" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + ForceConformanceInForLoopScope="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="2" + PrecompiledHeaderThrough="Precompiled.hpp" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/Camera.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/Camera.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="..\..\..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + ForceConformanceInForLoopScope="true" + UsePrecompiledHeader="2" + PrecompiledHeaderThrough="Precompiled.hpp" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/Camera.exe" + LinkIncremental="1" + GenerateDebugInformation="false" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath="Camera.cpp" + > + </File> + <File + RelativePath=".\Configuring.cpp" + > + </File> + <File + RelativePath="Main.cpp" + > + </File> + <File + RelativePath="Precompiled.cpp" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\Shooting.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + <File + RelativePath="Camera.hpp" + > + </File> + <File + RelativePath="Configuring.hpp" + > + </File> + <File + RelativePath="Precompiled.hpp" + > + </File> + <File + RelativePath="Shooting.hpp" + > + </File> + </Filter> + <Filter + Name="Statechart Header Files" + > + <File + RelativePath="..\..\..\..\boost\statechart\asynchronous_state_machine.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\custom_reaction.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\deep_history.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\deferral.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event_base.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event_processor.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\exception_translator.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\fifo_scheduler.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\in_state_reaction.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\null_exception_translator.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\result.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\shallow_history.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\simple_state.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\state.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\state_machine.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\termination.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\transition.hpp" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/boost/libs/statechart/example/Camera/Configuring.cpp b/src/boost/libs/statechart/example/Camera/Configuring.cpp new file mode 100644 index 000000000..f524a88af --- /dev/null +++ b/src/boost/libs/statechart/example/Camera/Configuring.cpp @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////////// +// 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) +////////////////////////////////////////////////////////////////////////////// + + + +#include "Precompiled.hpp" +#include "Configuring.hpp" +#include <iostream> +#include <stdexcept> + + + +Configuring::Configuring() +{ + std::cout << "Entering Configuring\n"; +} + +Configuring::~Configuring() +{ + std::cout << "Exiting Configuring\n"; +} diff --git a/src/boost/libs/statechart/example/Camera/Configuring.hpp b/src/boost/libs/statechart/example/Camera/Configuring.hpp new file mode 100644 index 000000000..39819e5fb --- /dev/null +++ b/src/boost/libs/statechart/example/Camera/Configuring.hpp @@ -0,0 +1,39 @@ +#ifndef BOOST_STATECHART_EXAMPLE_CONFIGURING_HPP_INCLUDED +#define BOOST_STATECHART_EXAMPLE_CONFIGURING_HPP_INCLUDED +////////////////////////////////////////////////////////////////////////////// +// 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) +////////////////////////////////////////////////////////////////////////////// + + + +#include "Camera.hpp" + +#include <boost/statechart/simple_state.hpp> +#include <boost/statechart/transition.hpp> + +#include <boost/config.hpp> + +#ifdef BOOST_INTEL +# pragma warning( disable: 304 ) // access control not specified +#endif + + + +namespace sc = boost::statechart; + + + +////////////////////////////////////////////////////////////////////////////// +struct Configuring : sc::simple_state< Configuring, NotShooting > +{ + typedef sc::transition< EvConfig, Idle > reactions; + + Configuring(); + ~Configuring(); +}; + + + +#endif diff --git a/src/boost/libs/statechart/example/Camera/Main.cpp b/src/boost/libs/statechart/example/Camera/Main.cpp new file mode 100644 index 000000000..d99bfe9e4 --- /dev/null +++ b/src/boost/libs/statechart/example/Camera/Main.cpp @@ -0,0 +1,110 @@ +////////////////////////////////////////////////////////////////////////////// +// 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) +////////////////////////////////////////////////////////////////////////////// + + + +////////////////////////////////////////////////////////////////////////////// +// This program shows how a state machine can be spread over several +// translation units if necessary. The inner workings of a digital camera are +// modeled, the corresponding state chart looks as follows: +// +// --------------------------- +// | | +// | NotShooting | +// | | +// | ------------- |<---O +// | O--->| Idle | | -------------- +// | ------------- | EvShutterHalf | | +// | | ^ |------------------>| Shooting | +// | EvConfig | | EvConfig | | | +// | v | | EvShutterRelease | | +// | ------------- |<------------------| | +// | | Configuring | | | | +// | ------------- | -------------- +// --------------------------- +// +// The states Configuring and Shooting will contain a large amount of logic, +// so they are implemented in their own translation units. This way one team +// could implement the Configuring mode while the other would work on the +// Shooting mode. Once the above state chart is implemented, the teams could +// work completely independently of each other. + + + +#include "Precompiled.hpp" +#include "Camera.hpp" +#include <iostream> + + + +////////////////////////////////////////////////////////////////////////////// +char GetKey() +{ + char key; + std::cin >> key; + return key; +} + + +////////////////////////////////////////////////////////////////////////////// +int main() +{ + std::cout << "Boost.Statechart Camera example\n\n"; + + std::cout << "h<CR>: Press shutter half-way\n"; + std::cout << "f<CR>: Press shutter fully\n"; + std::cout << "r<CR>: Release shutter\n"; + std::cout << "c<CR>: Enter/exit configuration\n"; + std::cout << "e<CR>: Exits the program\n\n"; + std::cout << "You may chain commands, e.g. hfr<CR> first presses the shutter half-way,\n"; + std::cout << "fully and then releases it.\n\n"; + + + Camera myCamera; + myCamera.initiate(); + + char key = GetKey(); + + while ( key != 'e' ) + { + switch( key ) + { + case 'h': + { + myCamera.process_event( EvShutterHalf() ); + } + break; + + case 'f': + { + myCamera.process_event( EvShutterFull() ); + } + break; + + case 'r': + { + myCamera.process_event( EvShutterRelease() ); + } + break; + + case 'c': + { + myCamera.process_event( EvConfig() ); + } + break; + + default: + { + std::cout << "Invalid key!\n"; + } + break; + } + + key = GetKey(); + } + + return 0; +} diff --git a/src/boost/libs/statechart/example/Camera/Precompiled.cpp b/src/boost/libs/statechart/example/Camera/Precompiled.cpp new file mode 100644 index 000000000..c85c33d38 --- /dev/null +++ b/src/boost/libs/statechart/example/Camera/Precompiled.cpp @@ -0,0 +1,9 @@ +////////////////////////////////////////////////////////////////////////////// +// 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) +////////////////////////////////////////////////////////////////////////////// + + + +#include "Precompiled.hpp" diff --git a/src/boost/libs/statechart/example/Camera/Precompiled.hpp b/src/boost/libs/statechart/example/Camera/Precompiled.hpp new file mode 100644 index 000000000..ad71c5e63 --- /dev/null +++ b/src/boost/libs/statechart/example/Camera/Precompiled.hpp @@ -0,0 +1,20 @@ +#ifndef BOOST_STATECHART_EXAMPLE_PRECOMPILED_HPP_INCLUDED +#define BOOST_STATECHART_EXAMPLE_PRECOMPILED_HPP_INCLUDED +////////////////////////////////////////////////////////////////////////////// +// 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) +////////////////////////////////////////////////////////////////////////////// + + + +#include <boost/statechart/state_machine.hpp> +#include <boost/statechart/event.hpp> +#include <boost/statechart/simple_state.hpp> +#include <boost/statechart/custom_reaction.hpp> +#include <boost/mpl/list.hpp> +#include <iostream> + + + +#endif diff --git a/src/boost/libs/statechart/example/Camera/Shooting.cpp b/src/boost/libs/statechart/example/Camera/Shooting.cpp new file mode 100644 index 000000000..ae9a1abce --- /dev/null +++ b/src/boost/libs/statechart/example/Camera/Shooting.cpp @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////////// +// 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) +////////////////////////////////////////////////////////////////////////////// + + + +#include "Precompiled.hpp" +#include "Shooting.hpp" +#include <iostream> + +#include <boost/config.hpp> + +#ifdef BOOST_INTEL +# pragma warning( disable: 383 ) // reference to temporary used +#endif + + + +////////////////////////////////////////////////////////////////////////////// +Shooting::Shooting() +{ + std::cout << "Entering Shooting\n"; +} + +Shooting::~Shooting() +{ + std::cout << "Exiting Shooting\n"; +} + +////////////////////////////////////////////////////////////////////////////// +struct Storing : sc::simple_state< Storing, Shooting > +{ + Storing() + { + std::cout << "Picture taken!\n"; + } +}; + +////////////////////////////////////////////////////////////////////////////// +struct Focused : sc::simple_state< Focused, Shooting > +{ + typedef sc::custom_reaction< EvShutterFull > reactions; + + sc::result react( const EvShutterFull & ); +}; + +sc::result Focused::react( const EvShutterFull & ) +{ + if ( context< Camera >().IsMemoryAvailable() ) + { + return transit< Storing >(); + } + else + { + std::cout << "Cache memory full. Please wait...\n"; + return discard_event(); + } +} + +////////////////////////////////////////////////////////////////////////////// +Focusing::Focusing( my_context ctx ) : my_base( ctx ) +{ + post_event( boost::intrusive_ptr< EvInFocus >( new EvInFocus() ) ); +} + +sc::result Focusing::react( const EvInFocus & evt ) +{ + return transit< Focused >( &Shooting::DisplayFocused, evt ); +} diff --git a/src/boost/libs/statechart/example/Camera/Shooting.hpp b/src/boost/libs/statechart/example/Camera/Shooting.hpp new file mode 100644 index 000000000..1ae85d924 --- /dev/null +++ b/src/boost/libs/statechart/example/Camera/Shooting.hpp @@ -0,0 +1,64 @@ +#ifndef BOOST_STATECHART_EXAMPLE_SHOOTING_HPP_INCLUDED +#define BOOST_STATECHART_EXAMPLE_SHOOTING_HPP_INCLUDED +////////////////////////////////////////////////////////////////////////////// +// 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) +////////////////////////////////////////////////////////////////////////////// + + + +#include "Camera.hpp" + +#include <boost/statechart/event.hpp> +#include <boost/statechart/simple_state.hpp> +#include <boost/statechart/state.hpp> +#include <boost/statechart/transition.hpp> +#include <boost/statechart/custom_reaction.hpp> +#include <boost/statechart/deferral.hpp> + +#include <boost/mpl/list.hpp> +#include <boost/config.hpp> + +#ifdef BOOST_INTEL +# pragma warning( disable: 304 ) // access control not specified +#endif + + + +namespace sc = boost::statechart; +namespace mpl = boost::mpl; + + + +////////////////////////////////////////////////////////////////////////////// +struct EvInFocus : sc::event< EvInFocus > {}; + +struct Focusing; +struct Shooting : sc::simple_state< Shooting, Camera, Focusing > +{ + typedef sc::transition< EvShutterRelease, NotShooting > reactions; + + Shooting(); + ~Shooting(); + + void DisplayFocused( const EvInFocus & ) + { + std::cout << "Focused!\n"; + } +}; + + struct Focusing : sc::state< Focusing, Shooting > + { + typedef mpl::list< + sc::custom_reaction< EvInFocus >, + sc::deferral< EvShutterFull > + > reactions; + + Focusing( my_context ctx ); + sc::result react( const EvInFocus & ); + }; + + + +#endif diff --git a/src/boost/libs/statechart/example/Handcrafted/Handcrafted.cpp b/src/boost/libs/statechart/example/Handcrafted/Handcrafted.cpp new file mode 100644 index 000000000..7b77c26f4 --- /dev/null +++ b/src/boost/libs/statechart/example/Handcrafted/Handcrafted.cpp @@ -0,0 +1,205 @@ +////////////////////////////////////////////////////////////////////////////// +// 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) +////////////////////////////////////////////////////////////////////////////// + + + +////////////////////////////////////////////////////////////////////////////// +// This is a quick-and-dirty handcrafted state machine with two states and two +// transitions employing GOF-visitation (two virtual calls per event). +// It is used to make speed comparisons with Boost.Statechart machines. +////////////////////////////////////////////////////////////////////////////// + + + +#include <boost/config.hpp> + +#include <iostream> +#include <iomanip> +#include <ctime> + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std +{ + using ::clock_t; + using ::clock; +} +#endif + +#ifdef BOOST_INTEL +# pragma warning( disable: 304 ) // access control not specified +#endif + + + +////////////////////////////////////////////////////////////////////////////// +class EvFlipBit; +class state_base +{ + public: + virtual ~state_base() {}; + + virtual const state_base & react( const EvFlipBit & toEvent ) const = 0; + + protected: + state_base() {} +}; + +template< class Derived > +class state : public state_base +{ + public: + state() : state_base() { } + + static const Derived & instance() + { + return instance_; + } + + private: + static const Derived instance_; +}; + +template< class Derived > +const Derived state< Derived >::instance_; + + +////////////////////////////////////////////////////////////////////////////// +class event_base +{ + public: + virtual ~event_base() {} + + protected: + event_base() {} + + public: + virtual const state_base & send( const state_base & toState ) const = 0; +}; + +template< class Derived > +class event : public event_base +{ + protected: + event() {} + + private: + virtual const state_base & send( const state_base & toState ) const + { + return toState.react( *static_cast< const Derived * >( this ) ); + } +}; + + +////////////////////////////////////////////////////////////////////////////// +class EvFlipBit : public event< EvFlipBit > { +public: + EvFlipBit() : event < EvFlipBit >() { } +}; +const EvFlipBit flip; + +class BitMachine +{ + public: + ////////////////////////////////////////////////////////////////////////// + BitMachine() : pCurrentState_( &Off::instance() ) {} + + void process_event( const event_base & evt ) + { + pCurrentState_ = &evt.send( *pCurrentState_ ); + } + + private: + ////////////////////////////////////////////////////////////////////////// + struct On : state< On > + { + On() : state<On>() { } + + virtual const state_base & react( const EvFlipBit & ) const + { + return Off::instance(); + } + }; + + struct Off : state< Off > + { + Off() : state<Off>() { } + + virtual const state_base & react( const EvFlipBit & ) const + { + return On::instance(); + } + }; + + const state_base * pCurrentState_; +}; + + +////////////////////////////////////////////////////////////////////////////// +char GetKey() +{ + char key; + std::cin >> key; + return key; +} + + +////////////////////////////////////////////////////////////////////////////// +int main() +{ + // common prime factors of 2^n-1 for n in [1,8] + const unsigned int noOfEvents = 3 * 3 * 5 * 7 * 17 * 31 * 127; + unsigned long eventsSentTotal = 0; + + std::cout << "Boost.Statechart Handcrafted example\n"; + std::cout << "Machine configuration: " << 2 << + " states interconnected with " << 2 << " transitions.\n\n"; + + std::cout << "p<CR>: Performance test\n"; + std::cout << "e<CR>: Exits the program\n\n"; + std::cout << + "You may chain commands, e.g. pe<CR> performs a test and then exits the program\n\n"; + + BitMachine bitMachine; + + char key = GetKey(); + + while ( key != 'e' ) + { + switch ( key ) + { + case 'p': + { + std::cout << "\nSending " << noOfEvents << + " events. Please wait...\n"; + + const unsigned long startEvents2 = eventsSentTotal; + const std::clock_t startTime2 = std::clock(); + + for ( unsigned int eventNo = 0; eventNo < noOfEvents; ++eventNo ) + { + bitMachine.process_event( flip ); + ++eventsSentTotal; + } + + const std::clock_t elapsedTime2 = std::clock() - startTime2; + const unsigned int eventsSent2 = eventsSentTotal - startEvents2; + std::cout << "Time to dispatch one event and\n" << + "perform the resulting transition: "; + std::cout << elapsedTime2 * 1000.0 / eventsSent2 << " microseconds\n\n"; + } + break; + + default: + { + std::cout << "Invalid key!\n"; + } + } + + key = GetKey(); + } + + return 0; +} diff --git a/src/boost/libs/statechart/example/Handcrafted/Handcrafted.vcproj b/src/boost/libs/statechart/example/Handcrafted/Handcrafted.vcproj new file mode 100644 index 000000000..6cda53079 --- /dev/null +++ b/src/boost/libs/statechart/example/Handcrafted/Handcrafted.vcproj @@ -0,0 +1,205 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="Handcrafted" + ProjectGUID="{155DB9E1-28AC-4671-8248-5FD03E8FCDAD}" + RootNamespace="Handcrafted" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + ForceConformanceInForLoopScope="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/Handcrafted.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/Handcrafted.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300" + Optimization="3" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="..\..\..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + ForceConformanceInForLoopScope="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/Handcrafted.exe" + LinkIncremental="1" + GenerateDebugInformation="false" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath="Handcrafted.cpp" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/boost/libs/statechart/example/Jamfile.v2 b/src/boost/libs/statechart/example/Jamfile.v2 new file mode 100644 index 000000000..2a4851ca1 --- /dev/null +++ b/src/boost/libs/statechart/example/Jamfile.v2 @@ -0,0 +1,75 @@ +############################################################################## +# Copyright 2005-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) +############################################################################## + +project libs/statechart/example ; + +local custom = <define>CUSTOMIZE_MEMORY_MANAGEMENT ; +local native = <define>BOOST_STATECHART_USE_NATIVE_RTTI ; + +rule independent-obj-build ( + name : directory : cpp-sources + : requirements * ) +{ + local objs ; + + for local cpp-source in $(cpp-sources) + { + obj $(name)$(cpp-source) + : $(directory)/$(cpp-source).cpp : $(requirements) ; + objs += $(name)$(cpp-source) ; + } + + return $(objs) ; +} + +rule statechart-st-example-build ( + name : directory : cpp-sources + : requirements * ) +{ + exe $(name) : [ independent-obj-build $(name) + : $(directory) : $(cpp-sources) + # Some platforms have either problems with the automatic + # detection of the threading mode (e.g. vc-7_1 & + # gcc >= 3.4.0) or don't support single-threaded mode + # (e.g. vc-8_0). We therefore manually turn MT + # off here + : <threading>single <define>BOOST_DISABLE_THREADS $(requirements) ] ; + + return $(name) ; +} + +rule statechart-mt-example-build ( + name : directory : cpp-sources + : requirements * ) +{ + exe $(name) : [ independent-obj-build $(name) + : $(directory) : $(cpp-sources) + : <threading>multi $(requirements) ] + ../../thread/build//boost_thread ; + + return $(name) ; +} + +stage run + : [ statechart-st-example-build BitMachine : BitMachine : BitMachine ] + [ statechart-st-example-build Camera + : Camera : Camera Configuring Main Shooting ] + [ statechart-st-example-build Handcrafted : Handcrafted : Handcrafted ] + [ statechart-st-example-build KeyboardNormal : Keyboard : Keyboard ] + [ statechart-st-example-build KeyboardNative + : Keyboard : Keyboard : $(native) ] + [ statechart-st-example-build PingPongSingle + : PingPong : PingPong Player : $(custom) ] + [ statechart-mt-example-build PingPongMulti1 + : PingPong : PingPong Player : $(custom) ] + [ statechart-mt-example-build PingPongMulti2 + : PingPong : PingPong Player : $(custom) <define>USE_TWO_THREADS ] + [ statechart-st-example-build StopWatch : StopWatch : StopWatch ] + [ statechart-st-example-build StopWatch2 : StopWatch : StopWatch2 ] + [ statechart-st-example-build PerformanceNormal + : Performance : Performance ] + [ statechart-st-example-build PerformanceCustom + : Performance : Performance : $(custom) ] + [ statechart-st-example-build PerformanceNative + : Performance : Performance : $(native) ] + : <install-dependencies>on <install-type>EXE <install-type>SHARED_LIB ; diff --git a/src/boost/libs/statechart/example/Keyboard/Keyboard.cpp b/src/boost/libs/statechart/example/Keyboard/Keyboard.cpp new file mode 100644 index 000000000..e9f086720 --- /dev/null +++ b/src/boost/libs/statechart/example/Keyboard/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 <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; +} diff --git a/src/boost/libs/statechart/example/Keyboard/Keyboard.vcproj b/src/boost/libs/statechart/example/Keyboard/Keyboard.vcproj new file mode 100644 index 000000000..9ce6ac0ac --- /dev/null +++ b/src/boost/libs/statechart/example/Keyboard/Keyboard.vcproj @@ -0,0 +1,284 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="Keyboard" + ProjectGUID="{4CBF564B-EEC6-49E1-B69B-CABF5DDFC684}" + RootNamespace="Keyboard" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + ExceptionHandling="1" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + ForceConformanceInForLoopScope="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/Keyboard.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/Keyboard.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="..\..\..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + StringPooling="true" + ExceptionHandling="1" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + ForceConformanceInForLoopScope="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/Keyboard.exe" + LinkIncremental="1" + GenerateDebugInformation="false" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\Keyboard.cpp" + > + </File> + </Filter> + <Filter + Name="Statechart Header Files" + > + <File + RelativePath="..\..\..\..\boost\statechart\asynchronous_state_machine.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\custom_reaction.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\deep_history.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\deferral.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event_base.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event_processor.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\exception_translator.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\fifo_scheduler.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\in_state_reaction.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\null_exception_translator.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\result.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\shallow_history.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\simple_state.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\state.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\state_machine.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\termination.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\transition.hpp" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/boost/libs/statechart/example/Performance/Performance.cpp b/src/boost/libs/statechart/example/Performance/Performance.cpp new file mode 100644 index 000000000..7b127ce26 --- /dev/null +++ b/src/boost/libs/statechart/example/Performance/Performance.cpp @@ -0,0 +1,522 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright 2005-2008 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) +////////////////////////////////////////////////////////////////////////////// + + + +////////////////////////////////////////////////////////////////////////////// +// #define CUSTOMIZE_MEMORY_MANAGEMENT +// #define BOOST_STATECHART_USE_NATIVE_RTTI +////////////////////////////////////////////////////////////////////////////// +// This program measures event processing performance of the BitMachine +// (see BitMachine example for more information) with a varying number of +// states. Also, a varying number of transitions are replaced with in-state +// reactions. This allows us to calculate how much time is spent for state- +// entry and state-exit during a transition. All measurements are written to +// comma-separated-values files, one file for each individual BitMachine. +////////////////////////////////////////////////////////////////////////////// + + + +#include <boost/statechart/event.hpp> +#include <boost/statechart/simple_state.hpp> +#include <boost/statechart/state_machine.hpp> +#include <boost/statechart/transition.hpp> +#include <boost/statechart/in_state_reaction.hpp> + +#include <boost/mpl/list.hpp> +#include <boost/mpl/front_inserter.hpp> +#include <boost/mpl/transform_view.hpp> +#include <boost/mpl/copy.hpp> +#include <boost/mpl/range_c.hpp> +#include <boost/mpl/integral_c.hpp> +#include <boost/mpl/shift_left.hpp> +#include <boost/mpl/bitxor.hpp> +#include <boost/mpl/for_each.hpp> +#include <boost/mpl/placeholders.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/less.hpp> +#include <boost/mpl/aux_/lambda_support.hpp> + +#include <boost/intrusive_ptr.hpp> +#include <boost/config.hpp> +#include <boost/assert.hpp> + +#ifdef CUSTOMIZE_MEMORY_MANAGEMENT +# ifdef BOOST_MSVC +# pragma warning( push ) +# pragma warning( disable: 4127 ) // conditional expression is constant +# pragma warning( disable: 4800 ) // forcing value to bool 'true' or 'false' +# endif +# define BOOST_NO_MT +# include <boost/pool/pool_alloc.hpp> +# ifdef BOOST_MSVC +# pragma warning( pop ) +# endif +#endif + +#include <vector> +#include <ctime> +#include <iostream> +#include <fstream> +#include <iomanip> +#include <ios> +#include <string> +#include <algorithm> + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std +{ + using ::clock_t; + using ::clock; +} +#endif + +#ifdef BOOST_INTEL +# pragma warning( disable: 304 ) // access control not specified +# pragma warning( disable: 444 ) // destructor for base is not virtual +# pragma warning( disable: 981 ) // operands are evaluated in unspecified order +#endif + + + +namespace sc = boost::statechart; +namespace mpl = boost::mpl; + + + +////////////////////////////////////////////////////////////////////////////// +typedef mpl::integral_c< unsigned int, 0 > uint0; +typedef mpl::integral_c< unsigned int, 1 > uint1; +typedef mpl::integral_c< unsigned int, 2 > uint2; +typedef mpl::integral_c< unsigned int, 3 > uint3; +typedef mpl::integral_c< unsigned int, 4 > uint4; +typedef mpl::integral_c< unsigned int, 5 > uint5; +typedef mpl::integral_c< unsigned int, 6 > uint6; +typedef mpl::integral_c< unsigned int, 7 > uint7; +typedef mpl::integral_c< unsigned int, 8 > uint8; +typedef mpl::integral_c< unsigned int, 9 > uint9; + +////////////////////////////////////////////////////////////////////////////// +template< class BitNo > +struct EvFlipBit : sc::event< EvFlipBit< BitNo > > {}; + +boost::intrusive_ptr< const sc::event_base > pFlipBitEvents[] = +{ + new EvFlipBit< uint0 >, + new EvFlipBit< uint1 >, + new EvFlipBit< uint2 >, + new EvFlipBit< uint3 >, + new EvFlipBit< uint4 >, + new EvFlipBit< uint5 >, + new EvFlipBit< uint6 >, + new EvFlipBit< uint7 >, + new EvFlipBit< uint8 >, + new EvFlipBit< uint9 > +}; + + +////////////////////////////////////////////////////////////////////////////// +template< + class StateNo, + class NoOfBits, + class FirstTransitionBit > +struct BitState; + +template< class NoOfBits, class FirstTransitionBit > +struct BitMachine : sc::state_machine< + BitMachine< NoOfBits, FirstTransitionBit >, + BitState< uint0, NoOfBits, FirstTransitionBit > + #ifdef CUSTOMIZE_MEMORY_MANAGEMENT + , boost::fast_pool_allocator< int > + #endif +> +{ + public: + BitMachine() : inStateReactions_( 0 ), transitions_( 0 ) {} + + // GCC 3.4.2 doesn't seem to instantiate a function template despite the + // fact that an address of the instantiation is passed as a non-type + // template argument. This leads to linker errors when a function template + // is defined instead of the overloads below. + void InStateReaction( const EvFlipBit< uint0 > & ) + { + ++inStateReactions_; + } + + void InStateReaction( const EvFlipBit< uint1 > & ) + { + ++inStateReactions_; + } + + void InStateReaction( const EvFlipBit< uint2 > & ) + { + ++inStateReactions_; + } + + void InStateReaction( const EvFlipBit< uint3 > & ) + { + ++inStateReactions_; + } + + void InStateReaction( const EvFlipBit< uint4 > & ) + { + ++inStateReactions_; + } + + void InStateReaction( const EvFlipBit< uint5 > & ) + { + ++inStateReactions_; + } + + void InStateReaction( const EvFlipBit< uint6 > & ) + { + ++inStateReactions_; + } + + void InStateReaction( const EvFlipBit< uint7 > & ) + { + ++inStateReactions_; + } + + void InStateReaction( const EvFlipBit< uint8 > & ) + { + ++inStateReactions_; + } + + void InStateReaction( const EvFlipBit< uint9 > & ) + { + ++inStateReactions_; + } + + void Transition( const EvFlipBit< uint0 > & ) + { + ++transitions_; + } + + void Transition( const EvFlipBit< uint1 > & ) + { + ++transitions_; + } + + void Transition( const EvFlipBit< uint2 > & ) + { + ++transitions_; + } + + void Transition( const EvFlipBit< uint3 > & ) + { + ++transitions_; + } + + void Transition( const EvFlipBit< uint4 > & ) + { + ++transitions_; + } + + void Transition( const EvFlipBit< uint5 > & ) + { + ++transitions_; + } + + void Transition( const EvFlipBit< uint6 > & ) + { + ++transitions_; + } + + void Transition( const EvFlipBit< uint7 > & ) + { + ++transitions_; + } + + void Transition( const EvFlipBit< uint8 > & ) + { + ++transitions_; + } + + void Transition( const EvFlipBit< uint9 > & ) + { + ++transitions_; + } + + unsigned int GetNoOfInStateReactions() const + { + return inStateReactions_; + } + + unsigned int GetNoOfTransitions() const + { + return transitions_; + } + + private: + unsigned int inStateReactions_; + unsigned int transitions_; +}; + +////////////////////////////////////////////////////////////////////////////// +template< + class BitNo, class StateNo, class NoOfBits, class FirstTransitionBit > +struct FlipTransition +{ + private: + typedef typename mpl::bitxor_< + StateNo, + mpl::shift_left< uint1, BitNo > + >::type NextStateNo; + + public: + typedef typename mpl::if_< + mpl::less< BitNo, FirstTransitionBit >, + sc::in_state_reaction< + EvFlipBit< BitNo >, + BitMachine< NoOfBits, FirstTransitionBit >, + &BitMachine< NoOfBits, FirstTransitionBit >::InStateReaction >, + sc::transition< + EvFlipBit< BitNo >, + BitState< NextStateNo, NoOfBits, FirstTransitionBit >, + BitMachine< NoOfBits, FirstTransitionBit >, + &BitMachine< NoOfBits, FirstTransitionBit >::Transition > + >::type type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT( + 3, FlipTransition, (BitNo, StateNo, FirstTransitionBit) ); +}; + +////////////////////////////////////////////////////////////////////////////// +template< + class StateNo, + class NoOfBits, + class FirstTransitionBit > +struct BitState : sc::simple_state< + BitState< StateNo, NoOfBits, FirstTransitionBit >, + BitMachine< NoOfBits, FirstTransitionBit > > +{ + typedef typename mpl::copy< + typename mpl::transform_view< + mpl::range_c< unsigned int, 0, NoOfBits::value >, + FlipTransition< + mpl::placeholders::_, StateNo, NoOfBits, FirstTransitionBit > + >::type, + mpl::front_inserter< mpl::list<> > + >::type reactions; +}; + +// GCC 3.4.2 doesn't seem to instantiate a class template member function +// despite the fact that an address of the function is passed as a non-type +// template argument. This leads to linker errors when the class template +// defining the functions is not explicitly instantiated. +template struct BitMachine< uint1, uint0 >; +template struct BitMachine< uint1, uint1 >; + +template struct BitMachine< uint2, uint0 >; +template struct BitMachine< uint2, uint1 >; +template struct BitMachine< uint2, uint2 >; + +template struct BitMachine< uint3, uint0 >; +template struct BitMachine< uint3, uint1 >; +template struct BitMachine< uint3, uint2 >; +template struct BitMachine< uint3, uint3 >; + +template struct BitMachine< uint4, uint0 >; +template struct BitMachine< uint4, uint1 >; +template struct BitMachine< uint4, uint2 >; +template struct BitMachine< uint4, uint3 >; +template struct BitMachine< uint4, uint4 >; + +template struct BitMachine< uint5, uint0 >; +template struct BitMachine< uint5, uint1 >; +template struct BitMachine< uint5, uint2 >; +template struct BitMachine< uint5, uint3 >; +template struct BitMachine< uint5, uint4 >; +template struct BitMachine< uint5, uint5 >; + +template struct BitMachine< uint6, uint0 >; +template struct BitMachine< uint6, uint1 >; +template struct BitMachine< uint6, uint2 >; +template struct BitMachine< uint6, uint3 >; +template struct BitMachine< uint6, uint4 >; +template struct BitMachine< uint6, uint5 >; +template struct BitMachine< uint6, uint6 >; + +template struct BitMachine< uint7, uint0 >; +template struct BitMachine< uint7, uint1 >; +template struct BitMachine< uint7, uint2 >; +template struct BitMachine< uint7, uint3 >; +template struct BitMachine< uint7, uint4 >; +template struct BitMachine< uint7, uint5 >; +template struct BitMachine< uint7, uint6 >; +template struct BitMachine< uint7, uint7 >; + + +//////////////////////////////////////////////////////////////////////////// +struct PerfResult +{ + PerfResult( double inStateRatio, double nanoSecondsPerReaction ) : + inStateRatio_( inStateRatio ), + nanoSecondsPerReaction_( nanoSecondsPerReaction ) + { + } + + double inStateRatio_; + double nanoSecondsPerReaction_; +}; + +template< class NoOfBits, class FirstTransitionBit > +class PerformanceTester +{ + public: + //////////////////////////////////////////////////////////////////////// + static PerfResult Test() + { + eventsSent_ = 0; + BitMachine< NoOfBits, FirstTransitionBit > machine; + machine.initiate(); + const std::clock_t startTime = std::clock(); + + const unsigned int laps = eventsToSend_ / ( GetNoOfStates() - 1 ); + + for ( unsigned int lap = 0; lap < laps; ++lap ) + { + VisitAllStatesImpl( machine, NoOfBits::value - 1 ); + } + + const std::clock_t elapsedTime = std::clock() - startTime; + + BOOST_ASSERT( eventsSent_ == eventsToSend_ ); + BOOST_ASSERT( + machine.GetNoOfInStateReactions() + + machine.GetNoOfTransitions() == eventsSent_ ); + + return PerfResult( + static_cast< double >( machine.GetNoOfInStateReactions() ) / + eventsSent_, + static_cast< double >( elapsedTime ) / + CLOCKS_PER_SEC * 1000.0 * 1000.0 * 1000.0 / eventsSent_ ); + } + + static unsigned int GetNoOfStates() + { + return 1 << NoOfBits::value; + } + + static unsigned int GetNoOfReactions() + { + return GetNoOfStates() * NoOfBits::value; + } + + private: + //////////////////////////////////////////////////////////////////////// + static void VisitAllStatesImpl( + BitMachine< NoOfBits, FirstTransitionBit > & machine, + unsigned int bit ) + { + if ( bit > 0 ) + { + PerformanceTester< NoOfBits, FirstTransitionBit >:: + VisitAllStatesImpl( machine, bit - 1 ); + } + + machine.process_event( *pFlipBitEvents[ bit ] ); + ++PerformanceTester< NoOfBits, FirstTransitionBit >::eventsSent_; + + if ( bit > 0 ) + { + PerformanceTester< NoOfBits, FirstTransitionBit >:: + VisitAllStatesImpl( machine, bit - 1 ); + } + } + + // common prime factors of 2^n-1 for n in [1,8] + static const unsigned int eventsToSend_ = 3 * 3 * 5 * 7 * 17 * 31 * 127; + static unsigned int eventsSent_; +}; + +template< class NoOfBits, class FirstTransitionBit > +unsigned int PerformanceTester< NoOfBits, FirstTransitionBit >::eventsSent_; + + +////////////////////////////////////////////////////////////////////////////// +typedef std::vector< PerfResult > PerfResultList; + +template< class NoOfBits > +struct PerfResultBackInserter +{ + public: + PerfResultBackInserter( PerfResultList & perfResultList ) : + perfResultList_( perfResultList ) + { + } + + template< class FirstTransitionBit > + void operator()( const FirstTransitionBit & ) + { + perfResultList_.push_back( + PerformanceTester< NoOfBits, FirstTransitionBit >::Test() ); + } + + private: + // avoids C4512 (assignment operator could not be generated) + PerfResultBackInserter & operator=( const PerfResultBackInserter & ); + + PerfResultList & perfResultList_; +}; + +template< class NoOfBits > +std::vector< PerfResult > TestMachine() +{ + PerfResultList result; + + mpl::for_each< mpl::range_c< unsigned int, 0, NoOfBits::value + 1 > >( + PerfResultBackInserter< NoOfBits >( result ) ); + + return result; +} + +template< class NoOfBits > +void TestAndWriteResults() +{ + PerfResultList results = TestMachine< NoOfBits >(); + + std::fstream output; + output.exceptions( + std::ios_base::badbit | std::ios_base::eofbit | std::ios_base::failbit ); + + std::string prefix = std::string( BOOST_COMPILER ) + "__"; + std::replace( prefix.begin(), prefix.end(), ' ', '_' ); + + output.open( + ( prefix + std::string( 1, '0' + static_cast< char >( NoOfBits::value ) ) + + ".txt" ).c_str(), + std::ios_base::out ); + + for ( PerfResultList::const_iterator pResult = results.begin(); + pResult != results.end(); ++pResult ) + { + output << std::fixed << std::setprecision( 0 ) << + std::setw( 8 ) << pResult->inStateRatio_ * 100 << ',' << + std::setw( 8 ) << pResult->nanoSecondsPerReaction_ << "\n"; + } +} + + +////////////////////////////////////////////////////////////////////////////// +int main() +{ + std::cout << + "Boost.Statechart in-state reaction vs. transition performance test\n\n"; + std::cout << "Press <CR> to start the test: "; + + { + std::string input; + std::getline( std::cin, input ); + } + + TestAndWriteResults< uint1 >(); + TestAndWriteResults< uint2 >(); + TestAndWriteResults< uint3 >(); + + return 0; +} diff --git a/src/boost/libs/statechart/example/Performance/Performance.vcproj b/src/boost/libs/statechart/example/Performance/Performance.vcproj new file mode 100644 index 000000000..3f59de013 --- /dev/null +++ b/src/boost/libs/statechart/example/Performance/Performance.vcproj @@ -0,0 +1,285 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="Performance" + ProjectGUID="{045411F0-A746-4DB3-85B9-C9AEDE6D5CBA}" + RootNamespace="Performance" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm800" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + ForceConformanceInForLoopScope="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/Performance.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/Performance.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm800" + Optimization="3" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="..\..\..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + StringPooling="true" + ExceptionHandling="1" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + ForceConformanceInForLoopScope="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/Performance.exe" + LinkIncremental="1" + GenerateDebugInformation="false" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath="Performance.cpp" + > + </File> + </Filter> + <Filter + Name="Statechart Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + <File + RelativePath="..\..\..\..\boost\statechart\asynchronous_state_machine.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\custom_reaction.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\deep_history.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\deferral.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event_base.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event_processor.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\exception_translator.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\fifo_scheduler.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\in_state_reaction.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\null_exception_translator.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\result.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\shallow_history.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\simple_state.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\state.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\state_machine.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\termination.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\transition.hpp" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/boost/libs/statechart/example/Performance/Performance.xls b/src/boost/libs/statechart/example/Performance/Performance.xls Binary files differnew file mode 100644 index 000000000..1eb95ad29 --- /dev/null +++ b/src/boost/libs/statechart/example/Performance/Performance.xls diff --git a/src/boost/libs/statechart/example/PingPong/PingPong.cpp b/src/boost/libs/statechart/example/PingPong/PingPong.cpp new file mode 100644 index 000000000..715ebf98b --- /dev/null +++ b/src/boost/libs/statechart/example/PingPong/PingPong.cpp @@ -0,0 +1,181 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright 2002-2008 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) +////////////////////////////////////////////////////////////////////////////// + + + +////////////////////////////////////////////////////////////////////////////// +// #define USE_TWO_THREADS // ignored for single-threaded builds +// #define CUSTOMIZE_MEMORY_MANAGEMENT +////////////////////////////////////////////////////////////////////////////// +// The following example program demonstrates the use of asynchronous state +// machines. First, it creates two objects of the same simple state machine +// mimicking a table tennis player. It then sends an event (the ball) to the +// first state machine. Upon reception, the first machine sends a similar +// event to the second state machine, which then sends the event back to the +// first machine. The two machines continue to bounce the event back and forth +// until one machine "has enough" and aborts the game. The two players don't +// "know" each other, they can only pass the ball back and forth because the +// event representing the ball also carries two boost::function objects. +// Both reference the fifo_scheduler<>::queue_event() function, binding the +// scheduler and the handle of the opponent. One can be used to return the +// ball to the opponent and the other can be used to abort the game. +// Depending on whether the program is compiled single-threaded or +// multi-threaded and the USE_TWO_THREADS define above, the two +// machines either run in the same thread without/with mutex locking or in two +// different threads with mutex locking. +////////////////////////////////////////////////////////////////////////////// + + +#include "Player.hpp" + +#include <boost/statechart/asynchronous_state_machine.hpp> +#include <boost/statechart/fifo_worker.hpp> + +#include <boost/mpl/list.hpp> +#include <boost/config.hpp> +#include <boost/intrusive_ptr.hpp> +#include <boost/function.hpp> +#include <boost/bind.hpp> + +#ifdef BOOST_HAS_THREADS +# include <boost/thread/thread.hpp> +#endif + +#include <iostream> +#include <ctime> + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std +{ + using ::clock_t; + using ::clock; +} +#endif + +#ifdef BOOST_INTEL +# pragma warning( disable: 304 ) // access control not specified +# pragma warning( disable: 383 ) // reference to temporary used +# pragma warning( disable: 981 ) // operands are evaluated in unspecified order +#endif + + + +namespace sc = boost::statechart; + + + +////////////////////////////////////////////////////////////////////////////// +const unsigned int noOfEvents = 1000000; + + +////////////////////////////////////////////////////////////////////////////// +char GetKey() +{ + char key; + std::cin >> key; + return key; +} + + +////////////////////////////////////////////////////////////////////////////// +int main() +{ + std::cout << "Boost.Statechart PingPong example\n\n"; + std::cout << "Threading configuration:\n"; + #ifdef BOOST_HAS_THREADS + std::cout << "Multi-threaded build with "; + #ifdef USE_TWO_THREADS + std::cout << 2; + #else + std::cout << 1; + #endif + std::cout << " thread(s).\n"; + #else + std::cout << "Single-threaded build\n"; + #endif + + std::cout << "\np<CR>: Performance test\n"; + std::cout << "e<CR>: Exits the program\n\n"; + + char key = GetKey(); + + while ( key != 'e' ) + { + switch( key ) + { + case 'p': + { + #ifdef BOOST_HAS_THREADS + MyScheduler scheduler1( true ); + #else + MyScheduler scheduler1; + #endif + + #ifdef USE_TWO_THREADS + #ifdef BOOST_HAS_THREADS + MyScheduler scheduler2( true ); + #else + MyScheduler & scheduler2 = scheduler1; + #endif + #else + MyScheduler & scheduler2 = scheduler1; + #endif + + MyScheduler::processor_handle player1 = + scheduler1.create_processor< Player >( noOfEvents / 2 ); + scheduler1.initiate_processor( player1 ); + MyScheduler::processor_handle player2 = + scheduler2.create_processor< Player >( noOfEvents / 2 ); + scheduler2.initiate_processor( player2 ); + + boost::intrusive_ptr< BallReturned > pInitialBall = new BallReturned(); + pInitialBall->returnToOpponent = boost::bind( + &MyScheduler::queue_event, &scheduler1, player1, _1 ); + pInitialBall->abortGame = boost::bind( + &MyScheduler::queue_event, + &scheduler1, player1, MakeIntrusive( new GameAborted() ) ); + + scheduler2.queue_event( player2, pInitialBall ); + + std::cout << "\nHaving players return the ball " << + noOfEvents << " times. Please wait...\n"; + + const unsigned int prevCount = Player::TotalNoOfProcessedEvents(); + const std::clock_t startTime = std::clock(); + + #ifdef USE_TWO_THREADS + #ifdef BOOST_HAS_THREADS + boost::thread otherThread( + boost::bind( &MyScheduler::operator(), &scheduler2, 0 ) ); + scheduler1(); + otherThread.join(); + #else + scheduler1(); + #endif + #else + scheduler1(); + #endif + + const std::clock_t elapsedTime = std::clock() - startTime; + std::cout << "Time to send and dispatch one event and\n" << + "perform the resulting transition: "; + std::cout << elapsedTime / static_cast< double >( CLOCKS_PER_SEC ) * + 1000000.0 / ( Player::TotalNoOfProcessedEvents() - prevCount ) + << " microseconds\n\n"; + } + break; + + default: + { + std::cout << "Invalid key!\n"; + } + } + + key = GetKey(); + } + + return 0; +} diff --git a/src/boost/libs/statechart/example/PingPong/PingPong.vcproj b/src/boost/libs/statechart/example/PingPong/PingPong.vcproj new file mode 100644 index 000000000..febebbc60 --- /dev/null +++ b/src/boost/libs/statechart/example/PingPong/PingPong.vcproj @@ -0,0 +1,301 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="PingPong" + ProjectGUID="{11CCA9FC-6012-4B64-8C61-808D0F8D1B51}" + RootNamespace="PingPong" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_ALL_DYN_LINK" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + DisableLanguageExtensions="false" + TreatWChar_tAsBuiltInType="true" + ForceConformanceInForLoopScope="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/PingPong.exe" + LinkIncremental="2" + AdditionalLibraryDirectories=""$(ProjectDir)..\..\..\..\bin.v2\libs\thread\build\msvc-9.0\$(ConfigurationName)\threading-multi";"$(ProjectDir)..\..\..\..\bin.v2\libs\date_time\build\msvc-9.0\$(ConfigurationName)\threading-multi"" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/PingPong.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy $(ProjectDir)..\..\..\..\bin.v2\libs\thread\build\msvc-9.0\$(ConfigurationName)\threading-multi\*.dll $(TargetDir)
copy $(ProjectDir)..\..\..\..\bin.v2\libs\date_time\build\msvc-9.0\$(ConfigurationName)\threading-multi\*.dll $(TargetDir)
" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="..\..\..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_ALL_DYN_LINK" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + DisableLanguageExtensions="false" + TreatWChar_tAsBuiltInType="true" + ForceConformanceInForLoopScope="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/PingPong.exe" + LinkIncremental="1" + AdditionalLibraryDirectories=""$(ProjectDir)..\..\..\..\bin.v2\libs\thread\build\msvc-9.0\$(ConfigurationName)\threading-multi";"$(ProjectDir)..\..\..\..\bin.v2\libs\date_time\build\msvc-9.0\$(ConfigurationName)\threading-multi"" + GenerateDebugInformation="false" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy $(ProjectDir)..\..\..\..\bin.v2\libs\thread\build\msvc-9.0\$(ConfigurationName)\threading-multi\*.dll $(TargetDir)
copy $(ProjectDir)..\..\..\..\bin.v2\libs\date_time\build\msvc-9.0\$(ConfigurationName)\threading-multi\*.dll $(TargetDir)
" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\PingPong.cpp" + > + </File> + <File + RelativePath=".\Player.cpp" + > + </File> + </Filter> + <Filter + Name="Statechart Header Files" + > + <File + RelativePath="..\..\..\..\boost\statechart\asynchronous_state_machine.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\custom_reaction.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\deep_history.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\deferral.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event_base.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event_processor.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\exception_translator.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\fifo_scheduler.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\in_state_reaction.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\null_exception_translator.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\result.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\shallow_history.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\simple_state.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\state.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\state_machine.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\termination.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\transition.hpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + > + <File + RelativePath=".\Player.hpp" + > + </File> + <File + RelativePath=".\Waiting.hpp" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/boost/libs/statechart/example/PingPong/Player.cpp b/src/boost/libs/statechart/example/PingPong/Player.cpp new file mode 100644 index 000000000..a67dbd8d6 --- /dev/null +++ b/src/boost/libs/statechart/example/PingPong/Player.cpp @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright 2008 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) +////////////////////////////////////////////////////////////////////////////// + + + +#include "Player.hpp" +#include "Waiting.hpp" // Waiting.hpp is only included here + + + +////////////////////////////////////////////////////////////////////////////// +void Player::initiate_impl() +{ + // Since we can only initiate at a point where the definitions of all the + // states in the initial state configuration are known, we duplicate + // the implementation of asynchronous_state_machine<>::initiate_impl() here + sc::state_machine< Player, Waiting, MyAllocator >::initiate(); +} + + +unsigned int Player::totalNoOfProcessedEvents_ = 0; diff --git a/src/boost/libs/statechart/example/PingPong/Player.hpp b/src/boost/libs/statechart/example/PingPong/Player.hpp new file mode 100644 index 000000000..9b333d7c4 --- /dev/null +++ b/src/boost/libs/statechart/example/PingPong/Player.hpp @@ -0,0 +1,126 @@ +#ifndef BOOST_STATECHART_EXAMPLE_PLAYER_HPP_INCLUDED +#define BOOST_STATECHART_EXAMPLE_PLAYER_HPP_INCLUDED +////////////////////////////////////////////////////////////////////////////// +// Copyright 2008 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) +////////////////////////////////////////////////////////////////////////////// + + + +#include <boost/statechart/event.hpp> +#include <boost/statechart/fifo_scheduler.hpp> +#include <boost/statechart/asynchronous_state_machine.hpp> + +#include <boost/config.hpp> +#include <boost/intrusive_ptr.hpp> +#include <boost/mpl/list.hpp> +#include <boost/function.hpp> + +#ifdef CUSTOMIZE_MEMORY_MANAGEMENT +# ifdef BOOST_HAS_THREADS + // for some reason the following is not automatically defined +# if defined( BOOST_MSVC ) | defined( BOOST_INTEL ) +# define __WIN32__ +# endif +# else +# define BOOST_NO_MT +# endif + +# ifdef BOOST_MSVC +# pragma warning( push ) +# pragma warning( disable: 4127 ) // conditional expression is constant +# endif + +# include <boost/pool/pool_alloc.hpp> + +# ifdef BOOST_MSVC +# pragma warning( pop ) +# endif +#endif + +#include <memory> // std::allocator + + + +namespace sc = boost::statechart; + + + +////////////////////////////////////////////////////////////////////////////// +template< class T > +boost::intrusive_ptr< T > MakeIntrusive( T * pObject ) +{ + return boost::intrusive_ptr< T >( pObject ); +} + + +////////////////////////////////////////////////////////////////////////////// +struct BallReturned : sc::event< BallReturned > +{ + boost::function1< void, const boost::intrusive_ptr< const BallReturned > & > + returnToOpponent; + boost::function0< void > abortGame; +}; + +struct GameAborted : sc::event< GameAborted > {}; + +#ifdef CUSTOMIZE_MEMORY_MANAGEMENT +typedef boost::fast_pool_allocator< int > MyAllocator; +typedef sc::fifo_scheduler< + sc::fifo_worker< MyAllocator >, MyAllocator > MyScheduler; +#else +typedef std::allocator< sc::none > MyAllocator; +typedef sc::fifo_scheduler<> MyScheduler; +#endif + + +////////////////////////////////////////////////////////////////////////////// +struct Player; +struct Waiting; + +namespace boost +{ +namespace statechart +{ + // The following class member specialization ensures that + // state_machine<>::initiate is not instantiated at a point where Waiting + // is not defined yet. + template<> + inline void asynchronous_state_machine< + Player, Waiting, MyScheduler, MyAllocator >::initiate_impl() {} +} +} + + +struct Player : sc::asynchronous_state_machine< + Player, Waiting, MyScheduler, MyAllocator > +{ + public: + Player( my_context ctx, unsigned int maxNoOfReturns ) : + my_base( ctx ), + maxNoOfReturns_( maxNoOfReturns ) + { + } + + static unsigned int & TotalNoOfProcessedEvents() + { + return totalNoOfProcessedEvents_; + } + + unsigned int GetMaxNoOfReturns() const + { + return maxNoOfReturns_; + } + + private: + // This function is defined in the Player.cpp + virtual void initiate_impl(); + + static unsigned int totalNoOfProcessedEvents_; + const unsigned int maxNoOfReturns_; +}; + + + +#endif diff --git a/src/boost/libs/statechart/example/PingPong/Waiting.hpp b/src/boost/libs/statechart/example/PingPong/Waiting.hpp new file mode 100644 index 000000000..b4e5e6008 --- /dev/null +++ b/src/boost/libs/statechart/example/PingPong/Waiting.hpp @@ -0,0 +1,96 @@ +#ifndef BOOST_STATECHART_EXAMPLE_WAITING_HPP_INCLUDED +#define BOOST_STATECHART_EXAMPLE_WAITING_HPP_INCLUDED +////////////////////////////////////////////////////////////////////////////// +// Copyright 2008 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) +////////////////////////////////////////////////////////////////////////////// + + +#include "Player.hpp" + +#include <boost/statechart/state.hpp> +#include <boost/statechart/transition.hpp> +#include <boost/statechart/custom_reaction.hpp> + +#include <boost/intrusive_ptr.hpp> +#include <boost/mpl/list.hpp> +#include <boost/function.hpp> +#include <boost/bind.hpp> + + + +namespace sc = boost::statechart; +namespace mpl = boost::mpl; + + + +////////////////////////////////////////////////////////////////////////////// +struct Waiting : sc::state< Waiting, Player > +{ + public: + ////////////////////////////////////////////////////////////////////////// + typedef mpl::list< + sc::custom_reaction< BallReturned >, + sc::custom_reaction< GameAborted > + > reactions; + + Waiting( my_context ctx ) : + my_base( ctx ), + noOfReturns_( 0 ), + pBallReturned_( new BallReturned() ) + { + outermost_context_type & machine = outermost_context(); + // as we will always return the same event to the opponent, we construct + // and fill it here so that we can reuse it over and over + pBallReturned_->returnToOpponent = boost::bind( + &MyScheduler::queue_event, + &machine.my_scheduler(), machine.my_handle(), _1 ); + pBallReturned_->abortGame = boost::bind( + &MyScheduler::queue_event, + &machine.my_scheduler(), machine.my_handle(), + MakeIntrusive( new GameAborted() ) ); + } + + sc::result react( const GameAborted & ) + { + return DestroyMyself(); + } + + sc::result react( const BallReturned & ballReturned ) + { + outermost_context_type & machine = outermost_context(); + ++machine.TotalNoOfProcessedEvents(); + + if ( noOfReturns_++ < machine.GetMaxNoOfReturns() ) + { + ballReturned.returnToOpponent( pBallReturned_ ); + return discard_event(); + } + else + { + ballReturned.abortGame(); + return DestroyMyself(); + } + } + + private: + ////////////////////////////////////////////////////////////////////////// + sc::result DestroyMyself() + { + outermost_context_type & machine = outermost_context(); + machine.my_scheduler().destroy_processor( machine.my_handle() ); + machine.my_scheduler().terminate(); + return terminate(); + } + + // avoids C4512 (assignment operator could not be generated) + Waiting & operator=( const Waiting & ); + + unsigned int noOfReturns_; + const boost::intrusive_ptr< BallReturned > pBallReturned_; +}; + + + +#endif diff --git a/src/boost/libs/statechart/example/StopWatch/StopWatch.cpp b/src/boost/libs/statechart/example/StopWatch/StopWatch.cpp new file mode 100644 index 000000000..93c50ecf6 --- /dev/null +++ b/src/boost/libs/statechart/example/StopWatch/StopWatch.cpp @@ -0,0 +1,189 @@ +////////////////////////////////////////////////////////////////////////////// +// 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 code implements the state-machine (this is the version +// discussed in the tutorial): +// +// -------------------------------- +// | | +// | O Active | +// | | |<---- +// | v | | EvReset +// | ---------------------------- | | +// | | | |----- +// | | Stopped | | +// | ---------------------------- | +// | | ^ | +// | | EvStartStop | EvStartStop |<-----O +// | v | | +// | ---------------------------- | +// | | | | +// | | Running | | +// | ---------------------------- | +// -------------------------------- + + + +#include <boost/statechart/event.hpp> +#include <boost/statechart/state_machine.hpp> +#include <boost/statechart/simple_state.hpp> +#include <boost/statechart/transition.hpp> + +#include <boost/config.hpp> + +#include <ctime> +#include <iostream> + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std +{ + using ::time; + using ::difftime; + using ::time_t; +} +#endif + +#ifdef BOOST_INTEL +# pragma warning( disable: 304 ) // access control not specified +# pragma warning( disable: 444 ) // destructor for base is not virtual +# pragma warning( disable: 981 ) // operands are evaluated in unspecified order +#endif + + + +namespace sc = boost::statechart; + + + +////////////////////////////////////////////////////////////////////////////// +struct EvStartStop : sc::event< EvStartStop > {}; +struct EvReset : sc::event< EvReset > {}; + +struct IElapsedTime +{ + virtual double ElapsedTime() const = 0; +}; + +struct Active; +struct StopWatch : sc::state_machine< StopWatch, Active > {}; + +struct Stopped; +struct Active : sc::simple_state< Active, StopWatch, Stopped > +{ + public: + typedef sc::transition< EvReset, Active > reactions; + + Active() : elapsedTime_( 0.0 ) {} + + double & ElapsedTime() + { + return elapsedTime_; + } + + double ElapsedTime() const + { + return elapsedTime_; + } + + private: + double elapsedTime_; +}; + + struct Running : IElapsedTime, sc::simple_state< Running, Active > + { + public: + typedef sc::transition< EvStartStop, Stopped > reactions; + + Running() : startTime_( std::time( 0 ) ) {} + + ~Running() + { + context< Active >().ElapsedTime() = ElapsedTime(); + } + + virtual double ElapsedTime() const + { + return context< Active >().ElapsedTime() + + std::difftime( std::time( 0 ), startTime_ ); + } + + private: + std::time_t startTime_; + }; + + struct Stopped : IElapsedTime, sc::simple_state< Stopped, Active > + { + typedef sc::transition< EvStartStop, Running > reactions; + + virtual double ElapsedTime() const + { + return context< Active >().ElapsedTime(); + } + }; + + +////////////////////////////////////////////////////////////////////////////// +char GetKey() +{ + char key; + std::cin >> key; + return key; +} + + +////////////////////////////////////////////////////////////////////////////// +int main() +{ + std::cout << "Boost.Statechart StopWatch example\n\n"; + std::cout << "s<CR>: Starts/Stops stop watch\n"; + std::cout << "r<CR>: Resets stop watch\n"; + std::cout << "d<CR>: Displays the elapsed time in seconds\n"; + std::cout << "e<CR>: Exits the program\n\n"; + std::cout << "You may chain commands, e.g. rs<CR> resets and starts stop watch\n\n"; + + StopWatch stopWatch; + stopWatch.initiate(); + + char key = GetKey(); + + while ( key != 'e' ) + { + switch( key ) + { + case 'r': + { + stopWatch.process_event( EvReset() ); + } + break; + + case 's': + { + stopWatch.process_event( EvStartStop() ); + } + break; + + case 'd': + { + std::cout << "Elapsed time: " << + stopWatch.state_cast< const IElapsedTime & >().ElapsedTime() << "\n"; + } + break; + + default: + { + std::cout << "Invalid key!\n"; + } + break; + } + + key = GetKey(); + } + + return 0; +} diff --git a/src/boost/libs/statechart/example/StopWatch/StopWatch.vcproj b/src/boost/libs/statechart/example/StopWatch/StopWatch.vcproj new file mode 100644 index 000000000..f04b6c760 --- /dev/null +++ b/src/boost/libs/statechart/example/StopWatch/StopWatch.vcproj @@ -0,0 +1,282 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="StopWatch" + ProjectGUID="{DFA55264-E7F5-43FE-841F-D56AC48FF2A8}" + RootNamespace="StopWatch" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + ForceConformanceInForLoopScope="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/StopWatch.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/StopWatch.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="..\..\..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + ForceConformanceInForLoopScope="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/StopWatch.exe" + LinkIncremental="1" + GenerateDebugInformation="false" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath="StopWatch.cpp" + > + </File> + </Filter> + <Filter + Name="Statechart Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + <File + RelativePath="..\..\..\..\boost\statechart\asynchronous_state_machine.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\custom_reaction.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\deep_history.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\deferral.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event_base.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\event_processor.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\exception_translator.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\fifo_scheduler.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\in_state_reaction.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\null_exception_translator.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\result.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\shallow_history.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\simple_state.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\state.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\state_machine.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\termination.hpp" + > + </File> + <File + RelativePath="..\..\..\..\boost\statechart\transition.hpp" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/boost/libs/statechart/example/StopWatch/StopWatch2.cpp b/src/boost/libs/statechart/example/StopWatch/StopWatch2.cpp new file mode 100644 index 000000000..3a11b2475 --- /dev/null +++ b/src/boost/libs/statechart/example/StopWatch/StopWatch2.cpp @@ -0,0 +1,216 @@ +////////////////////////////////////////////////////////////////////////////// +// 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 code implements the state-machine (this version details an +// alternative way of retrieving the elapsed time from the main program): +// +// -------------------------------- +// | | +// | O Active | +// | | |<---- +// | v | | EvReset +// | ---------------------------- | | +// | | | |----- +// | | Stopped | | +// | ---------------------------- | +// | | ^ | +// | | EvStartStop | EvStartStop |<-----O +// | v | | +// | ---------------------------- | +// | | | | +// | | Running | | +// | ---------------------------- | +// -------------------------------- + + + +#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 <ctime> +#include <iostream> + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std +{ + using ::time; + using ::difftime; + using ::time_t; +} +#endif + +#ifdef BOOST_INTEL +# pragma warning( disable: 304 ) // access control not specified +# pragma warning( disable: 444 ) // destructor for base is not virtual +# pragma warning( disable: 981 ) // operands are evaluated in unspecified order +#endif + + + +namespace sc = boost::statechart; +namespace mpl = boost::mpl; + + + +struct EvStartStop : sc::event< EvStartStop > {}; +struct EvReset : sc::event< EvReset > {}; +struct EvGetElapsedTime : sc::event< EvGetElapsedTime > +{ + public: + EvGetElapsedTime( double & time ) : time_( time ) {} + + void Assign( double time ) const + { + time_ = time; + } + + private: + double & time_; +}; + + +struct Active; +struct StopWatch : sc::state_machine< StopWatch, Active > {}; + + +struct Stopped; +struct Active : sc::simple_state< Active, StopWatch, Stopped > +{ + public: + typedef sc::transition< EvReset, Active > reactions; + + Active() : elapsedTime_( 0.0 ) {} + + double & ElapsedTime() + { + return elapsedTime_; + } + + double ElapsedTime() const + { + return elapsedTime_; + } + + private: + double elapsedTime_; +}; + +struct Running : sc::simple_state< Running, Active > +{ + public: + typedef mpl::list< + sc::custom_reaction< EvGetElapsedTime >, + sc::transition< EvStartStop, Stopped > + > reactions; + + Running() : startTime_( std::time( 0 ) ) {} + + ~Running() + { + context< Active >().ElapsedTime() = ElapsedTime(); + } + + sc::result react( const EvGetElapsedTime & evt ) + { + evt.Assign( ElapsedTime() ); + return discard_event(); + } + + private: + double ElapsedTime() const + { + return context< Active >().ElapsedTime() + + std::difftime( std::time( 0 ), startTime_ ); + } + + std::time_t startTime_; +}; + +struct Stopped : sc::simple_state< Stopped, Active > +{ + typedef mpl::list< + sc::custom_reaction< EvGetElapsedTime >, + sc::transition< EvStartStop, Running > + > reactions; + + sc::result react( const EvGetElapsedTime & evt ) + { + evt.Assign( context< Active >().ElapsedTime() ); + return discard_event(); + } +}; + + +namespace +{ + char GetKey() + { + char key; + std::cin >> key; + return key; + } +} + +int main() +{ + std::cout << "Boost.Statechart StopWatch example\n\n"; + std::cout << "s<CR>: Starts/Stops stop watch\n"; + std::cout << "r<CR>: Resets stop watch\n"; + std::cout << "d<CR>: Displays the elapsed time in seconds\n"; + std::cout << "e<CR>: Exits the program\n\n"; + std::cout << "You may chain commands, e.g. rs<CR> resets and starts stop watch\n\n"; + + StopWatch stopWatch; + stopWatch.initiate(); + + char key = GetKey(); + + while ( key != 'e' ) + { + switch( key ) + { + case 'r': + { + stopWatch.process_event( EvReset() ); + } + break; + + case 's': + { + stopWatch.process_event( EvStartStop() ); + } + break; + + case 'd': + { + double elapsedTime = 0.0; + stopWatch.process_event( EvGetElapsedTime( elapsedTime ) ); + std::cout << "Elapsed time: " << elapsedTime << "\n"; + } + break; + + default: + { + std::cout << "Invalid key!\n"; + } + break; + } + + key = GetKey(); + } + + return 0; +} |