Class: FSM::FSM

Inherits:
Object
  • Object
show all
Defined in:
lib/barebone-fsm.rb

Overview

This class implements the finite-state machine. FSM class exposes the states it contains and can trigger an event. States are created on the fly first time it’s referenced through index operator [].

The FSM state transits to the default state if the latest event does not define the next state. If default state is not set, then state does not change on undefined state. The initial state of the FSM is the first state mentioned. This can be either the default state if defined or the first referenced state.

Usage

fsm = FSM.new :default_state
fsm[:default_state].event(:first_event) do # the state is defined and referenced at the same time
  puts "The first transition from the default_state to state_name"
  :state_name # the next state is defined here
end

Instance Method Summary collapse

Constructor Details

#initialize(default_state = nil) ⇒ FSM

Returns a new instance of FSM.



94
95
96
97
98
99
100
# File 'lib/barebone-fsm.rb', line 94

def initialize(default_state=nil) 
  @states = {}
  if default_state then
    @state = @default = default_state 
    @states[@state] = FSMState.new(@state)
  end
end

Instance Method Details

#[](state_name = nil) ⇒ Object

It returns the FSMState object for state_name. If the state is missing, then it first sets up the state, and then returns the newly created state.



113
114
115
116
117
118
119
120
# File 'lib/barebone-fsm.rb', line 113

def [](state_name=nil) 
  state_name ||= @state
  if state_name and not @states.has_key? state_name then
    @states[state_name] = FSMState.new(state_name)
    @state ||= state_name
  end
  @states[state_name]
end

#build(&build_block) ⇒ Object Also known as: run

The #build/#run method sets up the states and events as given in the build_block. Only state and event methods are supported within the build_block with the name of the state/event and a block supplied. The operation for each such line is carried out by the #state/#event method.



149
150
151
# File 'lib/barebone-fsm.rb', line 149

def build(&build_block)
  self.instance_eval &build_block
end

#event(event_name) ⇒ Object

It triggers the event_name event and changes the state of the FSM to its new state. The :entry and :exit events are called on the leaving state and the entering state. If the event does not mention the new state, then the state changes to the default state.



136
137
138
139
140
141
142
143
144
# File 'lib/barebone-fsm.rb', line 136

def event(event_name) 
  @states[@state].event :exit
  new_state = @states[@state].event event_name
  new_state = nil if not @states.has_key? new_state
  new_state ||= @default_state
  new_state ||= @state 
  @state = new_state
  @states[@state].event :enter
end

#state(state_name = nil, &state_block) ⇒ Object

When the state_block is provided, it sets up a new state. Otherwise, when the state_block is missing, the FSMState object for state_name is returned. If called without any parameter, then the current state is returned.



125
126
127
128
129
130
131
# File 'lib/barebone-fsm.rb', line 125

def state(state_name=nil, &state_block)
  if block_given? then
    self.[](state_name).build &state_block
  else
    self.[](state_name)
  end
end

#to_sObject



102
103
104
105
106
107
108
109
# File 'lib/barebone-fsm.rb', line 102

def to_s() 
  "FSM" + 
    ": {" + 
      @states.values.map{ |st| 
        (st.state==@state ? ">" : "") + st.to_s
      }.join(', ') + 
    "}" 
end