class FiniteMachine::EventsMap

A class responsible for storing mappings between event namess and their transition objects.

Used internally by {StateMachine}.

@api private

Public Class Methods

new() click to toggle source

Initialize a EventsMap

@api private

# File lib/finite_machine/events_map.rb, line 24
def initialize
  @events_map = Concurrent::Map.new
end

Public Instance Methods

[](name)
Alias for: find
add(name, transition) click to toggle source

Add transition under name

@param [Symbol] the event name

@param [Transition] transition

the transition to add under event name

@return [nil]

@api public

# File lib/finite_machine/events_map.rb, line 54
def add(name, transition)
  if exists?(name)
    @events_map[name] << transition
  else
    @events_map[name] = [transition]
  end
  self
end
can_perform?(name, from_state, *conditions) click to toggle source

Check if event is valid and transition can be performed

@return [Boolean]

@api public

# File lib/finite_machine/events_map.rb, line 131
def can_perform?(name, from_state, *conditions)
  !match_transition_with(name, from_state, *conditions).nil?
end
choice_transition?(name, from_state) click to toggle source

Check if event has branching choice transitions or not

@example

events_map.choice_transition?(:go, :green) # => true

@param [Symbol] name

the event name

@param [Symbol] from_state

the transition from state

@return [Boolean]

true if transition has any branches, false otherwise

@api public

# File lib/finite_machine/events_map.rb, line 150
def choice_transition?(name, from_state)
  find(name).select { |trans| trans.matches?(from_state) }.size > 1
end
clear() click to toggle source

Reset map

@return [self]

@api public

# File lib/finite_machine/events_map.rb, line 238
def clear
  @events_map.clear
  self
end
events() click to toggle source

Retrieve all event names

@example

events_map.events # => [:init, :start, :stop]

@return [Array]

All event names

@api public

# File lib/finite_machine/events_map.rb, line 88
def events
  @events_map.keys
end
exists?(name) click to toggle source

Check if event is present

@example

events_map.exists?(:go) # => true

@param [Symbol] name

the event name

@return [Boolean]

true if event is present, false otherwise

@api public

# File lib/finite_machine/events_map.rb, line 40
def exists?(name)
  @events_map.key?(name)
end
find(name) click to toggle source

Finds transitions for the event name

@param [Symbol] name

@example

events_map[:start] # => []

@return [Array]

the transitions matching event name

@api public

# File lib/finite_machine/events_map.rb, line 74
def find(name)
  @events_map.fetch(name) { [] }
end
Also aliased as: []
inspect() click to toggle source

Inspect map content

@example

events_map.inspect

@return [String]

@api public

# File lib/finite_machine/events_map.rb, line 264
def inspect
  "<##{self.class} @events_map=#{self}>"
end
match_transition(name, from_state) click to toggle source

Find transition without checking conditions

@param [Symbol] name

the event name

@param [Symbol] from_state

the transition from state

@return [Transition, nil]

returns transition, nil otherwise

@api private

# File lib/finite_machine/events_map.rb, line 166
def match_transition(name, from_state)
  find(name).find { |trans| trans.matches?(from_state) }
end
match_transition_with(name, from_state, *conditions) click to toggle source

Examine transitions for event name that start in from state and find one matching condition.

@param [Symbol] name

the event name

@param [Symbol] from_state

the current context from_state

@return [Transition]

The choice transition that matches

@api public

# File lib/finite_machine/events_map.rb, line 183
def match_transition_with(name, from_state, *conditions)
  find(name).find do |trans|
    trans.matches?(from_state) && trans.check_conditions(*conditions)
  end
end
move_to(name, from_state, *conditions) click to toggle source

Find state that this machine can move to

@example

evenst_map.move_to(:go, :green) # => :red

@param [Symbol] name

the event name

@param [Symbol] from_state

the transition from state

@param [Array] conditions

the data associated with this transition

@return [Symbol]

the transition `to` state

@api public

# File lib/finite_machine/events_map.rb, line 227
def move_to(name, from_state, *conditions)
  transition = select_transition(name, from_state, *conditions)
  transition ||= UndefinedTransition.new(name)
  transition.to_state(from_state)
end
select_transition(name, from_state, *conditions) click to toggle source

Select transition that matches conditions

@param [Symbol] name

the event name

@param [Symbol] from_state

the transition from state

@param [Array] conditions

the conditional data

@return [Transition]

@api public

# File lib/finite_machine/events_map.rb, line 201
def select_transition(name, from_state, *conditions)
  if choice_transition?(name, from_state)
    match_transition_with(name, from_state, *conditions)
  else
    match_transition(name, from_state)
  end
end
state_transitions() click to toggle source

Retrieves all state transitions

@return [Array]

@api public

# File lib/finite_machine/events_map.rb, line 110
def state_transitions
  @events_map.values.flatten.map(&:states)
end
states() click to toggle source

Retreive all unique states

@example

events_map.states # => [:yellow, :green, :red]

@return [Array]

the array of all unique states

@api public

# File lib/finite_machine/events_map.rb, line 101
def states
  @events_map.values.flatten.map(&:states).map(&:to_a).flatten.uniq
end
states_for(name) click to toggle source

Retrieve from states for the event name

@param [Symbol] event_name

@example

events_map.states_for(:start) # => [:yellow, :green]

@api public

# File lib/finite_machine/events_map.rb, line 122
def states_for(name)
  find(name).map(&:states).flat_map(&:keys)
end
to_s() click to toggle source

Return string representation of this map

@return [String]

@api public

# File lib/finite_machine/events_map.rb, line 248
def to_s
  hash = {}
  @events_map.each_pair do |name, trans|
    hash[name] = trans
  end
  hash.to_s
end