1 
 2 --
 3 -- Event.lua
 4 --
 5 -- This file is part of the source package that accompanies the article
 6 -- "Writing C modules for Lua" from the book "Lua Programming Gems."
 7 --
 8 -- Copyright (c) 2008
 9 -- Wim Couwenberg, Ralph Steggink
10 --
11 
12 -- save the used globals
13 local math, require, setmetatable, pcall =
14       math, require, setmetatable, pcall
15 
16 -- create the Event module
17 module "Event"
18 
19 -- create the auxiliary and private C functions table
20 local aux, prv = {}, {}
21 
22 -- open the C library, get the initialization function and call it with the
23 -- aux, the prv and the module tables.
24 local initialize = require "C-Event"
25 initialize(aux, prv, _M)
26 
27 -- create a weak table to map callback data to event objects
28 local events = setmetatable({}, {__mode = "v"})
29 
30 -- metatable and garbage collector for Event object userdata
31 local umeta = {}
32 umeta.__gc = prv.del
33 
34 -- metatable and method definitions for Event object
35 local Event = {}
36 Event.__index = Event
37 
38 function Event:add(timeout)
39     local sec, usec
40     if timeout then
41         sec = math.floor(timeout)
42         usec = (timeout % 1)*1e6
43     end
44     return prv.add(self.__udata, sec, usec)
45 end
46 
47 function Event:del()
48     return prv.del(self.__udata)
49 end
50 
51 -- global functions
52 function create(fd, event_type, handler)
53     local udata, ptr = prv.create(fd, event_type)
54     local event = setmetatable({}, Event)
55     event.__udata = udata
56     event.handler = handler
57     events[ptr] = event
58     return event
59 end
60 
61 function dispatch()
62     prv.dispatch()
63 end
64 
65 -- dispatch event (called from C function)
66 function aux.handle_event(ptr, fd, event_type)
67     local event = events[ptr]
68     if event then
69         pcall(event.handler, event, fd, event_type)
70     end
71 end
72 
73 -- Event userdata metatable (used by "create" C function) 
74 aux.metatable = umeta