Merged triggering_event from trunk to branch.

[SVN r58693]
This commit is contained in:
Andreas Huber
2010-01-04 23:27:46 +00:00
parent 92f4f38d18
commit aee6435c74
6 changed files with 391 additions and 54 deletions
+8
View File
@@ -94,6 +94,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentat
doc\uml_mapping.html = doc\uml_mapping.html
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TriggeringEventTest", "test\TriggeringEventTest.vcproj", "{DFE5C3C2-0CF9-4709-8393-96201E9A8181}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -318,6 +320,12 @@ Global
{045411F0-A746-4DB3-85B9-C9AEDE6D5CBA}.Release|Win32.ActiveCfg = Release|Win32
{045411F0-A746-4DB3-85B9-C9AEDE6D5CBA}.Release|Win32.Build.0 = Release|Win32
{045411F0-A746-4DB3-85B9-C9AEDE6D5CBA}.ReleaseFail|Win32.ActiveCfg = Release|Win32
{DFE5C3C2-0CF9-4709-8393-96201E9A8181}.Debug|Win32.ActiveCfg = Debug|Win32
{DFE5C3C2-0CF9-4709-8393-96201E9A8181}.Debug|Win32.Build.0 = Debug|Win32
{DFE5C3C2-0CF9-4709-8393-96201E9A8181}.DebugFail|Win32.ActiveCfg = Debug|Win32
{DFE5C3C2-0CF9-4709-8393-96201E9A8181}.Release|Win32.ActiveCfg = Release|Win32
{DFE5C3C2-0CF9-4709-8393-96201E9A8181}.Release|Win32.Build.0 = Release|Win32
{DFE5C3C2-0CF9-4709-8393-96201E9A8181}.ReleaseFail|Win32.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -347,6 +347,11 @@ class simple_state : public detail::simple_state_base_type< MostDerived,
HistoryContext, orthogonalPosition >();
}
const event_base * triggering_event() const
{
return outermost_context_base().triggering_event();
}
protected:
//////////////////////////////////////////////////////////////////////////
simple_state() : pContext_( 0 ) {}
+74 -53
View File
@@ -229,7 +229,7 @@ class history_key
//////////////////////////////////////////////////////////////////////////////
template< class MostDerived,
class InitialState,
class InitialState,
class Allocator = std::allocator< void >,
class ExceptionTranslator = null_exception_translator >
class state_machine : noncopyable
@@ -246,7 +246,7 @@ class state_machine : noncopyable
terminate();
{
terminator guard( *this );
terminator guard( *this, 0 );
detail::result_utility::get_result( translator_(
initial_construct_function( *this ),
exception_event_handler( *this ) ) );
@@ -258,7 +258,7 @@ class state_machine : noncopyable
void terminate()
{
terminator guard( *this );
terminator guard( *this, 0 );
detail::result_utility::get_result( translator_(
terminate_function( *this ),
exception_event_handler( *this ) ) );
@@ -411,7 +411,8 @@ class state_machine : noncopyable
currentStatesEnd_( currentStates_.end() ),
pOutermostState_( 0 ),
isInnermostCommonOuter_( false ),
performFullExit_( true )
performFullExit_( true ),
pTriggeringEvent_( 0 )
{
}
@@ -438,6 +439,57 @@ class state_machine : noncopyable
post_event( evt.intrusive_from_this() );
}
template<
class HistoryContext,
detail::orthogonal_position_type orthogonalPosition >
void clear_shallow_history()
{
// If you receive a
// "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or
// similar compiler error here then you tried to clear shallow history
// for a state that does not have shallow history. That is, the state
// does not pass either statechart::has_shallow_history or
// statechart::has_full_history to its base class template.
BOOST_STATIC_ASSERT( HistoryContext::shallow_history::value );
typedef typename mpl::at_c<
typename HistoryContext::inner_initial_list,
orthogonalPosition >::type historized_state;
store_history_impl(
shallowHistoryMap_,
history_key_type::make_history_key< historized_state >(),
0 );
}
template<
class HistoryContext,
detail::orthogonal_position_type orthogonalPosition >
void clear_deep_history()
{
// If you receive a
// "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or
// similar compiler error here then you tried to clear deep history for
// a state that does not have deep history. That is, the state does not
// pass either statechart::has_deep_history or
// statechart::has_full_history to its base class template
BOOST_STATIC_ASSERT( HistoryContext::deep_history::value );
typedef typename mpl::at_c<
typename HistoryContext::inner_initial_list,
orthogonalPosition >::type historized_state;
store_history_impl(
deepHistoryMap_,
history_key_type::make_history_key< historized_state >(),
0 );
}
const event_base_type * triggering_event() const
{
return pTriggeringEvent_;
}
public:
//////////////////////////////////////////////////////////////////////////
// The following declarations should be private.
@@ -611,29 +663,6 @@ class state_machine : noncopyable
reinterpret_cast< void (*)() >( &HistorizedState::deep_construct ) );
}
template<
class HistoryContext,
detail::orthogonal_position_type orthogonalPosition >
void clear_shallow_history()
{
// If you receive a
// "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or
// similar compiler error here then you tried to clear shallow history
// for a state that does not have shallow history. That is, the state
// does not pass either statechart::has_shallow_history or
// statechart::has_full_history to its base class template.
BOOST_STATIC_ASSERT( HistoryContext::shallow_history::value );
typedef typename mpl::at_c<
typename HistoryContext::inner_initial_list,
orthogonalPosition >::type historized_state;
store_history_impl(
shallowHistoryMap_,
history_key_type::make_history_key< historized_state >(),
0 );
}
template< class DefaultState >
void construct_with_shallow_history(
const typename DefaultState::context_ptr_type & pContext )
@@ -660,29 +689,6 @@ class state_machine : noncopyable
reinterpret_cast< void (*)() >( &constructor_type::construct ) );
}
template<
class HistoryContext,
detail::orthogonal_position_type orthogonalPosition >
void clear_deep_history()
{
// If you receive a
// "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or
// similar compiler error here then you tried to clear deep history for
// a state that does not have deep history. That is, the state does not
// pass either statechart::has_deep_history or
// statechart::has_full_history to its base class template
BOOST_STATIC_ASSERT( HistoryContext::deep_history::value );
typedef typename mpl::at_c<
typename HistoryContext::inner_initial_list,
orthogonalPosition >::type historized_state;
store_history_impl(
deepHistoryMap_,
history_key_type::make_history_key< historized_state >(),
0 );
}
template< class DefaultState >
void construct_with_deep_history(
const typename DefaultState::context_ptr_type & pContext )
@@ -771,6 +777,10 @@ class state_machine : noncopyable
pCurrentState : pOutermostUnstableState;
BOOST_ASSERT( pHandlingState != 0 );
terminator guard( *this, &exceptionEvent );
// There is another scope guard up the call stack, which will terminate
// the machine. So this guard only sets the triggering event.
guard.dismiss();
// Setting a member variable to a special value for the duration of a
// call surely looks like a kludge (normally it should be a parameter of
@@ -831,12 +841,21 @@ class state_machine : noncopyable
{
public:
//////////////////////////////////////////////////////////////////////
terminator( state_machine & machine ) :
machine_( machine ), dismissed_( false ) {}
terminator(
state_machine & machine, const event_base * pNewTriggeringEvent ) :
machine_( machine ),
pOldTriggeringEvent_(machine_.pTriggeringEvent_),
dismissed_( false )
{
machine_.pTriggeringEvent_ = pNewTriggeringEvent;
}
~terminator()
{
if ( !dismissed_ ) { machine_.terminate_impl( false ); }
machine_.pTriggeringEvent_ = pOldTriggeringEvent_;
}
void dismiss() { dismissed_ = true; }
private:
@@ -845,6 +864,7 @@ class state_machine : noncopyable
terminator & operator=( const terminator & );
state_machine & machine_;
const event_base_type * const pOldTriggeringEvent_;
bool dismissed_;
};
friend class terminator;
@@ -852,7 +872,7 @@ class state_machine : noncopyable
void send_event( const event_base_type & evt )
{
terminator guard( *this );
terminator guard( *this, &evt );
BOOST_ASSERT( get_pointer( pOutermostUnstableState_ ) == 0 );
const typename rtti_policy_type::id_type eventType = evt.dynamic_type();
detail::reaction_result reactionResult = detail::do_forward_event;
@@ -1055,6 +1075,7 @@ class state_machine : noncopyable
bool performFullExit_;
history_map_type shallowHistoryMap_;
history_map_type deepHistoryMap_;
const event_base_type * pTriggeringEvent_;
};
+2 -1
View File
@@ -1,5 +1,5 @@
##############################################################################
# Copyright 2005-2006 Andreas Huber Doenni
# Copyright 2005-2009 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)
##############################################################################
@@ -137,6 +137,7 @@ test-suite statechart
[ statechart-st-run-variants TypeInfoTest ]
[ statechart-st-run-variants StateIterationTest ]
[ statechart-st-run-variants FifoSchedulerTest ]
[ statechart-st-run-variants TriggeringEventTest ]
[ statechart-st-lib-run LibTestNormal
: TuTestMain : TuTest : <link>static $(normal) ]
[ statechart-st-lib-run LibTestNative
+98
View File
@@ -0,0 +1,98 @@
//////////////////////////////////////////////////////////////////////////////
// Copyright 2009 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/state.hpp>
#include <boost/statechart/exception_translator.hpp>
#include <boost/statechart/event.hpp>
#include <boost/statechart/in_state_reaction.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/mpl/list.hpp>
#include <boost/test/test_tools.hpp>
#include <memory> // std::allocator
namespace sc = boost::statechart;
namespace mpl = boost::mpl;
struct EvGoToB : sc::event< EvGoToB > {};
struct EvDoIt : sc::event< EvDoIt > {};
struct A;
struct TriggringEventTest : sc::state_machine<
TriggringEventTest, A,
std::allocator< void >, sc::exception_translator<> >
{
void Transit(const EvGoToB &)
{
BOOST_REQUIRE(dynamic_cast<const EvGoToB *>(triggering_event()) != 0);
}
};
struct B : sc::state< B, TriggringEventTest >
{
B( my_context ctx ) : my_base( ctx )
{
BOOST_REQUIRE(dynamic_cast<const EvGoToB *>(triggering_event()) != 0);
}
~B()
{
BOOST_REQUIRE(triggering_event() == 0);
}
void DoIt( const EvDoIt & )
{
BOOST_REQUIRE(dynamic_cast<const EvDoIt *>(triggering_event()) != 0);
throw std::exception();
}
void HandleException( const sc::exception_thrown & )
{
BOOST_REQUIRE(dynamic_cast<const sc::exception_thrown *>(triggering_event()) != 0);
}
typedef mpl::list<
sc::in_state_reaction< EvDoIt, B, &B::DoIt >,
sc::in_state_reaction< sc::exception_thrown, B, &B::HandleException >
> reactions;
};
struct A : sc::state< A, TriggringEventTest >
{
typedef sc::transition<
EvGoToB, B, TriggringEventTest, &TriggringEventTest::Transit
> reactions;
A( my_context ctx ) : my_base( ctx )
{
BOOST_REQUIRE(triggering_event() == 0);
}
~A()
{
BOOST_REQUIRE(dynamic_cast<const EvGoToB *>(triggering_event()) != 0);
}
};
int test_main( int, char* [] )
{
TriggringEventTest machine;
machine.initiate();
machine.process_event(EvGoToB());
machine.process_event(EvDoIt());
machine.terminate();
return 0;
}
+204
View File
@@ -0,0 +1,204 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="TriggeringEventTest"
ProjectGUID="{DFE5C3C2-0CF9-4709-8393-96201E9A8181}"
RootNamespace="TriggeringEventTest"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectName)Debug"
IntermediateDirectory="$(ProjectName)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"
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"
AdditionalDependencies="libboost_test_exec_monitor-vc90-mt-gd-1_40.lib"
OutputFile="$(OutDir)/TriggeringEventTest.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="&quot;$(ProjectDir)..\..\..\bin.v2\libs\test\build\msvc-9.0\$(ConfigurationName)\asynch-exceptions-on\link-static\threading-multi&quot;"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/TriggeringEventTest.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="$(ProjectName)Release"
IntermediateDirectory="$(ProjectName)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"
AdditionalIncludeDirectories="..\..\..\"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
DisableLanguageExtensions="true"
TreatWChar_tAsBuiltInType="true"
ForceConformanceInForLoopScope="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libboost_test_exec_monitor-vc90-mt-1_40.lib"
OutputFile="$(OutDir)/TriggeringEventTest.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;$(ProjectDir)..\..\..\bin.v2\libs\test\build\msvc-9.0\$(ConfigurationName)\asynch-exceptions-on\link-static\threading-multi&quot;"
GenerateDebugInformation="true"
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=".\TriggeringEventTest.cpp"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>