Comparison

util/timer.lua @ 5877:615a0774e4cc

util.timer: Updated to use util.indexedbheap to provide a more complete API. Timers can now be stopped or rescheduled. Callbacks are now pcall'd. Adding/removing timers from within timer callbacks works better. Optional parameter can be passed when creating timer which gets passed to callback, eliminating the need for closures in various timer uses. Timers are now much more lightweight.
author Waqas Hussain <waqas20@gmail.com>
date Wed, 30 Oct 2013 17:44:42 -0400
parent 5776:bd0ff8ae98a8
child 5878:2b1c0c0a2ea6
comparison
equal deleted inserted replaced
5876:f62ad84811df 5877:615a0774e4cc
4 -- 4 --
5 -- This project is MIT/X11 licensed. Please see the 5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information. 6 -- COPYING file in the source package for more information.
7 -- 7 --
8 8
9 local indexedbheap = require "util.indexedbheap";
10 local log = require "util.logger".init("timer");
9 local server = require "net.server"; 11 local server = require "net.server";
10 local math_min = math.min 12 local math_min = math.min
11 local math_huge = math.huge 13 local math_huge = math.huge
12 local get_time = require "socket".gettime; 14 local get_time = require "socket".gettime;
13 local t_insert = table.insert; 15 local t_insert = table.insert;
76 end 78 end
77 , delay); 79 , delay);
78 end 80 end
79 end 81 end
80 82
81 add_task = _add_task; 83 --add_task = _add_task;
84
85 local h = indexedbheap.create();
86 local params = {};
87 local next_time = nil;
88 local _id, _callback, _now, _param;
89 local function _call() return _callback(_now, _id, _param); end
90 local function _traceback_handler(err) log("error", "Traceback[timer]: %s", traceback(tostring(err), 2)); end
91 local function _on_timer(now)
92 local peek;
93 while true do
94 peek = h:peek();
95 if peek == nil or peek > now then break; end
96 local _;
97 _, _callback, _id = h:pop();
98 _now = now;
99 _param = params[id];
100 params[id] = nil;
101 --item(now, id, _param); -- FIXME pcall
102 local success, err = xpcall(_call, _traceback_handler);
103 if success and type(err) == "number" then
104 h:insert(_callback, err + now, _id); -- re-add
105 end
106 end
107 next_time = peek;
108 if peek ~= nil then
109 return peek - now;
110 end
111 end
112 function add_task(delay, callback, param)
113 local current_time = get_time();
114 local event_time = current_time + delay;
115
116 local id = h:insert(callback, event_time);
117 params[id] = param;
118 if next_time == nil or event_time < next_time then
119 next_time = event_time;
120 _add_task(next_time - current_time, on_timer);
121 end
122 return id;
123 end
124 function stop(id)
125 params[id] = nil;
126 return h:remove(id);
127 end
128 function reschedule(id, delay)
129 local current_time = get_time();
130 local event_time = current_time + delay;
131 h:reprioritize(id, delay);
132 if next_time == nil or event_time < next_time then
133 next_time = event_time;
134 _add_task(next_time - current_time, on_timer);
135 end
136 return id;
137 end
82 138
83 return _M; 139 return _M;