Class: Finity::Machine
- Inherits:
-
Object
- Object
- Finity::Machine
- Defined in:
- lib/finity/machine.rb
Instance Attribute Summary collapse
-
#events ⇒ Object
Returns the value of attribute events.
-
#states ⇒ Object
Returns the value of attribute states.
Instance Method Summary collapse
-
#event(name, options = {}, &block) ⇒ Object
Register an event and evaluate the block for transitions.
-
#initial ⇒ Object
Return the name of the initial state.
-
#initialize(klass, options = {}, &block) ⇒ Machine
constructor
Initialize a new state machine within the provided class and define methods for querying the current state and initiating transitions.
-
#state(name, options = {}) ⇒ Object
Register a state, or a set of states.
-
#update(object, current, event) ⇒ Object
An event occured, so update the state machine by evaluating the transition functions and notify the left and entered state, but only if the event leads to a transition that triggers a state change.
Constructor Details
#initialize(klass, options = {}, &block) ⇒ Machine
Initialize a new state machine within the provided class and define methods for querying the current state and initiating transitions. The current state must be bound to the including instance, otherwise there may be problems due to caching between requests.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/finity/machine.rb', line 31 def initialize klass, = {}, &block @klass, @states, @events = klass, {}, {} instance_eval &block if block_given? @initial = current = .delete(:initial) || initial @klass.send :define_method, :current do |*args| unless self.instance_variable_defined? :@current self.instance_variable_set :@current, current end self.instance_variable_get :@current end @klass.send :define_method, :event! do |*args| self.instance_variable_set :@current, ( klass.finity.update self, self.current, *args ) end @klass.send :define_method, :state? do |*args| self.current.eql? *args end end |
Instance Attribute Details
#events ⇒ Object
Returns the value of attribute events.
25 26 27 |
# File 'lib/finity/machine.rb', line 25 def events @events end |
#states ⇒ Object
Returns the value of attribute states.
25 26 27 |
# File 'lib/finity/machine.rb', line 25 def states @states end |
Instance Method Details
#event(name, options = {}, &block) ⇒ Object
Register an event and evaluate the block for transitions.
63 64 65 66 |
# File 'lib/finity/machine.rb', line 63 def event name, = {}, &block name.is_a?(Array) ? name.each { |value| event value, , &block } : @events[name] = Event.new(name, , &block) end |
#initial ⇒ Object
Return the name of the initial state.
52 53 54 |
# File 'lib/finity/machine.rb', line 52 def initial @initial ||= @states.keys.first unless @states.first.nil? end |
#state(name, options = {}) ⇒ Object
Register a state, or a set of states.
57 58 59 60 |
# File 'lib/finity/machine.rb', line 57 def state name, = {} name.is_a?(Array) ? name.each { |value| state value, } : @states[name] = State.new(name, ) end |
#update(object, current, event) ⇒ Object
An event occured, so update the state machine by evaluating the transition functions and notify the left and entered state, but only if the event leads to a transition that triggers a state change.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/finity/machine.rb', line 71 def update object, current, event now ||= @states[current] if state = @events[event].handle(object, now) if @states[state].nil? raise InvalidState, "Invalid state #{state}" end if state.eql? current now.cycle object else now.leave object now = @states[current = state] now.enter object end end current end |