Class: Statum::Machine

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

Overview

Class for representing event machine

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Machine

Creates machine instance

Options Hash (options):

  • field (Symbol)

    Field to store state

  • initial (Symbol)

    Initial state

  • states (Array<Symbol>)

    States

  • events (Hash)

    Events


20
21
22
23
24
25
# File 'lib/statum/machine.rb', line 20

def initialize(options)
  @field   = options.delete(:field)
  @initial = options.delete(:initial)
  @states  = options.delete(:states)
  @events  = options.delete(:events)
end

Instance Attribute Details

#eventsHash (readonly)

Events


7
8
9
# File 'lib/statum/machine.rb', line 7

def events
  @events
end

#fieldSymbol (readonly) Also known as: name

State field


7
8
9
# File 'lib/statum/machine.rb', line 7

def field
  @field
end

#statesArray<Symbol> (readonly)

States


7
8
9
# File 'lib/statum/machine.rb', line 7

def states
  @states
end

Instance Method Details

#current(instance) ⇒ Symbol

Returns current state of instance


72
73
74
75
# File 'lib/statum/machine.rb', line 72

def current(instance)
  value = instance.send(field)
  value.nil? ? @initial : value.to_sym
end

#event?(name) ⇒ Boolean

Checks if event present


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

def event?(name)
  @events.keys.include?(name.to_sym)
end

#fire!(instance, name) ⇒ Object

Execute an event

Raises:

  • Statum::UnknownEventError

  • Statum::ErrorTransitionError


52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/statum/machine.rb', line 52

def fire!(instance, name)
  raise Statum::UnknownEventError, "Event #{name} not found" unless event?(name)

  current_state = current(instance)
  event         = events[name.to_sym]

  unless event.can_fire?(current_state)
    raise Statum::ErrorTransitionError, "Cannot transition from #{current_state} to #{event.to}"
  end

  event.before.evaluate(instance)
  instance.send("#{field}=", event.to)
  event.after.evaluate(instance)
end

#state?(name) ⇒ Boolean

Checks if state present


32
33
34
# File 'lib/statum/machine.rb', line 32

def state?(name)
  @states.include?(name.to_sym)
end