Class: DataMapper::Is::StateMachine::Data::Machine

Inherits:
Object
  • Object
show all
Defined in:
lib/dm-is-state_machine/is/data/machine.rb

Overview

This Machine class represents one state machine.

A model (i.e. a DataMapper resource) can have more than one Machine.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(column, initial) ⇒ Machine

Returns a new instance of Machine.



30
31
32
33
34
# File 'lib/dm-is-state_machine/is/data/machine.rb', line 30

def initialize(column, initial)
  @column, @initial   = column, initial
  @events, @states    = [], []
  @current_state_name = initial
end

Instance Attribute Details

#columnObject

The property of the DM resource that will hold this Machine’s state.

TODO: change :column to :property



15
16
17
# File 'lib/dm-is-state_machine/is/data/machine.rb', line 15

def column
  @column
end

#current_state_nameObject

The current value of this Machine’s state

This is the “primary control” of this Machine’s state. All other methods key off the value of @current_state_name.



24
25
26
# File 'lib/dm-is-state_machine/is/data/machine.rb', line 24

def current_state_name
  @current_state_name
end

#eventsObject

Returns the value of attribute events.



26
27
28
# File 'lib/dm-is-state_machine/is/data/machine.rb', line 26

def events
  @events
end

#initialObject

The initial value of this Machine’s state



18
19
20
# File 'lib/dm-is-state_machine/is/data/machine.rb', line 18

def initial
  @initial
end

#statesObject

Returns the value of attribute states.



28
29
30
# File 'lib/dm-is-state_machine/is/data/machine.rb', line 28

def states
  @states
end

Instance Method Details

#current_stateObject

Return the current state



64
65
66
67
# File 'lib/dm-is-state_machine/is/data/machine.rb', line 64

def current_state
  find_state(@current_state_name)
  # TODO: add caching, i.e. with `@current_state ||= ...`
end

#find_event(event_name) ⇒ Object

Find event whose name is event_name



72
73
74
75
# File 'lib/dm-is-state_machine/is/data/machine.rb', line 72

def find_event(event_name)
  @events.find { |event| event.name.to_s == event_name.to_s }
  # TODO: use a data structure that prevents duplicates
end

#find_state(state_name) ⇒ Object

Find state whose name is event_name



80
81
82
83
# File 'lib/dm-is-state_machine/is/data/machine.rb', line 80

def find_state(state_name)
  @states.find { |state| state.name.to_s == state_name.to_s }
  # TODO: use a data structure that prevents duplicates
end

#fire_event(event_name, resource) ⇒ Object

Fire (activate) the event with name event_name



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/dm-is-state_machine/is/data/machine.rb', line 39

def fire_event(event_name, resource)
  unless event = find_event(event_name)
    raise InvalidEvent, "Could not find event (#{event_name.inspect})"
  end
  transition = event.transitions.find do |t|
     t[:from].to_s == @current_state_name.to_s
  end
  unless transition
    raise InvalidEvent, "Event (#{event_name.inspect}) does not" +
    "exist for current state (#{@current_state_name.inspect})"
  end

  # == Run :exit hook (if present) ==
  resource.run_hook_if_present current_state.options[:exit]

  # == Change the current_state ==
  @current_state_name = transition[:to]

  # == Run :enter hook (if present) ==
  resource.run_hook_if_present current_state.options[:enter]
end