/spacey

To get this branch, use:
bzr branch /bzr/spacey

« back to all changes in this revision

Viewing changes to zoetrope/core/timer.lua

  • Committer: Josh C
  • Date: 2013-05-04 20:45:17 UTC
  • Revision ID: josh@9ix.org-20130504204517-1rfp92svud12kg42
zoetrope 1.4

Show diffs side-by-side

added added

removed removed

 
1
-- Class: Timer
 
2
-- A timer allows delayed or periodic execution of a function according
 
3
-- to elapsed time in an app. In order for it to work properly, it must
 
4
-- receive update events, so it must be added somewhere in the current
 
5
-- view or app. If you are using the <View> class, then this is already
 
6
-- done for you; one is created as the View's timer property.
 
7
 
 
8
Timer = Sprite:extend{
 
9
        timers = {},
 
10
        visible = false,
 
11
        active = false,
 
12
        solid = false,
 
13
 
 
14
        -- Method: wait
 
15
 
 
16
        -- Method: after
 
17
        -- Delays a function call after a certain a mount of time.
 
18
        --
 
19
        -- Arguments:
 
20
        --              * delay - how long to wait, in seconds
 
21
        --              * func - function to call
 
22
        --
 
23
        -- Returns:
 
24
        --              A <Promise> that is fulfilled after the function is called
 
25
        
 
26
        after = function (self, delay, func)
 
27
                if STRICT then
 
28
                        assert(type(func) == 'function', 'func property of timer must be a function')
 
29
                        assert(type(delay) == 'number', 'delay must be a number')
 
30
 
 
31
                        if delay <= 0 then
 
32
                                local info = debug.getinfo(2, 'Sl')
 
33
                                print('Warning: timer delay is ' .. delay .. ', will be triggered immediately (' .. 
 
34
                                          info.short_src .. ', line ' .. info.currentline .. ')')
 
35
                        end
 
36
                end
 
37
                
 
38
                self.active = true
 
39
                local promise = Promise:new()
 
40
                table.insert(self.timers, { func = func, timeLeft = delay, promise = promise })
 
41
                return promise
 
42
        end,
 
43
 
 
44
        -- Method: every
 
45
        -- Repeatedly makes a function call. To stop these calls from
 
46
        -- happening in the future, you must call stop().
 
47
        --
 
48
        -- Arguments:
 
49
        --              * delay - how often to make the function call, in seconds
 
50
        --              * func - function to call
 
51
        --
 
52
        -- Returns:
 
53
        --              nothing
 
54
        
 
55
        every = function (self, delay, func)
 
56
                if STRICT then
 
57
                        assert(type(func) == 'function', 'func property of timer must be a function')
 
58
                        assert(type(delay) == 'number', 'delay must be a number')
 
59
 
 
60
                        if delay <= 0 then
 
61
                                local info = debug.getinfo(2, 'Sl')
 
62
                                print('Warning: timer delay is ' .. delay .. ', will be triggered immediately (' .. 
 
63
                                          info.short_src .. ', line ' .. info.currentline .. ')')
 
64
                        end
 
65
                end
 
66
                
 
67
                self.active = true
 
68
                table.insert(self.timers, { func = func, timeLeft = delay, interval = delay })
 
69
        end,
 
70
 
 
71
        -- Method: status
 
72
        -- Returns how much time is left before a function call is scheduled.
 
73
        --
 
74
        -- Arguments:
 
75
        --              func - the function that is queued
 
76
        --
 
77
        -- Returns:
 
78
        --              the time left until the soonest call matching these arguments,
 
79
        --              or nil if there is no call scheduled
 
80
 
 
81
        status = function (self, func, bind, arg)
 
82
                local result
 
83
 
 
84
                for _, t in pairs(self.timers) do
 
85
                        if t.func == func and (not result or result < t.timeLeft) then
 
86
                           result = t.timeLeft
 
87
                        end
 
88
                end
 
89
 
 
90
                return result
 
91
        end,
 
92
        
 
93
        -- Method: stop
 
94
        -- Stops a timer from executing. The promise belonging to it is failed. 
 
95
        -- If there is no function associated with this timer, then this has no effect.
 
96
        --
 
97
        -- Arguments:
 
98
        --              func - function to stop; if omitted, stops all timers
 
99
        --
 
100
        -- Returns:
 
101
        --              nothing
 
102
 
 
103
        stop = function (self, func, bind)
 
104
                local found = false
 
105
 
 
106
                for i, timer in ipairs(self.timers) do
 
107
                        if not func or timer.func == func then
 
108
                                if timer.promise then
 
109
                                        timer.promise:fail('Timer stopped')
 
110
                                end
 
111
 
 
112
                                table.remove(self.timers, i)
 
113
                                found = true
 
114
                        end
 
115
                end
 
116
 
 
117
                if STRICT and not found then
 
118
                        local info = debug.getinfo(2, 'Sl')
 
119
                        print('Warning: asked to stop a timer on a function that was not queued (' ..
 
120
                                  info.short_src .. ', line ' .. info.currentline .. ')')
 
121
                end
 
122
        end,
 
123
 
 
124
        update = function (self, elapsed)
 
125
                for i, timer in ipairs(self.timers) do
 
126
                        timer.timeLeft = timer.timeLeft - elapsed
 
127
                        
 
128
                        if timer.timeLeft <= 0 then
 
129
                                
 
130
                                if timer.promise then
 
131
                                        timer.promise:fulfill(timer.func())
 
132
                                else
 
133
                                        timer.func()
 
134
                                end
 
135
 
 
136
                                if timer.interval then
 
137
                                        timer.timeLeft = timer.interval
 
138
                                        keepActive = true
 
139
                                else
 
140
                                        table.remove(self.timers, i)
 
141
                                end
 
142
                        else
 
143
                                keepActive = true
 
144
                        end
 
145
                end
 
146
                
 
147
                self.active = (#self.timers > 0)
 
148
        end,
 
149
 
 
150
        __tostring = function (self)
 
151
                local result = 'Timer ('
 
152
 
 
153
                if self.active then
 
154
                        result = result .. 'active, '
 
155
                        result = result .. #self.timers .. ' timers running'
 
156
                else
 
157
                        result = result .. 'inactive'
 
158
                end
 
159
 
 
160
                return result .. ')'
 
161
        end
 
162
}