<?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 3: Conditional Logic</title>
    <link>http://blog.8thlight.com/articles/2007/02/13/understanding-statemachines-part-3-conditional-logic</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>In the minds of the craftsmen...</description>
    <item>
      <title>Understanding Statemachines, Part 3: Conditional Logic</title>
      <description>&lt;h3&gt;Conditions&lt;/h3&gt;

&lt;p&gt;If you&amp;#8217;re doing any significant amount of work with statmachines, you will most certainly encounter some conditional logic in your statemachines.  Take our vending machine.  When ever a coin is inserted, the invoked event will depend on whether the total amount of money inserted is sufficient to buy something.  If enough money has been tendered, the display should suggest that the customer make a selection.  If insufficient money has been inserted, the customer should be prompted to insert more.
&lt;br/&gt;&lt;br/&gt;
Conditional logic can be accomplished by using &lt;b&gt;entry actions&lt;/b&gt;.  See the diagram below.&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img width="400" style="border: 1px solid black" src="/files/vending_machine3.png"&gt;&lt;br/&gt;&lt;b&gt;State Diagram with Conditional Logic&lt;/b&gt;&lt;/div&gt;

&lt;p&gt;Starting in the &lt;code&gt;Accept Money&lt;/code&gt; state, when a coin is inserted, the &lt;code&gt;coin&lt;/code&gt; event is fired and the statemachine transitions into the &lt;code&gt;Coin Inserted&lt;/code&gt; state.  This is where it gets fun.  Upon entering of the &lt;code&gt;Coin Inserted&lt;/code&gt; state its entry event is invoked: &lt;code&gt;count_amount_tendered&lt;/code&gt;.  This method will count the money and invoke the &lt;code&gt;not_paid_yet&lt;/code&gt; or &lt;code&gt;paid&lt;/code&gt; event accordingly.  This will cause the statemachine to transition into the appropriate state.
&lt;br/&gt;&lt;br/&gt;
The &lt;code&gt;Coin Inserted&lt;/code&gt; state is unique.  You wouldn&amp;#8217;t expect to find the statemachine in the &lt;code&gt;Coin Inserted&lt;/code&gt; state for any reason except to make this decision.  Once the decision is made, the state changes.  States like this are called &lt;b&gt;Decision States&lt;/b&gt;.&lt;/p&gt;

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

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

class VendingMachineContext

  attr_accessor :statemachine

  def initialize
    @amount_tendered = 0
  end

  def add_coin
    @amount_tendered = @amount_tendered + 25
  end

  def count_amount_tendered
    if @amount_tendered &gt;= 100
      @statemachine.paid
    else
      @statemachine.not_paid_yet
    end
  end

  def prompt_money
    puts "$.#{@amount_tendered}: more money please"
  end

  def prompt_selection
    puts "please make a selection"
  end
end

vending_machine = Statemachine.build do
  trans :accept_money, :coin, :coin_inserted, :add_coin
  state :coin_inserted do
    event :not_paid_yet, :accept_money, :prompt_money
    event :paid, :await_selection, :prompt_selection
    on_entry :count_amount_tendered
  end
  context VendingMachineContext.new
end
vending_machine.context.statemachine = vending_machine

vending_machine.coin
vending_machine.coin
vending_machine.coin
vending_machine.coin&lt;/pre&gt;

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

&lt;pre&gt;$.25: more money please
$.50: more money please
$.75: more money please
please make a selection&lt;/pre&gt;

&lt;p&gt;Next lesson: Superstates&lt;br/&gt;
&lt;a href="/articles/2007/04/07/understanding-statemachines-part-4-superstates"&gt;Understanding Statemachines, Part 4: Superstates&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 13 Feb 2007 03:34:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:a7c8f8e8-9f01-4b56-90b9-dcedc59b2ede</guid>
      <author>Micah</author>
      <link>http://blog.8thlight.com/articles/2007/02/13/understanding-statemachines-part-3-conditional-logic</link>
      <category>Coding</category>
      <category>Statemachine</category>
      <category>Micah</category>
      <enclosure type="image/png" length="6987" url="http://blog.8thlight.com/files/vending_machine31.png"/>
    </item>
    <item>
      <title>"Understanding Statemachines, Part 3: Conditional Logic" by Leon Bogaert</title>
      <description>&lt;p&gt;Could you provide me/us with the sources for this vending machine? That would be very helpful. Thanks!&lt;/p&gt;</description>
      <pubDate>Thu, 13 Mar 2008 21:33:11 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:9cd4cee3-6957-4791-8441-efc310d83250</guid>
      <link>http://blog.8thlight.com/articles/2007/02/13/understanding-statemachines-part-3-conditional-logic#comment-736</link>
    </item>
  </channel>
</rss>
