Class: FSM::Observer

Inherits:
Object
  • Object
show all
Includes:
Util
Defined in:
lib/fsm-0.0.0/dsl.rb,
lib/fsm-0.0.0/observer.rb

Defined Under Namespace

Modules: Once Classes: DSL

Constant Summary collapse

ANY =
const 'ANY'

Instance Method Summary collapse

Methods included from Util

included

Constructor Details

#initialize(fsm, &b) ⇒ Observer

Returns a new instance of Observer.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/fsm-0.0.0/observer.rb', line 28

def initialize fsm, &b
  sync_initialize

  @fsm = fsm
  @fsm.add_observer self

  @hooks = Hash.new{|etype_h, etype|
    etype_h[etype] = Hash.new{|fstate_h, fstate|
      fstate_h[fstate] = Array.new
    }
  }

  @q = Queue.new

  @thread = Thread.new{
    Thread.current.abort_on_exception = true
    loop{
      b, *a = @q.pop
      break unless b
      bcall b, *a
    }
  }

  @dsl = DSL.new self
  configure &b if b
end

Instance Method Details

#configure(&b) ⇒ Object



55
56
57
58
59
# File 'lib/fsm-0.0.0/observer.rb', line 55

def configure &b
  ex{
    @dsl.configure &b
  }
end

#defer(hook, *a) ⇒ Object



61
62
63
64
65
# File 'lib/fsm-0.0.0/observer.rb', line 61

def defer hook, *a 
  ex{
    @q.push [hook, *a]
  }
end

#fsm_event(event) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/fsm-0.0.0/observer.rb', line 157

def fsm_event event
  ex{
    [event.type, Event::Any].each do |etype|
      [event.state, ANY].each do |estate|
        #@hooks[etype][estate].each{|hook| idefer hook, event}
        hooks = [] 
        while((hook = @hooks[etype][estate].shift))
          idefer hook, event
          hooks.push hook unless hook.is_a? Once
        end
        @hooks[etype][estate].replace hooks
      end
    end
  }
end

#idefer(hook, *a) ⇒ Object



67
68
69
70
# File 'lib/fsm-0.0.0/observer.rb', line 67

def idefer hook, *a 
  ihook = lambda{|*a| instance_exec *a, &hook }
  defer ihook, *a
end

#joinObject



173
174
175
# File 'lib/fsm-0.0.0/observer.rb', line 173

def join
  @thread.join
end

#killObject Also known as: stop



177
178
179
# File 'lib/fsm-0.0.0/observer.rb', line 177

def kill 
  @thread.kill
end

#on(etype = Event::Any, fstate = ANY, &hook) ⇒ Object



72
73
74
75
76
# File 'lib/fsm-0.0.0/observer.rb', line 72

def on etype = Event::Any, fstate = ANY, &hook
  ex{
    idx = (@hooks[etype][fstate] << hook).size - 1
  }
end

#on_entry(*a, &b) ⇒ Object



78
79
80
# File 'lib/fsm-0.0.0/observer.rb', line 78

def on_entry *a, &b 
  on Event::Entry, *a, &b
end

#on_exit(*a, &b) ⇒ Object



86
87
88
# File 'lib/fsm-0.0.0/observer.rb', line 86

def on_exit *a, &b 
  on Event::Exit, *a, &b
end

#on_input(*a, &b) ⇒ Object



90
91
92
# File 'lib/fsm-0.0.0/observer.rb', line 90

def on_input *a, &b 
  on Event::Input, *a, &b
end

#on_transition(*a, &b) ⇒ Object



82
83
84
# File 'lib/fsm-0.0.0/observer.rb', line 82

def on_transition *a, &b 
  on Event::Transition, *a, &b
end

#once_on(etype = Event::Any, fstate = ANY, &hook) ⇒ Object



96
97
98
# File 'lib/fsm-0.0.0/observer.rb', line 96

def once_on etype = Event::Any, fstate = ANY, &hook
  on etype, fstate, &hook.extend(Once)
end

#once_on_entry(*a, &b) ⇒ Object



100
101
102
# File 'lib/fsm-0.0.0/observer.rb', line 100

def once_on_entry *a, &b
  once_on Event::Entry, *a, &b
end

#once_on_exit(*a, &b) ⇒ Object



108
109
110
# File 'lib/fsm-0.0.0/observer.rb', line 108

def once_on_exit *a, &b
  once_on Event::Exit, *a, &b
end

#once_on_input(*a, &b) ⇒ Object



112
113
114
# File 'lib/fsm-0.0.0/observer.rb', line 112

def once_on_input *a, &b
  once_on Event::Input, *a, &b
end

#once_on_transition(*a, &b) ⇒ Object



104
105
106
# File 'lib/fsm-0.0.0/observer.rb', line 104

def once_on_transition *a, &b
  once_on Event::Transition, *a, &b
end

#wait_for_entry(fstate, &hook) ⇒ Object Also known as: wait_for



116
117
118
119
120
121
122
123
124
# File 'lib/fsm-0.0.0/observer.rb', line 116

def wait_for_entry fstate, &hook
  argv = [fstate]
  unless fsm.state == fstate
    q = Queue.new
    once_on(Event::Entry, fstate){|*a| q.push a }
    argv.replace q.pop
  end
  icall hook, *argv if hook
end

#wait_for_exit(fstate, &hook) ⇒ Object



137
138
139
140
141
142
143
144
145
# File 'lib/fsm-0.0.0/observer.rb', line 137

def wait_for_exit fstate, &hook
  argv = [fstate]
  unless fsm.state == fstate
    q = Queue.new
    once_on(Event::Exit, fstate){|*a| q.push a }
    argv.replace q.pop
  end
  icall hook, *argv if hook
end

#wait_for_input(fstate, &hook) ⇒ Object



147
148
149
150
151
152
153
154
155
# File 'lib/fsm-0.0.0/observer.rb', line 147

def wait_for_input fstate, &hook
  argv = [fstate]
  unless fsm.state == fstate
    q = Queue.new
    once_on(Event::Input, fstate){|*a| q.push a }
    argv.replace q.pop
  end
  icall hook, *argv if hook
end

#wait_for_transition(fstate, &hook) ⇒ Object



127
128
129
130
131
132
133
134
135
# File 'lib/fsm-0.0.0/observer.rb', line 127

def wait_for_transition fstate, &hook
  argv = [fstate]
  unless fsm.state == fstate
    q = Queue.new
    once_on(Event::Transition, fstate){|*a| q.push a }
    argv.replace q.pop
  end
  icall hook, *argv if hook
end