Class: StateFu::Event

Inherits:
Sprocket show all
Defined in:
lib/event.rb

Instance Attribute Summary collapse

Attributes inherited from Sprocket

#hooks, #machine, #name

Instance Method Summary collapse

Methods inherited from Sprocket

#==, #===, #add_hook, #deep_copy, #lathe, #to_s

Methods included from HasOptions

#[], #[]=, included

Methods included from Applicable

included

Constructor Details

#initialize(machine, name, options = {}) ⇒ Event

called by Lathe when a new event is constructed



7
8
9
10
11
# File 'lib/event.rb', line 7

def initialize(machine, name, options={})
  @requirements = [].extend ArrayWithSymbolAccessor    
  @sequence     = {}
  super( machine, name, options )
end

Instance Attribute Details

#originsObject

Returns the value of attribute origins.



4
5
6
# File 'lib/event.rb', line 4

def origins
  @origins
end

#requirementsObject (readonly)

Returns the value of attribute requirements.



4
5
6
# File 'lib/event.rb', line 4

def requirements
  @requirements
end

#sequenceObject (readonly)

Returns the value of attribute sequence.



4
5
6
# File 'lib/event.rb', line 4

def sequence
  @sequence
end

#targetsObject

Returns the value of attribute targets.



4
5
6
# File 'lib/event.rb', line 4

def targets
  @targets
end

Instance Method Details

#add_to_sequence(origin_states, target_state) ⇒ Object

build a hash of target => [origins]

Raises:

  • (ArgumentError)


18
19
20
21
22
23
24
25
26
27
# File 'lib/event.rb', line 18

def add_to_sequence origin_states, target_state
  origin_states = [origin_states].flatten
  existing = origin_states.select {|s| target_for_origin(s) }
  raise ArgumentError.new unless existing.empty? && !targets       
  @sequence[target_state] ||= []
  [origin_states].flatten.each do |o|
    @sequence[target_state] << o
  end
  @sequence
end

#can_transition_from?(origin_state) ⇒ Boolean

Returns:

  • (Boolean)


42
43
44
45
# File 'lib/event.rb', line 42

def can_transition_from?(origin_state) 
  ( origins && origins.include?(origin_state.to_sym) && !targets.blank?) ||
    target_for_origin(origin_state)
end

#cycle?Boolean

Returns:

  • (Boolean)


67
68
69
# File 'lib/event.rb', line 67

def cycle?
  origin && (origin == target)
end

#fireable?(transition) ⇒ Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/event.rb', line 98

def fireable?( transition )
  transition.valid?(true)
end

#from(*args) ⇒ Object Also known as: transitions_from

generally called from a Lathe. Sets the origin(s) and optionally target(s) - that is, if you supply the :to option, or a single element hash of origins => targets ) of the event. Both origins= and targets= are accumulators.



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/event.rb', line 117

def from *args
  options = args.extract_options!.symbolize_keys!
  args.flatten!
  to = options.delete(:to) || options.delete(:transitions_to)
  if args.empty? && !to
    if options.length == 1
      self.origins = options.keys[0]
      self.targets = options.values[0]
    else
      raise options.inspect
    end
  else
    self.origins = *args
    self.targets = to unless to.nil?
  end
end

#from?(state) ⇒ Boolean

tests if a state or state name is in the list of origins

Returns:

  • (Boolean)


63
64
65
# File 'lib/event.rb', line 63

def from?( state )
  origin_names.include?( state.to_sym ) || target_for_origin(state)
end

#inspectObject

display nice and short



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/event.rb', line 150

def inspect
  s = self.to_s
  s = s[0,s.length-1]
  display_hooks = hooks.dup
  display_hooks.each do |k,v|
    display_hooks.delete(k) if v.empty?
  end
  unless display_hooks.empty?
    s << " hooks=#{display_hooks.inspect}"
  end
  unless requirements.empty?
    s << " requirements=#{requirements.inspect}"
  end
  s << " targets=#{targets.map(&:to_sym).inspect}" if targets
  s << " origins=#{origins.map(&:to_sym).inspect}" if origins
  s << ">"
  s
end

#originObject

if there is a single state in #origins, returns it



82
83
84
# File 'lib/event.rb', line 82

def origin
  origins && origins.length == 1 && origins[0] || nil
end

#origin_namesObject

the names of all possible origin states



48
49
50
# File 'lib/event.rb', line 48

def origin_names
  origins ? origins.map(&:to_sym) : nil
end

#requires(*args, &block) ⇒ Object

adds an event requirement. DOCME // TODO - can this be removed?



109
110
111
# File 'lib/event.rb', line 109

def requires( *args, &block )
  lathe.requires( *args, &block )
end

#sequence?Boolean

Returns:

  • (Boolean)


29
30
31
# File 'lib/event.rb', line 29

def sequence?
  !sequence.empty?
end

#simple?Boolean

a simple event has exactly one target, and any number of origins. It’s simple because it can be triggered without supplying a target name - ie, <tt>go!<tt> vs <tt>go!(:home)<tt>

Returns:

  • (Boolean)


94
95
96
# File 'lib/event.rb', line 94

def simple?
  !! ( origins && target || sequence? )
end

#targetObject

if there is a single state in #origins, returns it



87
88
89
# File 'lib/event.rb', line 87

def target
  targets && targets.length == 1 && targets[0] || nil
end

#target_for_origin(origin_state) ⇒ Object

Raises:

  • (ArgumentError)


33
34
35
36
37
38
39
# File 'lib/event.rb', line 33

def target_for_origin origin_state
  raise ArgumentError.new if origin_state.nil?
  name = sequence.detect do |k,v| 
    v.include?(origin_state.to_sym)
  end[0] rescue nil
  machine.states[name] if name
end

#target_namesObject

the names of all possible target states



53
54
55
# File 'lib/event.rb', line 53

def target_names
  targets ? targets.map(&:to_sym) : nil
end

#to(*args) ⇒ Object Also known as: transitions_to

sets the target states for the event.



135
136
137
138
139
140
# File 'lib/event.rb', line 135

def to *args
  options = args.extract_options!.symbolize_keys!
  args.flatten!
  raise options.inspect unless options.empty?
  self.targets= *args
end

#to?(state) ⇒ Boolean

tests if a state or state name is in the list of targets

Returns:

  • (Boolean)


58
59
60
# File 'lib/event.rb', line 58

def to?( state )
  target_names.include?( state.to_sym )
end