<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>8th Light Blog: Understanding Statemachines, Part 4: Superstates</title>
    <link>http://blog.8thlight.com/articles/2007/04/07/understanding-statemachines-part-4-superstates</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>In the minds of the craftsmen...</description>
    <item>
      <title>Understanding Statemachines, Part 4: Superstates</title>
      <description>&lt;h3&gt;Superstates&lt;/h3&gt;

&lt;p&gt;Often in statemachines, duplication can arise. For example, the vending machine in our examples may need periodic repairs.  It&amp;#8217;s not certain which state the vending machine will be in when the repair man arrives.  So all states should have a transition into the &lt;code&gt;Repair Mode&lt;/code&gt; state.&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img width="400" style="border: 1px solid black" src="/files/vending_machine4b.png"&gt;&lt;br/&gt;&lt;b&gt;Diagram 1 - Without Superstates&lt;/b&gt;&lt;/div&gt;

&lt;p&gt;In this diagram, both the &lt;code&gt;Waiting&lt;/code&gt; and &lt;code&gt;Paid&lt;/code&gt; states have a transition to the &lt;code&gt;Repair Mode&lt;/code&gt; invoked by the &lt;code&gt;repair&lt;/code&gt; event.  Duplication!  We can dry this up by using the &lt;b&gt;Superstate&lt;/b&gt; construct. See below:&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img width="400" style="border: 1px solid black" src="/files/vending_machine4a.png"&gt;&lt;br/&gt;&lt;b&gt;Diagram 2 - With Superstates&lt;/b&gt;&lt;/div&gt;

&lt;p&gt;Here we introduce the &lt;code&gt;Operational&lt;/code&gt; superstate.  Both the &lt;code&gt;Waiting&lt;/code&gt; and &lt;code&gt;Paid&lt;/code&gt; states are contained within the superstate which implies that they inherit all of the superstate&amp;#8217;s transitions.  That means we only need one transition into the &lt;code&gt;Repair Mode&lt;/code&gt; state from the &lt;code&gt;Operational&lt;/code&gt; superstate to achieve the same behavior as the solution in &lt;i&gt;diagram 1&lt;/i&gt;.  &lt;/p&gt;

&lt;p&gt;One statemachine may have multiple superstates.  And every superstate may contain other superstates. ie. Superstates can be nested.&lt;/p&gt;

&lt;h3&gt;History State&lt;/h3&gt;

&lt;p&gt;The solution in &lt;i&gt;diagram 2&lt;/i&gt; has an advantage over &lt;i&gt;diagram 1&lt;/i&gt;.  In &lt;i&gt;diagram 1&lt;/i&gt;, once the repair man is done he triggers the &lt;code&gt;operate&lt;/code&gt; event and the vending machine transitions into the &lt;code&gt;Waiting&lt;/code&gt; event.  This is unfortunate.  Even if the vending machine was in the &lt;code&gt;Paid&lt;/code&gt; state before the repair man came along, it will be in the &lt;code&gt;Waiting&lt;/code&gt; state after he leaves.  Shouldn&amp;#8217;t it go back into the &lt;code&gt;Paid&lt;/code&gt; state?&lt;/p&gt;

&lt;p&gt;Superstates come with the &lt;b&gt;history state&lt;/b&gt; which solves this problem.  Every superstate will remember which state it is in before the superstate is exited.  This memory is stored in a pseudo state called the &lt;b&gt;history state&lt;/b&gt;.  Transitions that end in the history state will recall the last active state of the superstate and enter it.  &lt;/p&gt;

&lt;p&gt;You can see the history state being use in &lt;i&gt;diagram 2&lt;/i&gt;.  In this solution, the history state allows the vending machine to return from a repair session into the same state it was in before, as though nothing happened at all.&lt;/p&gt;

&lt;h3&gt;Code&lt;/h3&gt;

&lt;p&gt;The following code builds the statemachine in &lt;i&gt;diagram 2&lt;/i&gt;.  Watch out for the &lt;code&gt;_H&lt;/code&gt;.  This is how the history state is denoted.  If you have a superstate named &lt;code&gt;foo&lt;/code&gt;, then it&amp;#8217;s history state will be named &lt;code&gt;foo_H&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;require 'rubygems'
require 'statemachine'

vending_machine = Statemachine.build do
  superstate :operational do
    trans :waiting, :dollar, :paid
    trans :paid, :selection, :waiting
    trans :waiting, :selection, :waiting
    trans :paid, :dollar, :paid

    event :repair, :repair_mode,  Proc.new { puts "Entering Repair Mode" }
  end

  trans :repair_mode, :operate, :operational_H, Proc.new { puts "Exiting Repair Mode" }

  on_entry_of :waiting, Proc.new { puts "Entering Waiting State" }
  on_entry_of :paid, Proc.new { puts "Entering Paid State" }
