Module: Opensteam::StateMachine::InstanceMethods

Defined in:
lib/opensteam/state_machine.rb

Instance Method Summary collapse

Instance Method Details

#change_state(new_state) ⇒ Object

changes state to new_state

if current_state is equal new_state, return false



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/opensteam/state_machine.rb', line 173

def change_state( new_state )
  if new_state.is_a?( Module )
    new_state = new_state.name
  end
  
  current_state = state
  
  add_history "starting transition from state '#{current_state}' to state '#{new_state}'"
  
  if current_state == new_state
    add_history "transition failed: current_state '#{current_state}' and new_state '#{new_state}' are the same!"
    return false
  end
  
  write_attribute(:state, new_state.to_s)
  ret = save
  
  if ret
    add_history( "Successfull: transition from state '#{current_state}' to state '#{new_state.to_s}'" )
  else
    add_history("Failed: transition from state '#{current_state}' to state '#{new_state.to_s}'")
  end

  
  self.execute_observers
#        self.class.observers.each do |o|
#          o.exc( self )
#        end
  
  ret
  
end

#eventsObject

returns an array of event-methods for the current state -> the instance_methods of the current state_module



108
# File 'lib/opensteam/state_machine.rb', line 108

def events ; (s = self.state_module ) ? s.instance_methods : [] ; end

#execute_observersObject



207
208
209
210
211
# File 'lib/opensteam/state_machine.rb', line 207

def execute_observers
  self.class.observers.each do |o|
    o.exc( self )
  end
end

#fire_event(event, *args, &block) ⇒ Object

fire an event for current state

if self.state is nil, returns false if event is not defined for current state (not an instance method of state_module), an error is raised if an error occured during the event, an error-entry is saved into the history calls change_state (return value of the event is used as next-state, if return value is a Symbol or a Module)



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/opensteam/state_machine.rb', line 140

def fire_event(event, *args, &block )
  
  return false unless self.state
  
  add_history( "trying to fire event '#{event}' for state '#{self.state}'" )
  
  return false unless event_scope = self.state_module
  
  unless events.include?( event.to_s )
    add_history( msg = "Error: event '#{event}' not defined for state '#{self.state}'")
    raise EventNotDefined, msg
    return false
  end
  
  begin 
    event_return = event_scope.instance_method( event ).bind( self ).call( *args, &block )
    add_history( "Successfully executed event '#{event}' for state '#{self.state}'" )
  rescue
    add_history("Error: An error occured during event '#{event}' in state '#{self.state}' : '#{$!}'")
  end
  
  unless event_return == false
    self.state = event_return if( event_return.is_a?(Symbol) || event_return.is_a?(Module) )
    return event_return
  end

end

#state=(new_state) ⇒ Object

overrides state-attribute setter calls change_state



126
127
128
# File 'lib/opensteam/state_machine.rb', line 126

def state=(new_state)
  change_state(new_state)
end

#state_moduleObject

returns the corresponding module for the current state

ex:

o = Order.create
o.state = :pending
o.state_module # => OrderStates::Pending


118
119
120
121
# File 'lib/opensteam/state_machine.rb', line 118

def state_module
  return nil unless state
  "#{self.class.to_s.demodulize}States::#{self.state.to_s.classify}".constantize rescue nil
end