Jekyll2022-08-12T07:26:21+00:00http://gresyk.dev/feed.xmlgresyk.devAndrew GresykTwitter thread on #cpp #state_machine #software_design.2019-03-20T09:55:00+00:002019-03-20T09:55:00+00:00http://gresyk.dev/features/2019/03/20/fsm-twitter-thread<p>Random ideas around writing an FSM library, with examples from, and motivations behind https://hfsm.dev, a header-only library created using #cpp template #metaprogramming with #gamedev, #embedded and #robotics in mind:</p>
<p><a href="https://twitter.com/andrew_gresyk/status/1108411688079015936">Twitter</a>
<a href="https://threadreaderapp.com/thread/1108411688079015936.html">ThreadReaderApp</a></p>Andrew GresykRandom ideas around writing an FSM library, with examples from, and motivations behind https://hfsm.dev, a header-only library created using #cpp template #metaprogramming with #gamedev, #embedded and #robotics in mind:Feature Announcement: Automatic Structure Visualization in HFSM2018-01-15T18:30:00+00:002018-01-15T18:30:00+00:00http://gresyk.dev/features/2018/01/15/hfsm-magic<p>Visualization in <a href="https://www.visualstudio.com/vs/">Visual Studio</a> watch window using a custom <a href="https://msdn.microsoft.com/en-us/library/jj620914.aspx">.natvis</a> <a href="https://github.com/andrew-gresyk/HFSM2/blob/master/hfsm2.natvis">file</a>:</p>
<p><img src="https://andrew-gresyk.github.io/attachments/magic.gif" alt="magic" /></p>
<p>The structure shown above was generated by HFSM automatically for the following FSM:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="n">FSM</span> <span class="o">=</span> <span class="n">M</span><span class="o">::</span><span class="n">Root</span><span class="o"><</span><span class="n">StreetLight</span><span class="p">,</span>
<span class="n">M</span><span class="o">::</span><span class="n">Composite</span><span class="o"><</span><span class="n">On</span><span class="p">,</span>
<span class="n">On</span><span class="o">::</span><span class="n">Red</span><span class="p">,</span>
<span class="n">On</span><span class="o">::</span><span class="n">Yellow</span><span class="p">,</span>
<span class="n">On</span><span class="o">::</span><span class="n">Green</span>
<span class="o">></span><span class="p">,</span>
<span class="n">Off</span>
<span class="o">></span><span class="p">;</span>
</code></pre></div></div>
<p>FSM structure and activity history API is available for custom run-time visualization:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// hfsm.hpp:</span>
<span class="k">struct</span> <span class="nc">StructureEntry</span> <span class="p">{</span>
<span class="kt">bool</span> <span class="n">isActive</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">wchar_t</span><span class="o">*</span> <span class="n">prefix</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">name</span><span class="p">;</span>
<span class="p">};</span>
<span class="k">using</span> <span class="n">MachineStructure</span> <span class="o">=</span> <span class="n">detail</span><span class="o">::</span><span class="n">ArrayView</span><span class="o"><</span><span class="n">StructureEntry</span><span class="o">></span><span class="p">;</span>
<span class="k">const</span> <span class="n">MachineStructure</span><span class="o">&</span> <span class="n">hfsm</span><span class="o">::</span><span class="n">M</span><span class="o"><>::</span><span class="n">Root</span><span class="o"><>::</span><span class="n">structure</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
<span class="k">using</span> <span class="n">MachineActivity</span> <span class="o">=</span> <span class="n">detail</span><span class="o">::</span><span class="n">ArrayView</span><span class="o"><</span><span class="kt">char</span><span class="o">></span><span class="p">;</span>
<span class="k">const</span> <span class="n">MachineActivity</span><span class="o">&</span> <span class="n">hfsm</span><span class="o">::</span><span class="n">M</span><span class="o"><>::</span><span class="n">Root</span><span class="o"><>::</span><span class="n">activity</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</code></pre></div></div>
<p>Example: using visualization API to print FSM structure using SFML:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">StructureVisualizer</span> <span class="p">{</span>
<span class="k">using</span> <span class="n">Lines</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">sf</span><span class="o">::</span><span class="n">Text</span><span class="o">></span><span class="p">;</span>
<span class="k">enum</span> <span class="o">:</span> <span class="kt">unsigned</span> <span class="p">{</span> <span class="n">FONT_SIZE</span> <span class="o">=</span> <span class="mi">16u</span> <span class="p">};</span>
<span class="nl">public:</span>
<span class="n">StructureVisualizer</span><span class="p">(</span><span class="k">const</span> <span class="n">k9</span><span class="o">::</span><span class="n">MachineStructure</span><span class="o">&</span> <span class="n">structure</span><span class="p">)</span> <span class="p">{</span>
<span class="n">_lines</span><span class="p">.</span><span class="n">reserve</span><span class="p">(</span><span class="n">structure</span><span class="p">.</span><span class="n">count</span><span class="p">());</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">structure</span><span class="p">.</span><span class="n">count</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
<span class="k">auto</span><span class="o">&</span> <span class="n">line</span> <span class="o">=</span> <span class="n">_lines</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="s">""</span><span class="p">,</span> <span class="n">font</span><span class="p">,</span> <span class="n">FONT_SIZE</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">wstringstream</span> <span class="n">stream</span><span class="p">;</span>
<span class="n">stream</span> <span class="o"><<</span> <span class="n">structure</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">prefix</span> <span class="o"><<</span> <span class="n">structure</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">name</span><span class="p">;</span>
<span class="n">line</span><span class="p">.</span><span class="n">setString</span><span class="p">(</span><span class="n">stream</span><span class="p">.</span><span class="n">str</span><span class="p">());</span>
<span class="n">line</span><span class="p">.</span><span class="n">setPosition</span><span class="p">(</span><span class="mf">10.0</span><span class="n">f</span><span class="p">,</span> <span class="mf">10.0</span><span class="n">f</span> <span class="o">+</span> <span class="n">FONT_SIZE</span> <span class="o">*</span> <span class="n">i</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">draw</span><span class="p">(</span><span class="k">const</span> <span class="n">k9</span><span class="o">::</span><span class="n">MachineActivity</span><span class="o">&</span> <span class="n">activity</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">activity</span><span class="p">.</span><span class="n">count</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
<span class="k">auto</span><span class="o">&</span> <span class="n">line</span> <span class="o">=</span> <span class="n">_lines</span><span class="p">[</span><span class="n">lineIndex</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="n">activity</span><span class="p">[</span><span class="n">lineIndex</span><span class="p">]</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span>
<span class="n">line</span><span class="p">.</span><span class="n">setFillColor</span><span class="p">(</span><span class="n">sf</span><span class="o">::</span><span class="n">Color</span><span class="o">::</span><span class="n">Yellow</span><span class="p">);</span>
<span class="k">else</span>
<span class="n">line</span><span class="p">.</span><span class="n">setFillColor</span><span class="p">(</span><span class="n">sf</span><span class="o">::</span><span class="n">Color</span><span class="p">(</span><span class="mi">127</span><span class="p">,</span> <span class="mi">127</span><span class="p">,</span> <span class="mi">127</span><span class="p">,</span> <span class="mi">255</span><span class="p">));</span>
<span class="n">line</span><span class="p">.</span><span class="n">setPosition</span><span class="p">(</span><span class="mf">10.0</span><span class="n">f</span><span class="p">,</span> <span class="mf">10.0</span><span class="n">f</span> <span class="o">+</span> <span class="n">FONT_SIZE</span> <span class="o">*</span> <span class="n">i</span><span class="p">);</span>
<span class="n">window</span><span class="p">.</span><span class="n">draw</span><span class="p">(</span><span class="n">line</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nl">private:</span>
<span class="n">Lines</span> <span class="n">_lines</span><span class="p">;</span>
<span class="p">};</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="n">Context</span> <span class="n">context</span><span class="p">;</span>
<span class="n">FSM</span> <span class="n">fsm</span><span class="p">(</span><span class="n">context</span><span class="p">);</span>
<span class="n">StructureVisualizer</span> <span class="n">structureVisualizer</span><span class="p">(</span><span class="n">fsm</span><span class="p">.</span><span class="n">structure</span><span class="p">());</span>
<span class="n">fsm</span><span class="p">.</span><span class="n">enter</span><span class="p">();</span>
<span class="k">while</span> <span class="p">(</span><span class="cm">/* running */</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// ...</span>
<span class="n">structureVisualizer</span><span class="p">.</span><span class="n">draw</span><span class="p">(</span><span class="n">fsm</span><span class="p">.</span><span class="n">activity</span><span class="p">());</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>Andrew GresykVisualization in Visual Studio watch window using a custom .natvis file:Presentation: Practical HFSM2018-01-10T18:30:00+00:002018-01-10T18:30:00+00:00http://gresyk.dev/presentations/2018/01/10/practical-hfsm<p><a href="https://andrew-gresyk.github.io/attachments/practical-hfsm.pdf">Slides</a> and <a href="https://skillsmatter.com/skillscasts/11360-practical-hfsm">video</a> from the <a href="https://www.meetup.com/CppLondon/">C++ London</a>’ <a href="https://www.meetup.com/CppLondon/events/246011416/">January 2018 Meetup</a>.</p>Andrew GresykSlides and video from the C++ London’ January 2018 Meetup.Presentation: Effective Screening Interviews2017-10-26T19:45:15+00:002017-10-26T19:45:15+00:00http://gresyk.dev/presentations/2017/10/26/effective-screening-inverviews<p><a href="https://andrew-gresyk.github.io/attachments/effective-screening-interviews.pdf">Slides</a> and <a href="https://www.youtube.com/watch?v=vIVZsVneVDg&t=4497">video</a> from the <a href="https://www.meetup.com/CppLondon/">C++ London</a>’ <a href="https://www.meetup.com/CppLondon/events/243386512/">October 2017 Meetup</a>.</p>Andrew GresykSlides and video from the C++ London’ October 2017 Meetup.Presentation: Hierarchical State Machine Framework for Videogames2017-04-11T18:30:00+00:002017-04-11T18:30:00+00:00http://gresyk.dev/presentations/2017/04/11/hfsm-for-videogames<p><a href="https://andrew-gresyk.github.io/attachments/hfsm-for-videogames.pdf">Slides</a> and videos (<a href="https://skillsmatter.com/skillscasts/9901-hierarchical-fsm">1</a> & <a href="https://skillsmatter.com/skillscasts/10157-hierarchical-fsm-part-2">2</a>) from the <a href="https://www.meetup.com/CppLondon/">C++ London</a>’ <a href="https://www.meetup.com/CppLondon/events/237580202/">April 2017 Meetup</a>.</p>Andrew GresykSlides and videos (1 & 2) from the C++ London’ April 2017 Meetup.