module SassListen::FSM

Constants

DEFAULT_STATE

Attributes

state[R]

Obtain the current state of the FSM

Public Class Methods

included(klass) click to toggle source

Included hook to extend class methods

# File lib/sass-listen/fsm.rb, line 7
def self.included(klass)
  klass.send :extend, ClassMethods
end
new() click to toggle source

Be kind and call super if you must redefine initialize

# File lib/sass-listen/fsm.rb, line 47
def initialize
  @state = self.class.default_state
end

Public Instance Methods

transition(state_name) click to toggle source
# File lib/sass-listen/fsm.rb, line 54
def transition(state_name)
  new_state = validate_and_sanitize_new_state(state_name)
  return unless new_state
  transition_with_callbacks!(new_state)
end
transition!(state_name) click to toggle source

Immediate state transition with no checks, or callbacks. “Dangerous!”

# File lib/sass-listen/fsm.rb, line 61
def transition!(state_name)
  @state = state_name
end

Protected Instance Methods

current_state() click to toggle source
# File lib/sass-listen/fsm.rb, line 102
def current_state
  states[@state]
end
current_state_name() click to toggle source
# File lib/sass-listen/fsm.rb, line 106
def current_state_name
  current_state && current_state.name || ''
end
default_state() click to toggle source
# File lib/sass-listen/fsm.rb, line 98
def default_state
  self.class.default_state
end
states() click to toggle source
# File lib/sass-listen/fsm.rb, line 94
def states
  self.class.states
end
transition_with_callbacks!(state_name) click to toggle source
# File lib/sass-listen/fsm.rb, line 89
def transition_with_callbacks!(state_name)
  transition! state_name.name
  state_name.call(self)
end
validate_and_sanitize_new_state(state_name) click to toggle source
# File lib/sass-listen/fsm.rb, line 67
def validate_and_sanitize_new_state(state_name)
  state_name = state_name.to_sym

  return if current_state_name == state_name

  if current_state && !current_state.valid_transition?(state_name)
    valid = current_state.transitions.map(&:to_s).join(', ')
    msg = "#{self.class} can't change state from '#{@state}'"           " to '#{state_name}', only to: #{valid}"
    fail ArgumentError, msg
  end

  new_state = states[state_name]

  unless new_state
    return if state_name == default_state
    fail ArgumentError, "invalid state for #{self.class}: #{state_name}"
  end

  new_state
end