Module: Chingu::Traits::Timer

Defined in:
lib/chingu/traits/timer.rb

Overview

A chingu trait providing timer-methods to its includer, examples: during(300) { @color = Color.new(0xFFFFFFFF) } # forces @color to white ever update for 300 ms after(400) { self.destroy! } # destroy object after 400 ms between(1000,2000) { self.rotate(10) } # starting after 1 second, call rotate(10) each update during 1 second

All the above can be combined with a 'then { do_something }'. For example, a classic shmup damage effect: during(100) { @color.alpha = 100 }.then { @color.alpha = 255 }

Instance Method Summary collapse

Instance Method Details

#after(time, options = {}, &block) ⇒ Object

Executes block after 'time' milliseconds



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/chingu/traits/timer.rb', line 64

def after(time, options = {}, &block)
  if options[:name]
    return if timer_exists?(options[:name]) && options[:preserve]
    stop_timer(options[:name])
  end

  ms = Gosu::milliseconds()
  @_last_timer = [options[:name], ms + time, nil, block]
  @_timers << @_last_timer
  self
end

#between(start_time, end_time, options = {}, &block) ⇒ Object

Executes block each update during 'start_time' and 'end_time'



79
80
81
82
83
84
85
86
87
88
89
# File 'lib/chingu/traits/timer.rb', line 79

def between(start_time, end_time, options = {}, &block)
  if options[:name]
    return if timer_exists?(options[:name]) && options[:preserve]
    stop_timer(options[:name])
  end

  ms = Gosu::milliseconds()
  @_last_timer = [options[:name], ms + start_time, ms + end_time, block]
  @_timers << @_last_timer
  self
end

#during(time, options = {}, &block) ⇒ Object

Executes block each update during 'time' milliseconds



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/chingu/traits/timer.rb', line 49

def during(time, options = {}, &block)
  if options[:name]
    return if timer_exists?(options[:name]) && options[:preserve]
    stop_timer(options[:name])
  end

  ms = Gosu::milliseconds()
  @_last_timer = [options[:name], ms, ms + time, block]
  @_timers << @_last_timer
  self
end

#every(delay, options = {}, &block) ⇒ Object

Executes block every 'delay' milliseconds



94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/chingu/traits/timer.rb', line 94

def every(delay, options = {}, &block)
  if options[:name]
    return if timer_exists?(options[:name]) && options[:preserve]
    stop_timer(options[:name])
  end
  
  ms = Gosu::milliseconds()
  @_repeating_timers << [options[:name], ms + delay, delay, options[:during] ? ms + options[:during] : nil, block]
  if options[:during]
    @_last_timer = [options[:name], nil, ms + options[:during]]
    return self
  end
end

#setup_trait(options) ⇒ Object



36
37
38
39
40
41
42
43
44
# File 'lib/chingu/traits/timer.rb', line 36

def setup_trait(options)
  #
  # Timers are saved as an array of arrays where each entry contains:
  # [name, start_time, end_time (or nil if one-shot), &block]
  #
  @_timers = Array.new
  @_repeating_timers = Array.new
  super
end

#stop_timer(timer_name) ⇒ Object

Stop timer with name 'name'



132
133
134
135
# File 'lib/chingu/traits/timer.rb', line 132

def stop_timer(timer_name)
  @_timers.reject! { |name, start_time, end_time, block| timer_name == name }
  @_repeating_timers.reject! { |name, start_time, end_time, block| timer_name == name }
end

#stop_timersObject

Stop all timers



140
141
142
143
# File 'lib/chingu/traits/timer.rb', line 140

def stop_timers
  @_timers.clear
  @_repeating_timers.clear
end

#then(&block) ⇒ Object

Executes block after the last timer ends …use one-shots start_time for our trailing “then”. …use durable timers end_time for our trailing “then”.



113
114
115
116
# File 'lib/chingu/traits/timer.rb', line 113

def then(&block)
  start_time = @_last_timer[2].nil? ? @_last_timer[1] : @_last_timer[2]
  @_timers << [@_last_timer[0], start_time, nil, block]
end

#timer_exists?(timer_name = nil) ⇒ Boolean

See if a timer with name 'name' exists

Returns:

  • (Boolean)


122
123
124
125
126
127
# File 'lib/chingu/traits/timer.rb', line 122

def timer_exists?(timer_name = nil)
  return false if timer_name.nil?
  @_timers.each { |name, | return true if timer_name == name }
  @_repeating_timers.each { |name, | return true if timer_name == name }
  return false
end

#update_traitObject



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/chingu/traits/timer.rb', line 145

def update_trait
  ms = Gosu::milliseconds()
  
  @_timers.each do |name, start_time, end_time, block|
    block.call if ms > start_time && (end_time == nil || ms < end_time)
  end
          
  index = 0
  @_repeating_timers.each do |name, start_time, delay, end_time, block|
    if ms > start_time
      block.call  
      @_repeating_timers[index] = [name, ms + delay, delay, end_time, block]
    end
    if end_time && ms > end_time
      @_repeating_timers.delete_at index
    else
      index += 1
    end
  end

  # Remove one-shot timers (only a start_time, no end_time) and all timers which have expired
  @_timers.reject! { |name, start_time, end_time, block| (ms > start_time && end_time == nil) || (end_time != nil && ms > end_time) }

  super
end