From 8da621cc1c255a2c5424ae5346f7165ea37bc509 Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Tue, 28 Aug 2012 18:25:37 +0200 Subject: [PATCH] Add more error messages and TODOs (for Camera example) --- examples/Camera/Camera.cpp | 53 +++++++++++++++ examples/Camera/Camera.hpp | 64 ++++++++++++++++++ examples/Camera/Configuring.cpp | 24 +++++++ examples/Camera/Configuring.hpp | 39 +++++++++++ examples/Camera/Main.cpp | 114 ++++++++++++++++++++++++++++++++ examples/Camera/Precompiled.cpp | 9 +++ examples/Camera/Precompiled.hpp | 20 ++++++ examples/Camera/Shooting.cpp | 71 ++++++++++++++++++++ examples/Camera/Shooting.hpp | 64 ++++++++++++++++++ examples/Makefile | 2 +- src/visualizer.cpp | 6 +- 11 files changed, 463 insertions(+), 3 deletions(-) create mode 100644 examples/Camera/Camera.cpp create mode 100644 examples/Camera/Camera.hpp create mode 100644 examples/Camera/Configuring.cpp create mode 100644 examples/Camera/Configuring.hpp create mode 100644 examples/Camera/Main.cpp create mode 100644 examples/Camera/Precompiled.cpp create mode 100644 examples/Camera/Precompiled.hpp create mode 100644 examples/Camera/Shooting.cpp create mode 100644 examples/Camera/Shooting.hpp diff --git a/examples/Camera/Camera.cpp b/examples/Camera/Camera.cpp new file mode 100644 index 0000000..8e4a984 --- /dev/null +++ b/examples/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/examples/Camera/Camera.hpp b/examples/Camera/Camera.hpp new file mode 100644 index 0000000..11bdf63 --- /dev/null +++ b/examples/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 +#include +#include +#include + +#include + +#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/examples/Camera/Configuring.cpp b/examples/Camera/Configuring.cpp new file mode 100644 index 0000000..f524a88 --- /dev/null +++ b/examples/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 +#include + + + +Configuring::Configuring() +{ + std::cout << "Entering Configuring\n"; +} + +Configuring::~Configuring() +{ + std::cout << "Exiting Configuring\n"; +} diff --git a/examples/Camera/Configuring.hpp b/examples/Camera/Configuring.hpp new file mode 100644 index 0000000..39819e5 --- /dev/null +++ b/examples/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 +#include + +#include + +#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/examples/Camera/Main.cpp b/examples/Camera/Main.cpp new file mode 100644 index 0000000..b4f7cf8 --- /dev/null +++ b/examples/Camera/Main.cpp @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////////////// +// 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.cpp" +#include "Camera.cpp" +#include "Shooting.cpp" +#include "Configuring.cpp" + + +#include + + + +////////////////////////////////////////////////////////////////////////////// +char GetKey() +{ + char key; + std::cin >> key; + return key; +} + + +////////////////////////////////////////////////////////////////////////////// +int main() +{ + std::cout << "Boost.Statechart Camera example\n\n"; + + std::cout << "h: Press shutter half-way\n"; + std::cout << "f: Press shutter fully\n"; + std::cout << "r: Release shutter\n"; + std::cout << "c: Enter/exit configuration\n"; + std::cout << "e: Exits the program\n\n"; + std::cout << "You may chain commands, e.g. hfr 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/examples/Camera/Precompiled.cpp b/examples/Camera/Precompiled.cpp new file mode 100644 index 0000000..c85c33d --- /dev/null +++ b/examples/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/examples/Camera/Precompiled.hpp b/examples/Camera/Precompiled.hpp new file mode 100644 index 0000000..ad71c5e --- /dev/null +++ b/examples/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 +#include +#include +#include +#include +#include + + + +#endif diff --git a/examples/Camera/Shooting.cpp b/examples/Camera/Shooting.cpp new file mode 100644 index 0000000..ae9a1ab --- /dev/null +++ b/examples/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 + +#include + +#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/examples/Camera/Shooting.hpp b/examples/Camera/Shooting.hpp new file mode 100644 index 0000000..1ae85d9 --- /dev/null +++ b/examples/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 +#include +#include +#include +#include +#include + +#include +#include + +#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/examples/Makefile b/examples/Makefile index c408fd3..f1bf4c6 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,7 +1,7 @@ -include ../Makefile.config .PHONY: all -all: test.pdf StopWatch.pdf main.pdf +all: test.pdf StopWatch.pdf main.pdf Camera/Main.pdf CLANG++ ?= $(shell $(LLVM_CONFIG) --bindir)/clang++ ifeq ($(wildcard $(CLANG++)),) diff --git a/src/visualizer.cpp b/src/visualizer.cpp index c238ba5..4ee95b9 100644 --- a/src/visualizer.cpp +++ b/src/visualizer.cpp @@ -245,6 +245,7 @@ public: void HandleReaction(const Type *T, const SourceLocation Loc, CXXRecordDecl *SrcState) { + // TODO: Improve Loc tracking if (const ElaboratedType *ET = dyn_cast(T)) HandleReaction(ET->getNamedType().getTypePtr(), Loc, SrcState); else if (const TemplateSpecializationType *TST = dyn_cast(T)) { @@ -260,8 +261,8 @@ public: } else if (name == "boost::mpl::list") { for (TemplateSpecializationType::iterator Arg = TST->begin(), End = TST->end(); Arg != End; ++Arg) HandleReaction(Arg->getAsType().getTypePtr(), Loc, SrcState); - } - //->getDecl()->getQualifiedNameAsString(); + } else + Diag(Loc, diag_unhandled_reaction_type) << name; } else Diag(Loc, diag_unhandled_reaction_type) << T->getTypeClassName(); } @@ -306,6 +307,7 @@ public: Model::Context *c = model.findContext(Context->getName()); if (c) c->add(state); + // TODO: else if (CXXRecordDecl *InnerInitialState = getTemplateArgDecl(Base->getType().getTypePtr(), 2)) state->setInitialInnerState(InnerInitialState->getName()); -- 2.39.2