end

vending_machine.repair
vending_machine.operate
vending_machine.dollar
vending_machine.repair
vending_machine.operate&lt;/pre&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;pre&gt;Entering Repair Mode
Exiting Repair Mode
Entering Waiting State
Entering Paid State
Entering Repair Mode
Exiting Repair Mode
Entering Paid State&lt;/pre&gt;

&lt;p&gt;Next we should cover pseudo states.&lt;/p&gt;</description>
      <pubDate>Sat, 07 Apr 2007 21:19:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:3fb702aa-c403-4fad-9760-b5431dbf81f7</guid>
      <author>Micah</author>
      <link>http://blog.8thlight.com/articles/2007/04/07/understanding-statemachines-part-4-superstates</link>
      <category>Coding</category>
      <category>Statemachine</category>
      <category>Micah</category>
    </item>
    <item>
      <title>"Understanding Statemachines, Part 4: Superstates" by Heg</title>
      <description>&lt;p&gt;Thank you very much for the gem and the articles - I&amp;#8217;ve enjoyed the series very much!!&lt;/p&gt;</description>
      <pubDate>Sun, 11 May 2008 07:01:05 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:5b50a2d3-d1df-4b1f-9563-de46d5826735</guid>
      <link>http://blog.8thlight.com/articles/2007/04/07/understanding-statemachines-part-4-superstates#comment-770</link>
    </item>
    <item>
      <title>"Understanding Statemachines, Part 4: Superstates" by luc</title>
      <description>&lt;p&gt;Same problem as tutor 3:&lt;/p&gt;

&lt;p&gt;problem with &amp;#8216;on&lt;em&gt;entry&lt;/em&gt;of&amp;#8217;  &lt;/p&gt;

&lt;p&gt;Example output:&lt;/p&gt;

&lt;p&gt;Entering Waiting State  &amp;lt;&amp;#8212; wrong msg
Entering Repair Mode
Exiting Repair Mode
Entering Waiting State
Entering Paid State
Entering Repair Mode
Exiting Repair Mode
Entering Paid State&lt;/p&gt;</description>
      <pubDate>Sat, 15 Dec 2007 17:30:52 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:5f434913-be66-48ca-a9be-e874e8232b2d</guid>
      <link>http://blog.8thlight.com/articles/2007/04/07/understanding-statemachines-part-4-superstates#comment-460</link>
    </item>
    <item>
      <title>"Understanding Statemachines, Part 4: Superstates" by Raindog</title>
      <description>&lt;p&gt;I was wondering if you could post a tutorial and use a complex statemachine as the example, perhaps one with multiple superstates, etc.&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;</description>
      <pubDate>Fri, 20 Jul 2007 15:25:23 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:eeb6d35f-f91e-4fb6-b257-4a4669e97316</guid>
      <link>http://blog.8thlight.com/articles/2007/04/07/understanding-statemachines-part-4-superstates#comment-279</link>
    </item>
    <item>
      <title>"Understanding Statemachines, Part 4: Superstates" by darren@pulsipher.org</title>
      <description>&lt;p&gt;Great stuff.
I was thinking I might have to do this myself, I am glad this has been done already.&lt;/p&gt;</description>
      <pubDate>Fri, 13 Jul 2007 08:45:43 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:24deb1bd-3626-4d29-976b-f4128e878790</guid>
      <link>http://blog.8thlight.com/articles/2007/04/07/understanding-statemachines-part-4-superstates#comment-277</link>
    </item>
    <item>
      <title>"Understanding Statemachines, Part 4: Superstates" by wlt</title>
      <description>&lt;p&gt;These tutorials is great! waiting for your next:)&lt;/p&gt;</description>
      <pubDate>Tue, 26 Jun 2007 20:19:25 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:c63d1173-f078-4162-9b1b-55f3ee777487</guid>
      <link>http://blog.8thlight.com/articles/2007/04/07/understanding-statemachines-part-4-superstates#comment-275</link>
    </item>
    <item>
      <title>"Understanding Statemachines, Part 4: Superstates" by Raindog</title>
      <description>&lt;p&gt;Thanks for these tutorials, I&amp;#8217;ve really enjoyed them and plan on using statemachine gem to implement some game logic for a simple enemy.&lt;/p&gt;</description>
      <pubDate>Fri, 13 Apr 2007 22:45:18 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:38551afb-8102-4379-87b5-8b71caf37dea</guid>
      <link>http://blog.8thlight.com/articles/2007/04/07/understanding-statemachines-part-4-superstates#comment-19</link>
    </item>
  </channel>
</rss>
