Class: Charyf::Utils::Machine

Inherits:
Object
  • Object
show all
Defined in:
lib/charyf/utils/machine.rb

Constant Summary collapse

DefaultExists =
Class.new(ArgumentError)
NotInState =
Class.new(ArgumentError)
InvalidDefinition =
Class.new(LoadError)
InvalidEvent =
Class.new(ArgumentError)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(state = nil) ⇒ Machine

Returns a new instance of Machine.



80
81
82
# File 'lib/charyf/utils/machine.rb', line 80

def initialize(state = nil)
  @state ||= self.class._default_state
end

Instance Attribute Details

#stateObject (readonly)

End of class



78
79
80
# File 'lib/charyf/utils/machine.rb', line 78

def state
  @state
end

Class Method Details

._default_stateObject



41
42
43
# File 'lib/charyf/utils/machine.rb', line 41

def _default_state
  @_default_state
end

._events(state) ⇒ Object



58
59
60
61
# File 'lib/charyf/utils/machine.rb', line 58

def _events(state)
  @_events ||= Hash.new
  @_events[state] ||= Hash.new
end

._statesObject

def _final_states

@_final_states ||= [:_terminated]

end



49
50
51
52
53
54
55
56
# File 'lib/charyf/utils/machine.rb', line 49

def _states
  @_states ||= {
      _terminated: {
          action: :_terminated,
          final: true
      }
  }
end

.buildObject

Raises:



63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/charyf/utils/machine.rb', line 63

def build
  _states.each do |state_name, state|
    events = _events(state_name)
    raise InvalidDefinition.new("No transitions from state #{state_name}") if events.empty? && !state[:final]

    _events(state_name).each do |event, details|
      raise InvalidDefinition.new("Transition '#{event}' to undefined state '#{details[:go]}'") unless _states.include?(details[:go])
    end
  end

  raise InvalidDefinition.new('No final states defined.') unless _states.values.any? { |state| state[:final] }
end

.on(event, go: nil, &block) ⇒ Object

Raises:



31
32
33
34
35
36
37
38
39
# File 'lib/charyf/utils/machine.rb', line 31

def on(event, go: nil, &block)
  raise NotInState.new unless @_state

  _events(@_state)[event] =
      {
          go: go,
          callback: block
      }
end

.state(name, default: false, final: false, action: nil, &block) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/charyf/utils/machine.rb', line 12

def state(name, default: false, final: false, action: nil, &block)
  if default
    raise DefaultExists.new if @_default_state
    @_default_state = name
  end


  _states[name] = {
      action: action || name,
      final: final
  }

  if block
    @_state = name
    block.call
    @_state = nil
  end
end

Instance Method Details

#eventsObject



109
110
111
# File 'lib/charyf/utils/machine.rb', line 109

def events
  self.class._events(@state).keys
end

#final?Boolean

Returns:

  • (Boolean)


101
102
103
# File 'lib/charyf/utils/machine.rb', line 101

def final?
  self.class._states[@state][:final]
end

#state?(state) ⇒ Boolean

Returns:

  • (Boolean)


105
106
107
# File 'lib/charyf/utils/machine.rb', line 105

def state?(state)
  @state == state
end

#terminateObject



97
98
99
# File 'lib/charyf/utils/machine.rb', line 97

def terminate
  @state = :_terminated
end

#trigger(event, payload = nil) ⇒ Object



89
90
91
# File 'lib/charyf/utils/machine.rb', line 89

def trigger(event, payload = nil)
  trigger?(event) && change(event, payload)
end

#trigger!(event, payload = nil) ⇒ Object

Raises:



84
85
86
87
# File 'lib/charyf/utils/machine.rb', line 84

def trigger!(event, payload = nil)
  raise InvalidEvent.new("No transition defined for event '#{event}' from state '#{@state}'") unless trigger?(event)
  change(event, payload)
end

#trigger?(event) ⇒ Boolean

Returns:

  • (Boolean)


93
94
95
# File 'lib/charyf/utils/machine.rb', line 93

def trigger?(event)
  self.class._events(@state).include?(event)
end