{"id":7894,"date":"2019-09-23T10:15:19","date_gmt":"2019-09-23T08:15:19","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=7894"},"modified":"2023-09-29T10:28:33","modified_gmt":"2023-09-29T08:28:33","slug":"implementing-a-state-machine-in-c17-part-2","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/en\/implementing-a-state-machine-in-c17-part-2\/","title":{"rendered":"Implementing a State Machine in C++17 &#8211; part 2"},"content":{"rendered":"\n<p>In my <a href=\"https:\/\/sii.pl\/blog\/implementing-a-state-machine-in-c17\/\">previous article<\/a> we&#8217;ve talked about implementing a simple state machine based on a <strong>std::variant<\/strong> and other newer additions to the C++ standard. Even though the implementation had its merits it was far from being complete. In this article, we improve upon that design to make it more useful and easy to use. <\/p>\n\n\n\n<p> If you haven&#8217;t read the first part, I highly recommend that you do before diving into this article, as it heavily relies on code examples presented there.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A problem to solve<\/h2>\n\n\n\n<p>Let&#8217;s start with defining a problem that&#8217;ll serve as a testbed for new ideas. Previously a state machine representing basic door was used as an example. Sadly, a door that anyone can open is not very useful, so let&#8217;s change that. Let&#8217;s introduce a new state <strong>locked,<\/strong> so that only someone who knows the key could open the door. A sequence diagram for such state machine could look like this:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/fsm.png\"><img decoding=\"async\" width=\"265\" height=\"300\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/fsm-265x300.png\" alt=\"\" class=\"wp-image-7909\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/fsm-265x300.png 265w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/fsm.png 840w\" sizes=\"(max-width: 265px) 100vw, 265px\" \/><\/a><\/figure>\n\n\n\n<p>Besides an additional state, we&#8217;ve introduced two new events <strong>lock<\/strong> and <strong>unlock<\/strong>. Now, once the door is locked, the only way to open it, is to unlock it first. With all that in mind, we can try to implement such a state.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nstruct LockedState\n{\nNothing      handle(const OpenEvent&)   const { return {}; }\nNothing      handle(const CloseEvent&)  const { return {}; }\nNothing      handle(const LockEvent&)   const { return {}; }\nTransitionTo handle(const UnlockEvent&) const { return {}; }\n};\n<\/pre><\/div>\n\n\n<p>Now, that&#8217;s a lot of boilerplate code! The state reacts only on <strong>unlock<\/strong> event but we had to provide actions for all 4 events. To make it even worse, we need to implement handlers for those two newly added events in <strong>closed<\/strong> and <strong>open<\/strong> states. To fix this, let&#8217;s provide a mechanism to collapse all similar event handlers.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename Action&gt;\nstruct ByDefault\n{\ntemplate &lt;typename Event&gt;\nAction handle(const Event&amp;) const\n{\nreturn Action{};\n}\n};\n<\/pre><\/div>\n\n\n<p>We can use this struct as a base for some of our states introducing some common behavior. Why is the action type parametrized you might ask? That&#8217;s because sometimes there&#8217;s a better action to invoke other than <strong>Nothing<\/strong>, like for example <strong>TransitionTo<\/strong>. Let&#8217;s see how this improves things when applied to <strong>closed<\/strong> state.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nstruct ClosedState : ByDefault&lt;Nothing&gt;\n{\nusing ByDefault::handle;\n \nTransitionTo&lt;LockedState&gt; handle(const LockEvent&amp;) const { return {}; }\nTransitionTo&lt;OpenState&gt;   handle(const OpenEvent&amp;) const { return {}; }\n};\n<\/pre><\/div>\n\n\n<p>Better! But still not perfect \ud83d\ude42 First of all, as we have <strong>handle<\/strong> method overloaded in <strong>ClosedState<\/strong>, we need to pull <strong>handle<\/strong> from <strong>ByDefault<\/strong> base class with a <strong>using<\/strong> declaration. Additionally, handlers for <strong>LockEvent<\/strong> and <strong>OpenEvent<\/strong> don&#8217;t do anything except returning a default constructed action object. This behavior could be shared in a helper base structure.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename Event, typename Action&gt;\nstruct On\n{\nAction handle(const Event&amp;) const\n{\nreturn {};\n}\n};\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nstruct ClosedState : ByDefault&lt;Nothing&gt;,\nOn&lt;LockEvent, TransitionTo&lt;LockedState&gt;&gt;,\nOn&lt;OpenEvent, TransitionTo&lt;OpenState&gt;&gt;\n{\nusing ByDefault::handle;\nusing On&lt;LockEvent, TransitionTo&lt;LockedState&gt;&gt;::handle;\nusing On&lt;OpenEvent, TransitionTo&lt;OpenState&gt;&gt;::handle;\n};\n<\/pre><\/div>\n\n\n<p>&lt;\/openevent,&gt;&lt;\/lockevent,&gt;&lt;\/openevent,&gt;&lt;\/lockevent,&gt;<\/p>\n\n\n\n<p>Not much of an improvement since we still need to pull in handlers from all base classes. Fortunately, there&#8217;s a way to circumvent it. C++17 allows expanding parameter packs inside <strong>using<\/strong> declarations. We can use it to pull all overloads into a single base class.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename... Handlers&gt;\nstruct Will : Handlers...\n{\nusing Handlers::handle...;\n};\n<\/pre><\/div>\n\n\n<p>Now we can get rid of all those <strong>using<\/strong> declarations.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nstruct ClosedState : public Will&amp;lt;ByDefault&amp;lt;Nothing&gt;,\nOn&amp;lt;LockEvent, TransitionTo&amp;lt;LockedState&gt;&gt;,\nOn&amp;lt;OpenEvent, TransitionTo&amp;lt;OpenState&gt;&gt;&gt;\n{\n};\n<\/pre><\/div>\n\n\n<p>Now, that&#8217;s much better \ud83d\ude42 But our work is still far from complete. Even though we introduced a new <strong>locked<\/strong> state, we still don&#8217;t do any kind of verification. First of all, we need to store some value, let&#8217;s call it &#8216;key&#8217;, inside the state, which will be later used for access control. The issue here is that the states are currently default initialized by the state machine. We need to add a way to construct the states outside the state machine and pass them to the state machine constructor.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nStateMachine(States... states) : states(std::move(states)...) { }\n \nStateMachine() = default;\n \nStateMachine(States... states)\n: states(std::move(states)...)\n{\n}\n<\/pre><\/div>\n\n\n<p>In essence, when we&#8217;re in a <strong>locked<\/strong> state we should only accept <strong>unlock<\/strong> events that have a matching &#8216;key&#8217;. This poses a problem since actions are returned from state <strong>handle<\/strong> methods and can have only one return type. We need to model somehow a situation where the result of an event can be an alternative to many possibilities. We can utilize <strong>std::variant<\/strong> for this task.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename... Actions&gt;\nclass OneOf\n{\npublic:\ntemplate &lt;typename T&gt;\nOneOf(T&amp;&amp; arg)\n: options(std::forward&lt;T&gt;(arg))\n{\n}\n \ntemplate &lt;typename Machine&gt;\nvoid execute(Machine&amp; machine)\n{\nstd::visit(&#x5B;&amp;machine](auto&amp; action){ action.execute(machine); }, options);\n}\n \nprivate:\nstd::variant&lt;Actions...&gt; options;\n};\n<\/pre><\/div>\n\n\n<p>And since, most of the time, we want to either do one thing or do nothing at all, as a convenience, another helper type can be introduced.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename Action&gt;\nstruct Maybe : public OneOf&lt;Action, Nothing&gt;\n{\nusing OneOf&lt;Action, Nothing&gt;::OneOf;\n};\n<\/pre><\/div>\n\n\n<p>Now, with that in place, we can update both the <strong>unlock<\/strong> event and <strong>locked<\/strong> state<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nstruct UnlockEvent\n{\nuint32_t key;\n};\n \nclass LockedState : public ByDefault&lt;Nothing&gt;\n{\npublic:\nusing ByDefault::handle;\n \nLockedState(uint32_t key)\n: key(key)\n{\n}\n \nMaybe&lt;TransitionTo&lt;ClosedState&gt;&gt; handle(const UnlockEvent&amp; e) const\n{\nif (e.key == key) {\nreturn TransitionTo&lt;ClosedState&gt;{};\n}\nreturn Nothing{};\n}\n \nprivate:\nuint32_t key;\n};\n<\/pre><\/div>\n\n\n<p>Great! That&#8217;s exactly what we wanted! We&#8217;ve defined a state machine that resembles a door that can be unlocked only when the passed key matches the one stored in the state.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Taking things further<\/h2>\n\n\n\n<p>What if we wanted to model some kind of programmable door. Like a safe in some hotels, where you can define your own pin code, but you can do that only when the safe is unlocked. A sequence diagram for such door could look like this:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/sequence-1.png\"><img decoding=\"async\" width=\"839\" height=\"321\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/sequence-1.png\" alt=\"\" class=\"wp-image-7911\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/sequence-1.png 839w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/sequence-1-300x115.png 300w\" sizes=\"(max-width: 839px) 100vw, 839px\" \/><\/a><\/figure>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Locking and unlocking<\/h2>\n\n\n\n<p>Let&#8217;s start by adding a &#8216;newKey&#8217; field to<strong> l<\/strong><strong>ock<\/strong> event. That&#8217;s not a big problem. The biggest hurdle is how to inform <strong>locked<\/strong> state about that new value? We could, for example, define a new action type that would update a given state. Even though that would solve our problem, it&#8217;s not the best solution, since it requires <strong>closed<\/strong> state to know the internals of a completely different state &#8211; <strong>locked<\/strong>.<\/p>\n\n\n\n<p>The true problem that we need to solve lies even deeper. Instead of trying to pass this information from one state to another, we should focus on giving the state information when it was entered and under what circumstances. For example, we could use this information to open a socket or maintain a database connection for as long as we&#8217;re in that state and tear down everything once we leave.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Necessary changes<\/h2>\n\n\n\n<p>To start, we need to provide a bit more information to the actions. To call appropriate methods, <strong>TransitionTo<\/strong> action would need to know what&#8217;s the current state and what event triggered the action. Apart from that, we want to grab a reference to the newly selected state when we make a transition. Let&#8217;s update our state machine&#8217;s implementation to provide that extra information.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename Event&gt;\nvoid handle(const Event&amp; event)\n{\nauto passEventToState = &#x5B;this, &amp;event] (auto statePtr) {\nauto action = statePtr-&gt;handle(event);\naction.execute(*this, *statePtr, event);\n};\nstd::visit(passEventToState, currentState);\n}\n \ntemplate &lt;typename State&gt;\nState&amp; transitionTo()\n{\nauto&amp; state = std::get&lt;State&gt;(states);\ncurrentState = &amp;state;\nreturn state;\n}\n<\/pre><\/div>\n\n\n<p>Now let&#8217;s update the <strong>TransitionTo<\/strong> action. We want to call <strong>onLeave<\/strong> method the on previous state and <strong>onEnter<\/strong> on the destination state, but how do we know that these methods are present? We could enforce it, just like it&#8217;s done with <strong>handle<\/strong> methods, but that would lead to a lot of unnecessary code. We can use <strong>SFINAE<\/strong> (<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/sfinae\" rel=\"nofollow\" >link<\/a>) to detect if such a method exists. If it does, we&#8217;ll call it, if not, we&#8217;ll simply ignore it.<\/p>\n\n\n\n<p>You may ask why we didn&#8217;t use that trick with <strong>handle<\/strong> methods and implemented a bunch of helpers just to provide some default behavior? That&#8217;s because the situation is a little bit different. Formally speaking, a transition function should be defined for each state and each event. Furthermore, there are situations when we want to trigger a compilation error when we add a new event and one of the existing states doesn&#8217;t know how to handle it, instead of blindly ignoring it. With that in mind, let&#8217;s update the <strong>TransitionTo<\/strong> action.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename TargetState&gt;\nclass TransitionTo\n{\npublic:\ntemplate &lt;typename Machine, typename State, typename Event&gt;\nvoid execute(Machine&amp; machine, State&amp; prevState, const Event&amp; event)\n{\nleave(prevState, event);\nTargetState&amp; newState = machine.template transitionTo&lt;TargetState&gt;();\nenter(newState, event);\n}\n \nprivate:\nvoid leave(...)\n{\n}\n \ntemplate &lt;typename State, typename Event&gt;\nauto leave(State&amp; state, const Event&amp; event) -&gt; decltype(state.onLeave(event))\n{\nreturn state.onLeave(event);\n}\n \nvoid enter(...)\n{\n}\n \ntemplate &lt;typename State, typename Event&gt;\nauto enter(State&amp; state, const Event&amp; event) -&gt; decltype(state.onEnter(event))\n{\nreturn state.onEnter(event);\n}\n};\n<\/pre><\/div>\n\n\n<p>Thanks to <strong>SFINAE<\/strong>, we can detect if a <strong>onEnter<\/strong> or <strong>onLeave<\/strong> method was defined and act accordingly. The last thing to do is to implement an <strong>onEnter<\/strong> method for <strong>locked<\/strong> state<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nvoid onEnter(const LockEvent& e)\n{\nkey = e.newKey;\n}\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Wrapping things up<\/h2>\n\n\n\n<p>In this article, we explored how previous state machine implementation could be enhanced in order to support optional transitions and how to make it easier to use. States can now define custom <strong>onEnter<\/strong> and <strong>onLeave <\/strong>methods that will be called when the state is entered or left. If you want to play with that code, you can grab it <a href=\"https:\/\/github.com\/AdamsPL\/state-machine\" rel=\"nofollow\" >here<\/a>.<\/p>\n\n\n\n<p>In the next part of the article, we&#8217;ll play with adding support for tracing and debugging information and we&#8217;ll try to infer a nice transition table solely based on the StateMachine&#8217;s type, so stay tuned! \ud83d\ude42<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;7894&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;20&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;4.3&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;4.3\\\/5 ( votes: 20)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Implementing a State Machine in C++17 - part 2&quot;,&quot;width&quot;:&quot;119.2&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 119.2px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            4.3\/5 ( votes: 20)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>In my previous article we&#8217;ve talked about implementing a simple state machine based on a std::variant and other newer additions &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/en\/implementing-a-state-machine-in-c17-part-2\/\">Continued<\/a><\/p>\n","protected":false},"author":193,"featured_media":8172,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1320],"tags":[1425,1395,1375,1427,1430],"class_list":["post-7894","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hard-development","tag-c-en","tag-c17-en","tag-embedded-competency-center-en","tag-state-machine-en","tag-stdvariant-en"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/code-coding-conceptual-270360.jpg","category_names":["Hard development"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/7894"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/users\/193"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/comments?post=7894"}],"version-history":[{"count":2,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/7894\/revisions"}],"predecessor-version":[{"id":24556,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/7894\/revisions\/24556"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media\/8172"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media?parent=7894"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/categories?post=7894"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/tags?post=7894"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}