ActionTimer 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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