ActionTimer 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1,7 @@
1
+ = CHANGELOG
2
+
3
+ == 0.0.2
4
+ * added new Timer::running? method
5
+ * added new Timer::pause method
6
+ * fixed single iteration action bug
7
+ * added unit tests for proper checks
data/README.rdoc ADDED
@@ -0,0 +1,46 @@
1
+ == ActionTimer: Simple timing for a complex world
2
+
3
+ ActionTimer is a helper for timed events. It allows for single and recurring actions to be executed in an efficient manner. It makes use of a single thread to keep time on registered actions and uses an ActionPool to execute actions. Simple and effective.
4
+
5
+ ==== useful links
6
+ * {trac site}[http://dev.modspox.com/trac/actiontimer]
7
+ * {RDocs}[http://dev.modspox.com/~sine/ActionTimer]
8
+
9
+ === install (easy):
10
+
11
+ gem install --include-dependencies ActionTimer
12
+
13
+ === install (less easy):
14
+
15
+ git clone http://github.com/spox/actiontimer.git
16
+ cd actiontimer
17
+ gem build actiontimer.gemspec
18
+ gem install ActionTimer-x.x.x.gem
19
+
20
+ === Simple example of using the timer:
21
+
22
+ require 'actiontimer'
23
+
24
+ timer = ActionTimer::Timer.new
25
+
26
+ timer.add(10){puts "#{Time.now}: This is timed every 10 seconds"}
27
+ timer.add(15){puts "#{Time.now}: This is timed every 15 seconds"}
28
+ loop do
29
+ puts "#{Time.now}: Main loop that sleeps for 5 seconds"
30
+ sleep(5)
31
+ end
32
+
33
+ ==== Output:
34
+
35
+ 2009-04-13 17:41:39 -0700: Main loop that sleeps for 5 seconds
36
+ 2009-04-13 17:41:44 -0700: Main loop that sleeps for 5 seconds
37
+ 2009-04-13 17:41:49 -0700: This is timed every 10 seconds
38
+ 2009-04-13 17:41:49 -0700: Main loop that sleeps for 5 seconds
39
+ 2009-04-13 17:41:54 -0700: This is timed every 15 seconds
40
+ 2009-04-13 17:41:54 -0700: Main loop that sleeps for 5 seconds
41
+ 2009-04-13 17:41:59 -0700: This is timed every 10 seconds
42
+ 2009-04-13 17:41:59 -0700: Main loop that sleeps for 5 seconds
43
+ 2009-04-13 17:42:04 -0700: Main loop that sleeps for 5 seconds
44
+ 2009-04-13 17:42:09 -0700: This is timed every 10 seconds
45
+ 2009-04-13 17:42:09 -0700: This is timed every 15 seconds
46
+ 2009-04-13 17:42:09 -0700: Main loop that sleeps for 5 seconds
data/actiontimer.gemspec CHANGED
@@ -2,12 +2,24 @@ spec = Gem::Specification.new do |s|
2
2
  s.name = 'ActionTimer'
3
3
  s.author = %q(spox)
4
4
  s.email = %q(spox@modspox.com)
5
- s.version = '0.0.1'
5
+ s.version = '0.0.2'
6
6
  s.summary = %q(Simple timer for a complex world)
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.has_rdoc = true
9
+ s.rdoc_options = %w(--title ActionTimer --main README.rdoc --line-numbers --inline-source)
10
+ s.extra_rdoc_files = %w(README.rdoc LICENSE CHANGELOG)
9
11
  s.files = Dir['**/*']
10
12
  s.require_paths = %w(lib)
11
13
  s.add_dependency 'ActionPool'
12
14
  s.required_ruby_version = '>= 1.8.6'
15
+ s.homepage = %q(http://dev.modspox.com/trac/ActionTimer)
16
+ description = []
17
+ File.open("README.rdoc") do |file|
18
+ file.each do |line|
19
+ line.chomp!
20
+ break if line.empty?
21
+ description << "#{line.gsub(/\[\d\]/, '')}"
22
+ end
23
+ end
24
+ s.description = description[1..-1].join(" ")
13
25
  end
@@ -5,20 +5,29 @@ module ActionTimer
5
5
  class Timer
6
6
  # pool:: ActionPool for processing actions
7
7
  # Creates a new timer
8
- def initialize(pool=nil, logger=nil)
8
+ # Argument hash: {:pool, :logger, :auto_start}
9
+ def initialize(args={}, extra=nil)
10
+ auto_start = true
11
+ if(args.is_a?(Hash))
12
+ @pool = args[:pool] ? args[:pool] : ActionPool::Pool.new
13
+ @logger = LogHelper.new(args[:logger])
14
+ auto_start = args.has_key?(:auto_start) ? args[:auto_start] : true
15
+ else
16
+ @pool = args.is_a?(ActionPool::Pool) ? args : ActionPool::Pool.new
17
+ @logger = LogHelper.new(extra)
18
+ end
9
19
  @actions = []
10
20
  @new_actions = []
11
21
  @timer_thread = nil
12
22
  @stop_timer = false
13
23
  @add_lock = Mutex.new
14
24
  @awake_lock = Mutex.new
15
- @pool = pool.nil? ? ActionPool::Pool.new : pool
16
- @logger = LogHelper.new(logger)
17
- start
25
+ start if auto_start
18
26
  end
19
27
 
20
28
  # Forcibly wakes the timer early
21
29
  def wakeup
30
+ raise NotRunning.new unless running?
22
31
  return unless @awake_lock.try_lock
23
32
  @timer_thread.wakeup if @timer_thread.status == 'sleep'
24
33
  @awake_lock.unlock
@@ -34,7 +43,7 @@ module ActionTimer
34
43
  action = Action.new(self, period, once, data, &func)
35
44
  action.owner = owner unless owner.nil?
36
45
  @add_lock.synchronize{ @new_actions << action }
37
- wakeup
46
+ wakeup if running?
38
47
  return action
39
48
  end
40
49
 
@@ -46,7 +55,7 @@ module ActionTimer
46
55
  raise InvalidType.new(ActionTimer::Action, action.class) unless action.is_a?(Action)
47
56
  end
48
57
  @add_lock.synchronize{ @new_actions = @new_actions + actions }
49
- wakeup
58
+ wakeup if running?
50
59
  end
51
60
 
52
61
  # action:: Action to remove from timer
@@ -54,12 +63,13 @@ module ActionTimer
54
63
  def remove(action)
55
64
  raise InvalidType.new(ActionTimer::Action, action.class) unless action.is_a?(Action)
56
65
  @actions.delete(action)
57
- wakeup
66
+ wakeup if running?
58
67
  end
59
68
 
60
69
  # Start the timer
61
70
  def start
62
71
  raise AlreadyRunning.new unless @timer_thread.nil?
72
+ @stop_timer = false
63
73
  @timer_thread = Thread.new do
64
74
  begin
65
75
  until @stop_timer do
@@ -75,16 +85,33 @@ module ActionTimer
75
85
  add_waiting_actions
76
86
  end
77
87
  rescue Object => boom
88
+ @timer_thread = nil
89
+ clean_actions
78
90
  @logger.fatal("Timer encountered an unexpected error: #{boom}\n#{boom.backtrace.join("\n")}")
79
91
  end
80
92
  end
81
93
  end
82
94
 
83
- # Stop the timer
95
+ # Pause the timer in its current state.
96
+ def pause
97
+ @stop_timer = true
98
+ if(running?)
99
+ wakeup
100
+ @timer_thread.join
101
+ end
102
+ @timer_thread = nil
103
+ end
104
+
105
+ # Stop the timer. Unlike pause, this will completely
106
+ # stop the timer and remove all actions from the timer
84
107
  def stop
85
108
  @stop_timer = true
86
- wakeup
87
- @timer_thread.join
109
+ if(running?)
110
+ wakeup
111
+ clean_actions
112
+ @timer_thread.join
113
+ end
114
+ @timer_thread = nil
88
115
  end
89
116
 
90
117
  # owner:: owner actions to remove
@@ -100,6 +127,11 @@ module ActionTimer
100
127
  wakeup
101
128
  end
102
129
 
130
+ # Is timer currently running?
131
+ def running?
132
+ return !@timer_thread.nil?
133
+ end
134
+
103
135
  private
104
136
 
105
137
  def get_min_sleep
@@ -122,7 +154,7 @@ module ActionTimer
122
154
  @actions.each do |action|
123
155
  action.tick(time_passed)
124
156
  if(action.due?)
125
- remove(action) if action.is_complete?
157
+ @actions.delete(action) if action.is_complete?
126
158
  action = action.schedule
127
159
  @pool.process do
128
160
  begin
@@ -135,5 +167,10 @@ module ActionTimer
135
167
  end
136
168
  end
137
169
 
170
+ def clean_actions
171
+ @actions.clear
172
+ @new_actions.clear
173
+ end
174
+
138
175
  end
139
176
  end
@@ -0,0 +1,129 @@
1
+ require 'test/unit'
2
+ require 'actiontimer'
3
+
4
+ class TimerTests < Test::Unit::TestCase
5
+ def setup
6
+ @timer = ActionTimer::Timer.new
7
+ end
8
+
9
+ # Simple test of basic repetitive action
10
+ def test_basic
11
+ result = 0
12
+ @timer.add(2){ result += 1 }
13
+ sleep(5)
14
+ assert_equal(2, result)
15
+ end
16
+
17
+ # Check the the running? method properly reports
18
+ def test_running
19
+ @timer.add(1){ 1 + 1}
20
+ assert(@timer.running?)
21
+ @timer.pause
22
+ assert(!@timer.running?)
23
+ @timer.start
24
+ assert(@timer.running?)
25
+ @timer.stop
26
+ assert(!@timer.running?)
27
+ end
28
+
29
+ # Check that a single iterative action is only
30
+ # completed once
31
+ def test_once
32
+ result = 0
33
+ @timer.add(1, true){ result += 1 }
34
+ sleep(3)
35
+ assert_equal(1, result)
36
+ end
37
+
38
+ # Check that timer can be paused and restarted
39
+ # without registered actions being effected
40
+ def test_pause
41
+ result = 0
42
+ @timer.add(1){ result += 1 }
43
+ sleep(3.1)
44
+ @timer.pause
45
+ sleep(2)
46
+ @timer.start
47
+ sleep(2.1)
48
+ assert_equal(5, result)
49
+ end
50
+
51
+ # Check that data can be passed to the block
52
+ # properly when created
53
+ def test_data
54
+ result = 0
55
+ @timer.add(1, true, 3){|a| result = a}
56
+ sleep(2)
57
+ assert_equal(3, result)
58
+ end
59
+
60
+ # Check that the timer's auto starting mechanism
61
+ # can be disabled
62
+ def test_auto_start
63
+ timer = ActionTimer::Timer.new(:auto_start => false)
64
+ timer.add(1){ 1+1 }
65
+ assert(!timer.running?)
66
+ timer.start
67
+ assert(timer.running?)
68
+ end
69
+
70
+ # Check that the actions can be cleared out of the
71
+ # timer and the timer is still left in a "running"
72
+ # state.
73
+ def test_clear
74
+ result = 0
75
+ @timer.add(1){ result += 1 }
76
+ sleep(3)
77
+ @timer.clear
78
+ sleep(2)
79
+ assert_equal(2, result)
80
+ assert(@timer.running?)
81
+ end
82
+
83
+ # Check that the timer throws an exception when it
84
+ # is instructed to wakeup while not running
85
+ def test_wakeup
86
+ @timer.stop
87
+ assert_raise(ActionTimer::NotRunning){ @timer.wakeup }
88
+ end
89
+
90
+ # Check that the timer throws an exception when it
91
+ # is instructed to start but is already running
92
+ def test_start
93
+ assert_raise(ActionTimer::AlreadyRunning){ @timer.start }
94
+ end
95
+
96
+ # Check that multiple actions can be added at once
97
+ def test_mass_add
98
+ result = 0
99
+ actions = []
100
+ actions << ActionTimer::Action.new(@timer, 1){ result += 1}
101
+ actions << ActionTimer::Action.new(@timer, 3){ result += 1}
102
+ actions << ActionTimer::Action.new(@timer, 5){ result += 1}
103
+ @timer.mass_add(actions)
104
+ sleep(5.3)
105
+ assert_equal(7, result)
106
+ end
107
+
108
+ # Check that an action can be properly removed from
109
+ # the timer
110
+ def test_remove
111
+ result = 0
112
+ action = @timer.add(1){result += 1}
113
+ sleep(2.1)
114
+ @timer.remove(action)
115
+ sleep(2)
116
+ assert_equal(2, result)
117
+ end
118
+
119
+ # Check that an action's period can be dynamically
120
+ # reset
121
+ def test_action_reset
122
+ result = 0
123
+ action = @timer.add(1){ result += 1}
124
+ sleep(2.1)
125
+ action.reset_period(3)
126
+ sleep(3.1)
127
+ assert_equal(result, 3)
128
+ end
129
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ActionTimer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - spox
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-15 00:00:00 -07:00
12
+ date: 2009-05-20 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,34 +22,40 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: "0"
24
24
  version:
25
- description:
25
+ description: ""
26
26
  email: spox@modspox.com
27
27
  executables: []
28
28
 
29
29
  extensions: []
30
30
 
31
- extra_rdoc_files: []
32
-
31
+ extra_rdoc_files:
32
+ - README.rdoc
33
+ - LICENSE
34
+ - CHANGELOG
33
35
  files:
34
- - README~
36
+ - tests
37
+ - tests/run_tests.rb
35
38
  - actiontimer.gemspec
39
+ - README.rdoc
36
40
  - lib
37
41
  - lib/actiontimer
38
42
  - lib/actiontimer/Action.rb
39
43
  - lib/actiontimer/LogHelper.rb
40
44
  - lib/actiontimer/Exceptions.rb
41
- - lib/actiontimer/Action.rb~
42
- - lib/actiontimer/Timer.rb~
43
45
  - lib/actiontimer/Timer.rb
44
46
  - lib/actiontimer.rb
45
47
  - LICENSE
46
- - README
47
- - ActionTimer-0.0.1.gem
48
+ - CHANGELOG
48
49
  has_rdoc: true
49
- homepage:
50
+ homepage: http://dev.modspox.com/trac/ActionTimer
50
51
  post_install_message:
51
- rdoc_options: []
52
-
52
+ rdoc_options:
53
+ - --title
54
+ - ActionTimer
55
+ - --main
56
+ - README.rdoc
57
+ - --line-numbers
58
+ - --inline-source
53
59
  require_paths:
54
60
  - lib
55
61
  required_ruby_version: !ruby/object:Gem::Requirement
File without changes
data/README DELETED
@@ -1,48 +0,0 @@
1
- == ActionTimer ==
2
- ~ Simple timing for a complex world ~
3
-
4
- ActionTimer is a helper for timed events. It
5
- allows for single and recurring actions to
6
- be executed in an efficient manner. It makes
7
- use of a single thread to keep time on registered
8
- actions and uses an ActionPool to execute
9
- actions. Simple and effective.
10
-
11
- install (easy):
12
-
13
- gem install ActionTimer
14
-
15
- install (less easy):
16
-
17
- git clone http://github.com/spox/actiontimer.git
18
- cd actiontimer
19
- gem build actiontimer.gemspec
20
- gem install ActionTimer-x.x.x.gem
21
-
22
- Simple example of using the timer:
23
-
24
- require 'actiontimer'
25
-
26
- timer = ActionTimer::Timer.new
27
-
28
- timer.add(10){puts "#{Time.now}: This is timed every 10 seconds"}
29
- timer.add(15){puts "#{Time.now}: This is timed every 15 seconds"}
30
- loop do
31
- puts "#{Time.now}: Main loop that sleeps for 5 seconds"
32
- sleep(5)
33
- end
34
-
35
- Output:
36
-
37
- 2009-04-13 17:41:39 -0700: Main loop that sleeps for 5 seconds
38
- 2009-04-13 17:41:44 -0700: Main loop that sleeps for 5 seconds
39
- 2009-04-13 17:41:49 -0700: This is timed every 10 seconds
40
- 2009-04-13 17:41:49 -0700: Main loop that sleeps for 5 seconds
41
- 2009-04-13 17:41:54 -0700: This is timed every 15 seconds
42
- 2009-04-13 17:41:54 -0700: Main loop that sleeps for 5 seconds
43
- 2009-04-13 17:41:59 -0700: This is timed every 10 seconds
44
- 2009-04-13 17:41:59 -0700: Main loop that sleeps for 5 seconds
45
- 2009-04-13 17:42:04 -0700: Main loop that sleeps for 5 seconds
46
- 2009-04-13 17:42:09 -0700: This is timed every 10 seconds
47
- 2009-04-13 17:42:09 -0700: This is timed every 15 seconds
48
- 2009-04-13 17:42:09 -0700: Main loop that sleeps for 5 seconds
data/README~ DELETED
@@ -1,48 +0,0 @@
1
- == ActionTimer ==
2
- ~ Simple timing for a complex world ~
3
-
4
- ActionTimer is a helper for timed events. It
5
- allows for single and recurring actions to
6
- be executed in an efficient manner. It makes
7
- use of a single thread to keep time on registered
8
- actions and uses an ActionPool to execute
9
- actions. Simple and effective.
10
-
11
- install (easy):
12
-
13
- gem install ActionTimer
14
-
15
- install (less easy):
16
-
17
- git clone http://github.com/spox/actiontimer.git
18
- cd actiontimer
19
- gem build actiontimer.gemspec
20
- gem install ActionTimer-x.x.x.gem
21
-
22
- Simple example of using the timer:
23
-
24
- require 'actiontimer'
25
-
26
- timer = ActionTimer::Timer.new
27
-
28
- timer.add(10){puts "#{Time.now}: This is timed every 10 seconds"}
29
- timer.add(15){puts "#{Time.now}: This is timed every 15 seconds"}
30
- loop do
31
- puts "#{Time.now}: Main loop that sleeps for 5 seconds"
32
- sleep(5)
33
- end
34
-
35
- Output:
36
-
37
- 2009-04-13 13:41:39 -0700: Main loop that sleeps for 5 seconds
38
- 2009-04-13 13:41:44 -0700: Main loop that sleeps for 5 seconds
39
- 2009-04-13 13:41:49 -0700: This is timed every 10 seconds
40
- 2009-04-13 13:41:49 -0700: Main loop that sleeps for 5 seconds
41
- 2009-04-13 13:41:54 -0700: This is timed every 15 seconds
42
- 2009-04-13 13:41:54 -0700: Main loop that sleeps for 5 seconds
43
- 2009-04-13 13:41:59 -0700: This is timed every 10 seconds
44
- 2009-04-13 13:41:59 -0700: Main loop that sleeps for 5 seconds
45
- 2009-04-13 13:42:04 -0700: Main loop that sleeps for 5 seconds
46
- 2009-04-13 13:42:09 -0700: This is timed every 10 seconds
47
- 2009-04-13 13:42:09 -0700: This is timed every 15 seconds
48
- 2009-04-13 13:42:09 -0700: Main loop that sleeps for 5 seconds
@@ -1,69 +0,0 @@
1
- module ActionTimer
2
- class Action
3
-
4
- attr_accessor :owner
5
-
6
- # timer:: Timer this action resides within
7
- # period:: amount of time between runs
8
- # once:: only run this action once
9
- # data:: data to pass to block
10
- # block:: block to be executed
11
- def initialize(timer, period, once=false, data=nil, &block)
12
- @period = period.to_f
13
- @block = block
14
- @data = data
15
- @once = once
16
- @due = false
17
- @timer = timer
18
- @completed = false
19
- @wait_remaining = @period
20
- @owner = nil
21
- end
22
-
23
- # o:: Object that added this action
24
- # Adds an owner for this action. Useful
25
- # for clearing all actions for a given
26
- # object from the timer
27
- def owner=(o)
28
- @owner = o
29
- end
30
-
31
- # amount:: amount of time that has passed
32
- # Decrement remaining wait time by given amount
33
- def tick(amount)
34
- @wait_remaining = @wait_remaining - amount if @wait_remaining > 0
35
- @wait_remaining = 0 if @wait_remaining < 0
36
- @completed = true if @once && @wait_remaining <= 0
37
- end
38
-
39
- # Time remaning before Action is due
40
- def remaining
41
- @wait_remaining <= 0 ? 0 : @wait_remaining
42
- end
43
-
44
- # new_time:: new period
45
- # Resets the wait period between runs
46
- def reset_period(new_time)
47
- @period = new_time.to_f
48
- @wait_remaining = @period
49
- @timer.wakeup
50
- end
51
-
52
- # Action is ready to be destroyed
53
- def is_complete?
54
- @completed
55
- end
56
-
57
- # Used for scheduling with Timer. Resets the interval
58
- # and returns itself
59
- def schedule
60
- @wait_remaining = @period
61
- return self
62
- end
63
-
64
- # Run the action
65
- def run
66
- @data.nil? ? @block.call : @block.call(@data)
67
- end
68
- end
69
- end
@@ -1,140 +0,0 @@
1
- require 'actionpool'
2
- ['Action', 'Exceptions', 'LogHelper'].each{|f| require "actiontimer/#{f}"}
3
-
4
- module ActionTimer
5
- class Timer
6
- # pool:: ActionPool for processing actions
7
- # Creates a new timer
8
- def initialize(pool=nil, logger=nil)
9
- @actions = []
10
- @new_actions = []
11
- @timer_thread = nil
12
- @stop_timer = false
13
- @add_lock = Mutex.new
14
- @awake_lock = Mutex.new
15
- @new_actions = Queue.new
16
- @pool = pool.nil? ? ActionPool::Pool.new : pool
17
- @logger = LogHelper.new(logger)
18
- start
19
- end
20
-
21
- # Forcibly wakes the timer early
22
- def wakeup
23
- return unless @awake_lock.try_lock
24
- @timer_thread.wakeup if @timer_thread.status == 'sleep'
25
- @awake_lock.unlock
26
- end
27
-
28
- # period:: amount of time between runs
29
- # once:: only run this action once
30
- # data:: data to pass to block
31
- # owner:: owner of Action
32
- # func:: block to be executed
33
- # Add a new action to block
34
- def add(period, once=false, data=nil, owner=nil, &func)
35
- action = Action.new(self, period, once, data, &func)
36
- action.owner = owner unless owner.nil?
37
- @add_lock.synchronize{ @new_actions << action }
38
- wakeup
39
- return action
40
- end
41
-
42
- # actions:: Array of actions
43
- # Add multiple Actions to the timer at once
44
- def mass_add(actions)
45
- raise InvalidType.new(Array, actions.class) unless actions.is_a?(Array)
46
- actions.each do |action|
47
- raise InvalidType.new(ActionTimer::Action, action.class) unless action.is_a?(Action)
48
- end
49
- @add_lock.synchronize{ @new_actions = @new_actions + actions }
50
- wakeup
51
- end
52
-
53
- # action:: Action to remove from timer
54
- # Remove given action from timer
55
- def remove(action)
56
- raise InvalidType.new(ActionTimer::Action, action.class) unless action.is_a?(Action)
57
- @actions.delete(action)
58
- wakeup
59
- end
60
-
61
- # Start the timer
62
- def start
63
- raise AlreadyRunning.new unless @timer_thread.nil?
64
- @timer_thread = Thread.new do
65
- begin
66
- until @stop_timer do
67
- to_sleep = get_min_sleep
68
- if((to_sleep.nil? || to_sleep > 0) && @new_actions.empty?)
69
- @awake_lock.unlock if @awake_lock.locked?
70
- actual_sleep = to_sleep.nil? ? sleep : sleep(to_sleep)
71
- @awake_lock.lock
72
- else
73
- actual_sleep = 0
74
- end
75
- tick(actual_sleep)
76
- add_waiting_actions
77
- end
78
- rescue Object => boom
79
- @logger.fatal("Timer encountered an unexpected error: #{boom}\n#{boom.backtrace.join("\n")}")
80
- end
81
- end
82
- end
83
-
84
- # Stop the timer
85
- def stop
86
- @stop_timer = true
87
- wakeup
88
- @timer_thread.join
89
- end
90
-
91
- # owner:: owner actions to remove
92
- # Clears timer of actions. If an owner is supplied
93
- # only actions owned by owner will be removed
94
- def clear(owner=nil)
95
- if(owner.nil?)
96
- @actions.clear
97
- @new_actions.clear
98
- else
99
- @actions.each{|a| @actions.delete(a) if a.owner == owner}
100
- end
101
- wakeup
102
- end
103
-
104
- private
105
-
106
- def get_min_sleep
107
- min = @actions.map{|a|a.remaining}.sort[0]
108
- unless(min.nil? || min > 0)
109
- @actions.each{|a|@actions.delete(a) if a.remaining == 0} # kill stuck actions
110
- min = get_min_sleep
111
- end
112
- return min
113
- end
114
-
115
- def add_waiting_actions
116
- @add_lock.synchronize do
117
- @actions = @actions + @new_actions
118
- @new_actions.clear
119
- end
120
- end
121
-
122
- def tick(time_passed)
123
- @actions.each do |action|
124
- action.tick(time_passed)
125
- if(action.due?)
126
- remove(action) if action.is_complete?
127
- action = action.schedule
128
- @pool.process do
129
- begin
130
- action.run
131
- rescue Object => boom
132
- @logger.error("Timer caught an error while running action: #{boom}\n#{boom.backtrace.join("\n")}")
133
- end
134
- end
135
- end
136
- end
137
- end
138
-
139
- end
140
- end