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.



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

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

Instance Attribute Details

#stateObject (readonly)

End of class



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

def state
  @state
end

Class Method Details

._default_stateObject



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

def _default_state
  @_default_state
end

._events(state) ⇒ Object



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

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

._statesObject

def _final_states

@_final_states ||= [:_terminated]

end



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

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

.buildObject

Raises:



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

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:



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

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

Sig does not handle blocks



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

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



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

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

#final?Boolean

Returns:

  • (Boolean)


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

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

#state?(state) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#terminateObject



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

def terminate
  @state = :_terminated
end

#trigger(event, payload = nil) ⇒ Object



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

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

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

Raises:



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

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)


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

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