Class Timer
In: lib/rbot/timer.rb
Parent: Object
Timer dot/f_27.png

Timer handler, manage multiple Action objects, calling them when required. When the Timer is constructed, a new Thread is created to manage timed delays and run Actions.

XXX: there is no way to stop the timer currently. I‘m keeping it this way to weed out old Timer implementation legacy in rbot code. -jsn.

Methods

[]   add   add_once   block   configure   delete   new   remove   reschedule   run_actions   start   stop   unblock  

Classes and Modules

Class Timer::Action

Public Class methods

creates a new Timer and starts it.

[Source]

     # File lib/rbot/timer.rb, line 123
123:   def initialize
124:     self.extend(MonitorMixin)
125:     @tick = self.new_cond
126:     @thread = nil
127:     @actions = Hash.new
128:     @current = nil
129:     self.start
130:   end

Public Instance methods

Creates and installs a new Action, repeatable by default.

period:Action period
opts:options for Action#new, see there
block:Action callback code

Returns the id of the created Action

[Source]

     # File lib/rbot/timer.rb, line 138
138:   def add(period, opts = {}, &block)
139:     a = Action.new({:repeat => true, :period => period}.merge(opts), &block)
140:     self.synchronize do
141:       @actions[a.object_id] = a
142:       @tick.signal
143:     end
144:     return a.object_id
145:   end

Creates and installs a new Action, one-time by default.

period:Action delay
opts:options for Action#new, see there
block:Action callback code

Returns the id of the created Action

[Source]

     # File lib/rbot/timer.rb, line 153
153:   def add_once(period, opts = {}, &block)
154:     self.add(period, {:repeat => false}.merge(opts), &block)
155:   end

blocks an existing Action

aid:Action id, obtained previously from add() or add_once()

[Source]

     # File lib/rbot/timer.rb, line 159
159:   def block(aid)
160:     debug "blocking #{aid}"
161:     self.synchronize { self[aid].block }
162:   end

Provides for on-the-fly reconfiguration of Actions

aid:Action id, obtained previously from add() or add_once()
opts:see Action#new
block:(optional) new Action callback code

[Source]

     # File lib/rbot/timer.rb, line 188
188:   def configure(aid, opts = {}, &block)
189:     self.synchronize do
190:       self[aid].configure(opts, &block)
191:       @tick.signal
192:     end
193:   end
delete(aid)

Alias for remove

removes an existing blocked Action

aid:Action id, obtained previously from add() or add_once()

[Source]

     # File lib/rbot/timer.rb, line 176
176:   def remove(aid)
177:     self.synchronize do
178:       @actions.delete(aid) # or raise "nonexistent action #{aid}"
179:     end
180:   end

changes Action period

aid:Action id
period:new period
block:(optional) new Action callback code

[Source]

     # File lib/rbot/timer.rb, line 199
199:   def reschedule(aid, period, &block)
200:     self.configure(aid, :period => period, &block)
201:   end

[Source]

     # File lib/rbot/timer.rb, line 203
203:   def start
204:     raise 'already started' if @thread
205:     @stopping = false
206:     debug "starting timer #{self}"
207:     @thread = Thread.new do
208:       loop do
209:         tmout = self.run_actions
210:         break if tmout and tmout < 0
211:         self.synchronize { @tick.wait(tmout) }
212:       end
213:     end
214:   end

[Source]

     # File lib/rbot/timer.rb, line 216
216:   def stop
217:     raise 'already stopped' unless @thread
218:     debug "stopping timer #{self}..."
219:     @stopping = true
220:     self.synchronize { @tick.signal }
221:     @thread.join(60) or @thread.kill
222:     debug "timer #{self} stopped"
223:     @thread = nil
224:   end

unblocks an existing blocked Action

aid:Action id, obtained previously from add() or add_once()

[Source]

     # File lib/rbot/timer.rb, line 166
166:   def unblock(aid)
167:     debug "unblocking #{aid}"
168:     self.synchronize do
169:       self[aid].unblock
170:       @tick.signal
171:     end
172:   end

Protected Instance methods

[Source]

     # File lib/rbot/timer.rb, line 228
228:   def [](aid)
229:     aid ||= @current
230:     raise "no current action" unless aid
231:     raise "nonexistent action #{aid}" unless @actions.include? aid
232:     @actions[aid]
233:   end

[Source]

     # File lib/rbot/timer.rb, line 235
235:   def run_actions(now = Time.now)
236:     @actions.keys.each do |k|
237:       return -1 if @stopping
238:       a = @actions[k] or next
239:       next if a.blocked? || a.next > now
240: 
241:       begin
242:         @current = k
243:         a.run(now)
244:       ensure
245:         @current = nil
246:       end
247: 
248:       @actions.delete k unless a.next
249:     end
250: 
251:     nxt = @actions.values.find_all { |v| !v.blocked? }.map{ |v| v.next }.min
252: 
253:     if nxt
254:       delta = nxt - now
255:       delta = 0 if delta < 0
256:       return delta
257:     else
258:       return nil
259:     end
260:   end

[Validate]