Class: StateJacket::StateMachine

Inherits:
Object
  • Object
show all
Defined in:
lib/state_jacket/state_machine.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(transition_system, state:) ⇒ StateMachine

Returns a new instance of StateMachine.

Raises:

  • (ArgumentError)


5
6
7
8
9
10
11
# File 'lib/state_jacket/state_machine.rb', line 5

def initialize(transition_system, state:)
  transition_system.lock
  raise ArgumentError.new("illegal state") unless transition_system.is_state?(state)
  @transition_system = transition_system
  @state = state.to_s
  @triggers = {}
end

Instance Attribute Details

#stateObject (readonly)

Returns the value of attribute state.



3
4
5
# File 'lib/state_jacket/state_machine.rb', line 3

def state
  @state
end

Instance Method Details

#can_trigger?(event) ⇒ Boolean

Returns:

  • (Boolean)


60
61
62
63
# File 'lib/state_jacket/state_machine.rb', line 60

def can_trigger?(event)
  return false unless is_locked?
  !!transition_for(event)
end

#eventsObject



17
18
19
# File 'lib/state_jacket/state_machine.rb', line 17

def events
  triggers.keys
end

#is_event?(event) ⇒ Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/state_jacket/state_machine.rb', line 56

def is_event?(event)
  triggers.has_key? event.to_s
end

#is_locked?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/state_jacket/state_machine.rb', line 52

def is_locked?
  !!@locked
end

#lockObject



44
45
46
47
48
49
50
# File 'lib/state_jacket/state_machine.rb', line 44

def lock
  return true if is_locked?
  triggers.freeze
  triggers.values.map(&:freeze)
  triggers.values.freeze
  @locked = true
end

#on(event, transitions = {}) ⇒ Object

Raises:

  • (ArgumentError)


21
22
23
24
25
26
27
28
29
30
# File 'lib/state_jacket/state_machine.rb', line 21

def on(event, transitions={})
  raise "events cannot be added after locking" if is_locked?
  raise ArgumentError.new("event has already been added") if is_event?(event)
  transitions.each do |from, to|
    raise ArgumentError.new("illegal transition") unless transition_system.can_transition?(from => to)
    triggers[event.to_s] ||= []
    triggers[event.to_s] << { from.to_s => to.to_s }
    triggers[event.to_s].uniq!
  end
end

#to_hObject



13
14
15
# File 'lib/state_jacket/state_machine.rb', line 13

def to_h
  triggers.dup
end

#trigger(event) {|from, to| ... } ⇒ Object

Yields:

  • (from, to)

Raises:

  • (ArgumentError)


32
33
34
35
36
37
38
39
40
41
42
# File 'lib/state_jacket/state_machine.rb', line 32

def trigger(event)
  raise "must be locked before triggering events" unless is_locked?
  raise ArgumentError.new("event not defined") unless is_event?(event)
  transition = transition_for(event)
  return nil unless transition
  from = @state
  to = transition.values.first
  raise "current state doesn't match transition state" unless from == transition.keys.first
  yield from, to if block_given?
  @state = to
end