lib/state_fu/lathe.rb in davidlee-state-fu-0.2.0 vs lib/state_fu/lathe.rb in davidlee-state-fu-0.3.1

- old
+ new

@@ -1,12 +1,19 @@ module StateFu + # A Lathe parses and a Machine definition and returns a freshly turned + # Machine. + # + # It provides the means to define the arrangement of StateFu objects + # ( eg States and Events) which comprise a workflow, process, + # lifecycle, circuit, syntax, etc. class Lathe # NOTE: Sprocket is the abstract superclass of Event and State attr_reader :machine, :sprocket, :options + # you don't need to call this directly. def initialize( machine, sprocket = nil, options={}, &block ) @machine = machine @sprocket = sprocket @options = options.symbolize_keys! @@ -139,11 +146,11 @@ options.symbolize_keys! require_sprocket( StateFu::State, NilClass ) if child? && sprocket.is_a?( StateFu::State ) # in state block targets = options.delete(:to) evt = define_event( name, options, &block ) - evt.from sprocket unless evt.origins + evt.from sprocket unless sprocket.nil? evt.to( targets ) unless targets.nil? evt else # in master lathe origins = options.delete( :from ) targets = options.delete( :to ) @@ -224,27 +231,56 @@ require_sprocket( StateFu::Event ) sprocket.to( *args, &block ) end # + # define chained events and states succinctly + # usage: chain 'state1 -event1-> state2 -event2-> state3' + def chain (string) + rx_word = /([a-zA-Z0-9_]+)/ + rx_state = /^#{rx_word}$/ + rx_event = /^-#{rx_word}->$/ + previous = nil + string.split.each do |chunk| + case chunk + when rx_state + current = state($1) + if previous.is_a?( StateFu::Event ) + previous.to( current ) + end + when rx_event + current = event($1) + if previous.is_a?( StateFu::State ) + current.from( previous ) + end + else + raise ArgumentError, "'#{chunk}' is not a valid token" + end + previous = current + end + end + + # # do something with all states / events # def each_sprocket( type, *args, &block) - require_no_sprocket() + options = args.extract_options!.symbolize_keys! if args == [:ALL] || args == [] args = machine.send("#{type}s").except( options.delete(:except) ) end args.map { |name| self.send( type, name, options.dup, &block) }.extend StateArray end def states( *args, &block ) + require_no_sprocket() each_sprocket( 'state', *args, &block ) end alias_method :all_states, :states alias_method :each_state, :states def events( *args, &block ) + require_sprocket( NilClass, StateFu::State ) each_sprocket( 'event', *args, &block ) end alias_method :all_events, :events alias_method :each_event, :events