Sha256: 8130f1735e0324d5aa834ea15499a7fe7699cb2baf950a7ba3c202ae3b8ac51e

Contents?: true

Size: 1.95 KB

Versions: 3

Compression:

Stored size: 1.95 KB

Contents

module FSM
  #
  # A State has a name and a list of outgoing transitions.
  # 
  class State
    include FSM::Options::InstanceMethods
    attr_reader(:name, :transitions)
    
    # name: a symbol which identifies this state
    # options
    #  * :enter : a symbol or string or Proc
    #  * :exit : a symbol or string or Proc
    def initialize(name, target_class, options = {})
      raise ArgumentError.new('name and target_class is required') unless name && target_class
      assert_options(options, [:enter, :exit])
      @name = name
      @target_class = target_class
      @enter = Executable.new options[:enter] if options.has_key?(:enter)
      @exit = Executable.new options[:exit] if options.has_key?(:exit)
      @transitions = {}
    end
    
    # Called when this state is entered
    def enter(target)
      @enter.execute(target) if @enter
      nil
    end
    # Called when this state is exited
    def exit(target)
      @exit.execute(target) if @exit
      nil
    end    
    
    def add_transition(transition)
      raise ArgumentError.new("#{self} already has a transition to '#{transition.name}'") if @transitions.has_key?(transition.name)
      raise ArgumentError.new("the transition '#{transition.name}' is already defined") if @transitions.detect() {|to_name, tr| transition.name == tr.name}
      @transitions[transition.to.name] = transition
    end
    
    # All states that are reachable form this state by one hop
    def to_states
      @transitions.map { |to_name, transition| transition.to}
    end
    def final?
      @transitions.empty?
    end
    
    def initial?
      Machine[@target_class].initial_state_name == self.name
    end
    
    def to_s
      "State '#{self.name}' is "
    end
    
    def to_dot(options = {})
      if initial?
        attrs = "style=bold, label=\"#{self.name}\\n(initial)\""
      elsif final?  
        attrs = "style=bold"
      else
        attrs = ""
      end
      "#{self.name}[#{attrs}]"
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
simplificator-fsm-0.3.2 lib/fsm/state.rb
simplificator-fsm-0.3.3 lib/fsm/state.rb
simplificator-fsm-0.3.5 lib/fsm/state.rb