Class: StateFu::Machine
- Includes:
- HasOptions, Applicable
- Defined in:
- lib/machine.rb
Instance Attribute Summary collapse
-
#events ⇒ Object
readonly
Instance Methods.
-
#helpers ⇒ Object
readonly
Instance Methods.
-
#hooks ⇒ Object
readonly
Returns the value of attribute hooks.
-
#named_procs ⇒ Object
readonly
Instance Methods.
-
#options ⇒ Object
readonly
Instance Methods.
-
#requirement_messages ⇒ Object
readonly
Instance Methods.
-
#states ⇒ Object
readonly
Instance Methods.
-
#tools ⇒ Object
readonly
Instance Methods.
Class Method Summary collapse
-
.bind!(machine, owner, name, options = {}) ⇒ Object
make it so that a class which has included StateFu has a binding to this machine.
- .BINDINGS ⇒ Object
-
.for_class(klass, name, options = {}, &block) ⇒ Object
Class methods.
Instance Method Summary collapse
-
#apply!(&block) ⇒ Object
(also: #lathe)
merge the commands in &block with the existing machine; returns a lathe for the machine.
-
#bind!(owner, name = DEFAULT, options = {}) ⇒ Object
make it so a class which has included StateFu has a binding to this machine.
-
#deep_clone ⇒ Object
(also: #deep_copy)
Marshal, the poor man’s X-Ray photocopier.
- #empty? ⇒ Boolean
- #event_names ⇒ Object
-
#find_or_create_states_by_name(*args) ⇒ Object
given a messy bunch of symbols, find or create a list of matching States.
- #graphviz ⇒ Object
-
#helper(*modules_to_add) ⇒ Object
the modules listed here will be mixed into Binding and Transition objects for this machine.
- #helper_modules ⇒ Object
- #initial_state ⇒ Object
- #initial_state=(s) ⇒ Object
-
#initialize(options = {}, &block) ⇒ Machine
constructor
A new instance of Machine.
- #inject_helpers_into(obj) ⇒ Object
- #inject_tools_into(obj) ⇒ Object
- #inspect ⇒ Object
- #state_names ⇒ Object
-
#tool(*modules_to_add) ⇒ Object
same as helper, but for extending Lathes rather than the Bindings / Transitions.
Methods included from HasOptions
Methods included from Applicable
Constructor Details
#initialize(options = {}, &block) ⇒ Machine
Returns a new instance of Machine.
78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/machine.rb', line 78 def initialize( ={}, &block ) @states = [].extend( StateArray ) @events = [].extend( EventArray ) @helpers = [].extend( HelperArray ) @tools = [].extend( ToolArray ) @named_procs = {} @requirement_messages = {} @options = @hooks = Hooks.for( self ) apply!( &block ) if block_given? end |
Instance Attribute Details
#events ⇒ Object (readonly)
Instance Methods
76 77 78 |
# File 'lib/machine.rb', line 76 def events @events end |
#helpers ⇒ Object (readonly)
Instance Methods
76 77 78 |
# File 'lib/machine.rb', line 76 def helpers @helpers end |
#hooks ⇒ Object (readonly)
Returns the value of attribute hooks.
11 12 13 |
# File 'lib/machine.rb', line 11 def hooks @hooks end |
#named_procs ⇒ Object (readonly)
Instance Methods
76 77 78 |
# File 'lib/machine.rb', line 76 def named_procs @named_procs end |
#options ⇒ Object (readonly)
Instance Methods
76 77 78 |
# File 'lib/machine.rb', line 76 def @options end |
#requirement_messages ⇒ Object (readonly)
Instance Methods
76 77 78 |
# File 'lib/machine.rb', line 76 def @requirement_messages end |
#states ⇒ Object (readonly)
Instance Methods
76 77 78 |
# File 'lib/machine.rb', line 76 def states @states end |
#tools ⇒ Object (readonly)
Instance Methods
76 77 78 |
# File 'lib/machine.rb', line 76 def tools @tools end |
Class Method Details
.bind!(machine, owner, name, options = {}) ⇒ Object
make it so that a class which has included StateFu has a binding to this machine
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/machine.rb', line 32 def self.bind!(machine, owner, name, ={}) name = name.to_sym [:define_methods] = (name == DEFAULT) unless .symbolize_keys!.has_key?(:define_methods) [:field_name] ||= Persistence.default_field_name(name) [:singleton] = true unless owner.is_a?(Class) # define an accessor method with the given name if [:singleton] _binding = StateFu::Binding.new machine, owner, name, MethodFactory.define_singleton_method(owner, name) { _binding } if alias_name = [:alias] || [:as] MethodFactory.define_singleton_method(owner, alias_name) { _binding } end else klass = owner klass.state_fu_machines[name] = machine klass.[name] = # prepare the state machine accessor method if owner.respond_to? name raise "FIXME " + name else klass.class_eval do define_method name do state_fu name end # allow aliases to be set up, e.g. machine(:as => :status) if alias_name = [:alias] || [:as] alias_method alias_name, name end end end # prepare event / state class methods StateFu::MethodFactory.prepare_class_machine klass, machine, name, # prepare the persistence field StateFu::Persistence.prepare_field owner, [:field_name] end end |
.BINDINGS ⇒ Object
4 5 6 |
# File 'lib/machine.rb', line 4 def self.BINDINGS @@_bindings ||= {} end |
.for_class(klass, name, options = {}, &block) ⇒ Object
Class methods
17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/machine.rb', line 17 def self.for_class(klass, name, ={}, &block) .symbolize_keys! name = name.to_sym unless machine = klass.state_fu_machines[ name ] machine = new() end if block_given? machine.apply! &block end machine.bind! klass, name, machine end |
Instance Method Details
#apply!(&block) ⇒ Object Also known as: lathe
merge the commands in &block with the existing machine; returns a lathe for the machine.
92 93 94 |
# File 'lib/machine.rb', line 92 def apply!( &block ) StateFu::Lathe.new( self, &block ) end |
#bind!(owner, name = DEFAULT, options = {}) ⇒ Object
make it so a class which has included StateFu has a binding to this machine
131 132 133 |
# File 'lib/machine.rb', line 131 def bind!(owner, name=DEFAULT, ={}) self.class.bind!(self, owner, name, ) end |
#deep_clone ⇒ Object Also known as: deep_copy
Marshal, the poor man’s X-Ray photocopier. TODO: a version which will not break its teeth on procs
181 182 183 |
# File 'lib/machine.rb', line 181 def deep_clone Marshal::load(Marshal.dump(self)) end |
#empty? ⇒ Boolean
135 136 137 |
# File 'lib/machine.rb', line 135 def empty? states.empty? end |
#event_names ⇒ Object
160 161 162 |
# File 'lib/machine.rb', line 160 def event_names events.map(&:name) end |
#find_or_create_states_by_name(*args) ⇒ Object
given a messy bunch of symbols, find or create a list of matching States.
166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/machine.rb', line 166 def find_or_create_states_by_name( *args ) args = args.compact.flatten raise ArgumentError.new( args.inspect ) unless args.all? { |a| [Symbol, StateFu::State].include? a.class } args.map do |s| unless state = states[s.to_sym] # TODO clean this line up state = s.is_a?( StateFu::State ) ? s : StateFu::State.new( self, s ) self.states << state end state end end |
#graphviz ⇒ Object
190 191 192 |
# File 'lib/machine.rb', line 190 def graphviz @graphviz ||= Plotter.new(self).output end |
#helper(*modules_to_add) ⇒ Object
the modules listed here will be mixed into Binding and Transition objects for this machine. use this to define methods, references or data useful to you during transitions, event hooks, or in general use of StateFu.
They can be supplied as a string/symbol (as per rails controller helpers), or a Module.
To do this globally, just duck-punch StateFu::Machine / StateFu::Binding.
119 120 121 |
# File 'lib/machine.rb', line 119 def helper *modules_to_add modules_to_add.each { |mod| helpers << mod } end |
#helper_modules ⇒ Object
97 98 99 |
# File 'lib/machine.rb', line 97 def helper_modules helpers.modules end |
#initial_state ⇒ Object
152 153 154 |
# File 'lib/machine.rb', line 152 def initial_state() @initial_state ||= states.first end |
#initial_state=(s) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/machine.rb', line 139 def initial_state=( s ) case s when Symbol, String, StateFu::State unless init_state = states[ s.to_sym ] init_state = StateFu::State.new( self, s.to_sym ) states << init_state end @initial_state = init_state else raise( ArgumentError, s.inspect ) end end |
#inject_helpers_into(obj) ⇒ Object
101 102 103 |
# File 'lib/machine.rb', line 101 def inject_helpers_into( obj ) helpers.inject_into( obj ) end |
#inject_tools_into(obj) ⇒ Object
105 106 107 |
# File 'lib/machine.rb', line 105 def inject_tools_into( obj ) tools.inject_into( obj ) end |
#inspect ⇒ Object
186 187 188 |
# File 'lib/machine.rb', line 186 def inspect "#<#{self.class} ##{__id__} states=#{state_names.inspect} events=#{event_names.inspect} options=#{.inspect}>" end |
#state_names ⇒ Object
156 157 158 |
# File 'lib/machine.rb', line 156 def state_names states.map(&:name) end |
#tool(*modules_to_add) ⇒ Object
same as helper, but for extending Lathes rather than the Bindings / Transitions. use this to extend the Lathe DSL to suit your problem domain.
125 126 127 |
# File 'lib/machine.rb', line 125 def tool *modules_to_add modules_to_add.each { |mod| tools << mod } end |