Class: FSM::Machine
- Inherits:
-
Object
- Object
- FSM::Machine
- Defined in:
- lib/fsm/machine.rb
Instance Attribute Summary collapse
-
#current_state_attribute_name ⇒ Object
Returns the value of attribute current_state_attribute_name.
-
#initial_state_name ⇒ Object
Returns the value of attribute initial_state_name.
-
#states ⇒ Object
Returns the value of attribute states.
-
#transitions ⇒ Object
Returns the value of attribute transitions.
Class Method Summary collapse
- .[](includer) ⇒ Object
- .[]=(*args) ⇒ Object
- .get_current_state_name(target) ⇒ Object
- .set_current_state_name(target, value) ⇒ Object
Instance Method Summary collapse
- #available_transitions(target) ⇒ Object
- #build_transition_methods ⇒ Object
- #dot(options = {}) ⇒ Object
-
#initialize(target_class) ⇒ Machine
constructor
A new instance of Machine.
- #reachable_states(target) ⇒ Object
- #state(name, options = {}) ⇒ Object
-
#state_for_name(name, quiet = false) ⇒ Object
Lookup a State by it’s name raises ArgumentError if state can not be found unless quiet is set to true.
- #to_dot ⇒ Object
- #transition(name, from_name, to_name, options = {}) ⇒ Object
Constructor Details
#initialize(target_class) ⇒ Machine
Returns a new instance of Machine.
5 6 7 8 9 10 |
# File 'lib/fsm/machine.rb', line 5 def initialize(target_class) @target_class = target_class self.states = [] self.transitions = [] self.current_state_attribute_name = :state end |
Instance Attribute Details
#current_state_attribute_name ⇒ Object
Returns the value of attribute current_state_attribute_name.
3 4 5 |
# File 'lib/fsm/machine.rb', line 3 def current_state_attribute_name @current_state_attribute_name end |
#initial_state_name ⇒ Object
Returns the value of attribute initial_state_name.
3 4 5 |
# File 'lib/fsm/machine.rb', line 3 def initial_state_name @initial_state_name end |
#states ⇒ Object
Returns the value of attribute states.
3 4 5 |
# File 'lib/fsm/machine.rb', line 3 def states @states end |
#transitions ⇒ Object
Returns the value of attribute transitions.
3 4 5 |
# File 'lib/fsm/machine.rb', line 3 def transitions @transitions end |
Class Method Details
.[](includer) ⇒ Object
12 13 14 |
# File 'lib/fsm/machine.rb', line 12 def self.[](includer) (@machines ||= {})[includer] end |
.[]=(*args) ⇒ Object
16 17 18 |
# File 'lib/fsm/machine.rb', line 16 def self.[]=(*args) (@machines ||= {})[args.first] = args.last end |
.get_current_state_name(target) ⇒ Object
41 42 43 44 |
# File 'lib/fsm/machine.rb', line 41 def self.get_current_state_name(target) value = target.send(Machine[target.class].current_state_attribute_name) (value && value.is_a?(String)) ? value.intern : value end |
.set_current_state_name(target, value) ⇒ Object
46 47 48 |
# File 'lib/fsm/machine.rb', line 46 def self.set_current_state_name(target, value) target.send("#{Machine[target.class].current_state_attribute_name}=", value) end |
Instance Method Details
#available_transitions(target) ⇒ Object
60 61 62 63 64 |
# File 'lib/fsm/machine.rb', line 60 def available_transitions(target) current_state_name = Machine.get_current_state_name(target) state = state_for_name(current_state_name) state.transitions.values end |
#build_transition_methods ⇒ Object
67 68 69 70 71 72 |
# File 'lib/fsm/machine.rb', line 67 def build_transition_methods names = self.transitions.map() {|transition| transition.name}.uniq names.each do |name| define_transition_method(name) end end |
#dot(options = {}) ⇒ Object
89 90 91 92 93 94 95 96 97 98 |
# File 'lib/fsm/machine.rb', line 89 def dot( = {}) format = [:format] || :png extension = [:extension] || format file_name = [:outfile] || "#{@target_class.name.downcase}.#{extension}" cmd = "dot -T#{format} -o#{file_name}" IO.popen cmd, 'w' do |io| io.write to_dot end raise 'dot failed' unless $?.success? end |
#reachable_states(target) ⇒ Object
51 52 53 54 55 56 57 58 |
# File 'lib/fsm/machine.rb', line 51 def reachable_states(target) reachables = [] current_state_name = Machine.get_current_state_name(target) self.states.map do |state| reachables += state.to_states if state.name == current_state_name end reachables end |
#state(name, options = {}) ⇒ Object
20 21 22 23 24 |
# File 'lib/fsm/machine.rb', line 20 def state(name, = {}) raise "State is already defined: '#{name}'" if self.state_for_name(name, true) self.states << State.new(name, ) self.initial_state_name=(name) unless self.initial_state_name end |
#state_for_name(name, quiet = false) ⇒ Object
Lookup a State by it’s name raises ArgumentError if state can not be found unless quiet is set to true
76 77 78 79 80 |
# File 'lib/fsm/machine.rb', line 76 def state_for_name(name, quiet = false) state = self.states.detect() {|state| state.name == name} raise ArgumentError.new("Unknonw state '#{name}'") unless quiet || state state end |
#to_dot ⇒ Object
82 83 84 85 86 87 |
# File 'lib/fsm/machine.rb', line 82 def to_dot dots = self.transitions.map do |transition| " #{transition.from.name} -> #{transition.to.name}" end "digraph FSM {\n#{dots.join(";\n")}\n}" end |
#transition(name, from_name, to_name, options = {}) ⇒ Object
31 32 33 34 35 36 37 38 39 |
# File 'lib/fsm/machine.rb', line 31 def transition(name, from_name, to_name, = {}) raise ArgumentError.new("name, from_name and to_name are required") if name.nil? || from_name.nil? || to_name.nil? from_state = self.state_for_name(from_name) to_state = self.state_for_name(to_name) transition = Transition.new(name, from_state, to_state, ) from_state.add_transition(transition) self.transitions << transition end |